kexi

widgetlibrary.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at>
00003    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00004    Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <qdom.h>
00023 
00024 #include <kdebug.h>
00025 #include <klocale.h>
00026 #include <klibloader.h>
00027 #include <kparts/componentfactory.h>
00028 #include <ktrader.h>
00029 #include <kiconloader.h>
00030 #include <kpopupmenu.h>
00031 
00032 #include "widgetfactory.h"
00033 #include "widgetlibrary.h"
00034 #include "libactionwidget.h"
00035 #include "container.h"
00036 #include "form.h"
00037 #include "formIO.h"
00038 
00039 namespace KFormDesigner {
00040 
00042 class XMLGUIClient : public QObject, public KXMLGUIClient
00043 {
00044     public:
00045         XMLGUIClient(KXMLGUIClient* parent, const QString& xmlFileName)
00046          : QObject(parent->actionCollection()), KXMLGUIClient(parent)
00047         {
00048             setXMLFile( xmlFileName, true /*merge*/ );
00049         }
00050 };
00051 
00053 class WidgetLibraryPrivate
00054 {
00055     public:
00056         WidgetLibraryPrivate()
00057          : widgets(101)
00058 //       , alternateWidgets(101)
00059          , services(101, false)
00060          , supportedFactoryGroups(17, false)
00061          , factories(101, false)
00062          , advancedProperties(1009, true)
00063          , hiddenClasses(101, true)
00064          , showAdvancedProperties(true)
00065          , factoriesLoaded(false)
00066         {
00067             services.setAutoDelete(true);
00068             advancedProperties.insert("autoMask", (char*)1);
00069             advancedProperties.insert("baseSize", (char*)1);
00070             advancedProperties.insert("mouseTracking", (char*)1);
00071             advancedProperties.insert("acceptDrops", (char*)1);
00072             advancedProperties.insert("cursorPosition", (char*)1);
00073             advancedProperties.insert("contextMenuEnabled", (char*)1);
00074             advancedProperties.insert("trapEnterKeyEvent", (char*)1);
00075             advancedProperties.insert("dragEnabled", (char*)1);
00076             advancedProperties.insert("enableSqueezedText", (char*)1);
00077             advancedProperties.insert("sizeIncrement", (char*)1); advancedProperties.insert("palette", (char*)1);
00079             advancedProperties.insert("backgroundOrigin", (char*)1);
00080             advancedProperties.insert("backgroundMode", (char*)1);//this is rather useless
00081             advancedProperties.insert("layout", (char*)1);// too large risk to break things
00082                                                           // by providing this in propeditor
00083             advancedProperties.insert("minimumSize", (char*)1);
00084             advancedProperties.insert("maximumSize", (char*)1);
00085 #ifdef KEXI_NO_UNFINISHED
00086 
00087             advancedProperties.insert("paletteBackgroundPixmap", (char*)1);
00088             advancedProperties.insert("icon", (char*)1);
00089             advancedProperties.insert("pixmap", (char*)1);
00090             advancedProperties.insert("accel", (char*)1);
00091 #endif
00092         }
00093         // dict which associates a class name with a Widget class
00094         WidgetInfo::Dict widgets;//, alternateWidgets;
00095         QAsciiDict<KService::Ptr> services;
00096         QAsciiDict<char> supportedFactoryGroups;
00097         QAsciiDict<WidgetFactory> factories;
00098         QAsciiDict<char> advancedProperties;
00099         QAsciiDict<char> hiddenClasses;
00100         bool showAdvancedProperties : 1;
00101         bool factoriesLoaded : 1;
00102 };
00103 }
00104 
00105 using namespace KFormDesigner;
00106 
00107 //-------------------------------------------
00108 
00109 WidgetLibrary::WidgetLibrary(QObject *parent, const QStringList& supportedFactoryGroups)
00110  : QObject(parent)
00111  , d(new WidgetLibraryPrivate())
00112 {
00113     for (QStringList::ConstIterator it = supportedFactoryGroups.constBegin();
00114         it!=supportedFactoryGroups.constEnd(); ++it)
00115     {
00116         d->supportedFactoryGroups.insert( (*it).lower().latin1(), (char*)1);
00117     }
00118     lookupFactories();
00119 }
00120 
00121 WidgetLibrary::~WidgetLibrary()
00122 {
00123     delete d;
00124 }
00125 
00126 void
00127 WidgetLibrary::loadFactoryWidgets(WidgetFactory *f)
00128 {
00129     const WidgetInfo::Dict widgets = f->classes();
00130     WidgetInfo *w;
00131     for(QAsciiDictIterator<WidgetInfo> it(widgets); (w = it.current()); ++it)
00132     {
00133         if (0 != d->hiddenClasses[ w->className() ])
00134             continue; //this class is hidden
00135         // check if we want to inherit a widget from a different factory
00136         if (!w->m_parentFactoryName.isEmpty() && !w->m_inheritedClassName.isEmpty()) {
00137             WidgetFactory *parentFactory = d->factories[w->m_parentFactoryName];
00138             if (!parentFactory) {
00139                 kdWarning() << "WidgetLibrary::loadFactoryWidgets(): class '" << w->className()
00140                     << "' - no such parent factory '" << w->m_parentFactoryName << "'" << endl;
00141                 continue;
00142             }
00143             WidgetInfo* inheritedClass = parentFactory->m_classesByName[ w->m_inheritedClassName ];
00144             if (!inheritedClass) {
00145                 kdWarning() << "WidgetLibrary::loadFactoryWidgets(): class '" << w->m_inheritedClassName
00146                     << "' - no such class to inherit in factory '" << w->m_parentFactoryName << "'" << endl;
00147                 continue;
00148             }
00149             //ok: inherit properties:
00150             w->m_inheritedClass = inheritedClass;
00151             if (w->pixmap().isEmpty())
00152                 w->setPixmap( inheritedClass->pixmap() );
00153             //ok?
00154             foreach (QValueList<QCString>::ConstIterator, it_alt, inheritedClass->m_alternateNames) {
00155                 w->addAlternateClassName( *it_alt, inheritedClass->isOverriddenClassName( *it_alt ) );
00156             }
00157             if (w->includeFileName().isEmpty())
00158                 w->setIncludeFileName( inheritedClass->includeFileName() );
00159             if (w->name().isEmpty())
00160                 w->setName( inheritedClass->name() );
00161             if (w->namePrefix().isEmpty())
00162                 w->setNamePrefix( inheritedClass->namePrefix() );
00163             if (w->description().isEmpty())
00164                 w->setDescription( inheritedClass->description() );
00165         }
00166 
00167 //      kdDebug() << "WidgetLibrary::addFactory(): adding class " << w->className() << endl;
00168         QValueList<QCString> l = w->alternateClassNames();
00169         l.prepend( w->className() );
00170         //d->widgets.insert(w->className(), w);
00171 //      if(!w->alternateClassName().isEmpty()) {
00172 //          QStringList l = QStringList::split("|", w->alternateClassName());
00173         QValueList<QCString>::ConstIterator endIt = l.constEnd();
00174         for(QValueList<QCString>::ConstIterator it = l.constBegin(); it != endIt; ++it) {
00175             WidgetInfo *widgetForClass = d->widgets.find( *it );
00176             if (!widgetForClass || (widgetForClass && !widgetForClass->isOverriddenClassName(*it))) {
00177                 //insert a widgetinfo, if:
00178                 //1) this class has no alternate class assigned yet, or
00179                 //2) this class has alternate class assigned but without 'override' flag
00180                 d->widgets.replace( *it, w);
00181             }
00182 
00183 /*          WidgetInfo *widgetForClass = d->alternateWidgets.find(*it);
00184             if (!widgetForClass || (widgetForClass && !widgetForClass->isOverriddenClassName(*it))) {
00185                 //insert a widgetinfo, if:
00186                 //1) this class has no alternate class assigned yet, or
00187                 //2) this class has alternate class assigned but without 'override' flag
00188                 d->alternateWidgets.replace(*it, w);
00189             }*/
00190         }
00191     }
00192 }
00193 
00194 void
00195 WidgetLibrary::lookupFactories()
00196 {
00197     KTrader::OfferList tlist = KTrader::self()->query("KFormDesigner/WidgetFactory");
00198     KTrader::OfferList::ConstIterator it, end( tlist.constEnd() );
00199     for( it = tlist.constBegin(); it != end; ++it)
00200     {
00201         KService::Ptr ptr = (*it);
00202         KService::Ptr* existingService = (d->services)[ptr->library().latin1()];
00203         if (existingService) {
00204             kdWarning() << "WidgetLibrary::lookupFactories(): factory '" << ptr->name()
00205                 << "' already found (library="<< (*existingService)->library()
00206                 <<")! skipping this one: library=" << ptr->library() << endl;
00207             continue;
00208         }
00209         kdDebug() << "WidgetLibrary::lookupFactories(): found factory: " << ptr->name() << endl;
00210 
00211         QCString groupName = ptr->property("X-KFormDesigner-FactoryGroup").toCString();
00212         if (!groupName.isEmpty() && !d->supportedFactoryGroups[groupName]) {
00213             kdDebug() << "WidgetLibrary::lookupFactories(): factory group '" << groupName
00214                 << "' is unsupported by this application (library=" << ptr->library() << ")"<< endl;
00215             continue;
00216         }
00217         const uint factoryVersion = ptr->property("X-KFormDesigner-WidgetFactoryVersion").toUInt();
00218         if (KFormDesigner::version()!=factoryVersion) {
00219             kdWarning() << QString("WidgetLibrary::lookupFactories(): factory '%1'" 
00220                 " has version '%2' but required Widget Factory version is '%3'\n"
00221                 " -- skipping this factory!").arg(ptr->library()).arg(factoryVersion)
00222                 .arg(KFormDesigner::version()) << endl;
00223             continue;
00224         }
00225         d->services.insert(ptr->library().latin1(), new KService::Ptr( ptr ));
00226     }
00227 }
00228 
00229 void
00230 WidgetLibrary::loadFactories()
00231 {
00232     if (d->factoriesLoaded)
00233         return;
00234     d->factoriesLoaded = true;
00235     for (QAsciiDictIterator<KService::Ptr> it(d->services); it.current(); ++it) {
00236         WidgetFactory *f = KParts::ComponentFactory::createInstanceFromService<WidgetFactory>(
00237             *it.current(), this, (*it.current())->library().latin1(), QStringList());
00238         if (!f) {
00239             kdWarning() << "WidgetLibrary::loadFactories(): creating factory failed! "
00240                 << (*it.current())->library() << endl;
00241             continue;
00242         }
00243         f->m_library = this;
00244         f->m_showAdvancedProperties = d->showAdvancedProperties; //inherit this flag from the library
00245         f->m_xmlGUIFileName = (*it.current())->property("X-KFormDesigner-XMLGUIFileName").toString();
00246         d->factories.insert( f->name(), f );
00247 
00248         //collect information about classes to be hidden
00249         if (f->m_hiddenClasses) {
00250             for (QAsciiDictIterator<char> it2(*f->m_hiddenClasses); it2.current(); ++it2) {
00251                 d->hiddenClasses.replace( it2.currentKey(), (char*)1 );
00252             }
00253         }
00254     }
00255 
00256     //now we have factories instantiated: load widgets
00257     QPtrList<WidgetFactory> loadLater;
00258     for (QAsciiDictIterator<WidgetFactory> it(d->factories); it.current(); ++it) {
00259         //ONE LEVEL, FLAT INHERITANCE, but works!
00260         //if this factory inherits from something, load its witgets later
00262         if (it.current()->inheritsFactories())
00263             loadLater.append( it.current() );
00264         else
00265             loadFactoryWidgets(it.current());
00266     }
00267     //load now the rest
00268     for (QPtrListIterator<WidgetFactory> it(loadLater); it.current(); ++it) {
00269         loadFactoryWidgets(it.current());
00270     }
00271 }
00272 
00273 /* old
00274 QString
00275 WidgetLibrary::createXML()
00276 {
00277     loadFactories();
00278 
00279     QDomDocument doc("kpartgui");
00280     QDomElement root = doc.createElement("kpartgui");
00281 
00282     root.setAttribute("name", "kformdesigner");
00283     root.setAttribute("version", "0.3");
00284     doc.appendChild(root);
00285 
00286     QDomElement toolbar = doc.createElement("ToolBar");
00287     toolbar.setAttribute("name", "widgets");
00288     root.appendChild(toolbar);
00289 
00290     QDomElement texttb = doc.createElement("text");
00291     toolbar.appendChild(texttb);
00292     QDomText ttext = doc.createTextNode("Widgets");
00293     texttb.appendChild(ttext);
00294 
00295     QDomElement menubar = doc.createElement("MenuBar");
00296     toolbar.setAttribute("name", "widgets");
00297     root.appendChild(menubar);
00298 
00299     QDomElement Mtextb = doc.createElement("text");
00300     toolbar.appendChild(Mtextb);
00301     QDomText Mtext = doc.createTextNode("Widgets");
00302     Mtextb.appendChild(Mtext);
00303     QDomElement menu = doc.createElement("Menu");
00304     menu.setAttribute("name", "widgets");
00305 
00306     QAsciiDictIterator<WidgetInfo> it(d->widgets);
00307     int i = 0;
00308     for(; it.current(); ++it)
00309     {
00310         QDomElement action = doc.createElement("Action");
00311         action.setAttribute("name", "library_widget" + it.current()->className());
00312         toolbar.appendChild(action);
00313 
00314         i++;
00315     }
00316 
00317     return doc.toString();
00318 }*/
00319 
00320 ActionList
00321 WidgetLibrary::createWidgetActions(KXMLGUIClient* client, KActionCollection *parent, 
00322     QObject *receiver, const char *slot)
00323 {
00324     loadFactories();
00325 
00326     // init XML gui clients (custom factories have their own .rc files)
00327     for (QAsciiDictIterator<WidgetFactory> it(d->factories); it.current(); ++it)
00328     {
00329         if (it.current()->m_xmlGUIFileName.isEmpty()) { // probably a built-in factory, with GUI file like kexiformpartinstui.rc
00330             it.current()->m_guiClient = 0;
00331         }
00332         else { // a custom factory with its own .rc file
00333             it.current()->m_guiClient = new XMLGUIClient(client, it.current()->m_xmlGUIFileName);
00334         }
00335     }
00336 
00337     ActionList actions;
00338     for (QAsciiDictIterator<WidgetInfo> it(d->widgets); it.current(); ++it)
00339     {
00340         LibActionWidget *a = new LibActionWidget(it.current(), 
00341             it.current()->factory()->m_guiClient 
00342             ? it.current()->factory()->m_guiClient->actionCollection() : parent);
00343         connect(a, SIGNAL(prepareInsert(const QCString &)), receiver, slot);
00344         actions.append(a);
00345     }
00346     return actions;
00347 }
00348 
00349 void
00350 WidgetLibrary::addCustomWidgetActions(KActionCollection *col)
00351 {
00352     for (QAsciiDictIterator<WidgetFactory> it(d->factories); it.current(); ++it)
00353     {
00354         it.current()->createCustomActions(
00355             it.current()->m_guiClient 
00356             ? it.current()->m_guiClient->actionCollection() : col);
00357     }
00358 }
00359 
00360 QWidget*
00361 WidgetLibrary::createWidget(const QCString &classname, QWidget *parent, const char *name, Container *c,
00362     int options)
00363 {
00364     loadFactories();
00365     WidgetInfo *wclass = d->widgets[classname];
00366     if(!wclass)
00367         return 0;
00368 
00369     QWidget *widget = wclass->factory()->createWidget(wclass->className(), parent, name, c, options);
00370     if (!widget) {
00371         //try to instantiate from inherited class
00372         if (wclass->inheritedClass())
00373             widget = wclass->inheritedClass()->factory()->createWidget(
00374                 wclass->className(), parent, name, c, options);
00375     }
00376     widget->setAcceptDrops(true);
00377     return widget;
00378 }
00379 
00380 bool
00381 WidgetLibrary::createMenuActions(const QCString &c, QWidget *w, QPopupMenu *menu,
00382     KFormDesigner::Container *container)
00383 {
00384     loadFactories();
00385     WidgetInfo *wclass = d->widgets[c];
00386     if(!wclass)
00387         return false;
00388 
00389     wclass->factory()->m_widget = w;
00390     wclass->factory()->m_container = container;
00391     if (wclass->factory()->createMenuActions(c, w, menu, container))
00392         return true;
00393     //try from inherited class
00394     if (wclass->inheritedClass())
00395         return wclass->inheritedClass()->factory()
00396             ->createMenuActions(wclass->className(), w, menu, container);
00397     return false;
00398 }
00399 
00400 bool
00401 WidgetLibrary::startEditing(const QCString &classname, QWidget *w, Container *container)
00402 {
00403     loadFactories();
00404     WidgetInfo *wclass = d->widgets[classname];
00405     if(!wclass)
00406         return false;
00407 
00408     if (wclass->factory()->startEditing(classname, w, container))
00409         return true;
00410     //try from inherited class
00411     if (wclass->inheritedClass())
00412         return wclass->inheritedClass()->factory()->startEditing(wclass->className(), w, container);
00413     return false;
00414 }
00415 
00416 bool
00417 WidgetLibrary::previewWidget(const QCString &classname, QWidget *widget, Container *container)
00418 {
00419     loadFactories();
00420     WidgetInfo *wclass = d->widgets[classname];
00421     if(!wclass)
00422         return false;
00423 
00424     if (wclass->factory()->previewWidget(classname, widget, container))
00425         return true;
00426     //try from inherited class
00427     if (wclass->inheritedClass())
00428         return wclass->inheritedClass()->factory()->previewWidget(wclass->className(), widget, container);
00429     return false;
00430 }
00431 
00432 bool
00433 WidgetLibrary::clearWidgetContent(const QCString &classname, QWidget *w)
00434 {
00435     loadFactories();
00436     WidgetInfo *wclass = d->widgets[classname];
00437     if(!wclass)
00438         return false;
00439 
00440     if (wclass->factory()->clearWidgetContent(classname, w))
00441         return true;
00442     //try from inherited class
00443     if (wclass->inheritedClass())
00444         return wclass->inheritedClass()->factory()->clearWidgetContent(wclass->className(), w);
00445     return false;
00446 }
00447 
00448 QString
00449 WidgetLibrary::displayName(const QCString &classname)
00450 {
00451     loadFactories();
00452     WidgetInfo *wi = d->widgets.find(classname);
00453     if(wi)
00454         return wi->name();
00455 
00456     return classname;
00457 }
00458 
00459 QString
00460 WidgetLibrary::savingName(const QCString &classname)
00461 {
00462     loadFactories();
00463     QString s;
00464     WidgetInfo *wi = d->widgets.find(classname);
00465     if(wi && !wi->savingName().isEmpty())
00466         return wi->savingName();
00467 
00468     return classname;
00469 }
00470 
00471 QString
00472 WidgetLibrary::namePrefix(const QCString &classname)
00473 {
00474     loadFactories();
00475     WidgetInfo *wi = d->widgets.find(classname);
00476     if(wi)
00477         return wi->namePrefix();
00478 
00479     return classname;
00480 }
00481 
00482 QString
00483 WidgetLibrary::textForWidgetName(const QCString &name, const QCString &className)
00484 {
00485     loadFactories();
00486     WidgetInfo *widget = d->widgets[className];
00487     if(!widget)
00488         return QString::null;
00489 
00490     QString newName = name;
00491     newName.remove(widget->namePrefix());
00492     newName = widget->name() + " " + newName;
00493     return newName;
00494 }
00495 
00496 QCString
00497 WidgetLibrary::classNameForAlternate(const QCString &classname)
00498 {
00499     loadFactories();
00500     if(d->widgets.find(classname))
00501         return classname;
00502 
00503     WidgetInfo *wi =  d->widgets[classname];
00504     if (wi) {
00505         return wi->className();
00506     }
00507 
00508     // widget not supported
00509     return "CustomWidget";
00510 }
00511 
00512 QString
00513 WidgetLibrary::includeFileName(const QCString &classname)
00514 {
00515     loadFactories();
00516     WidgetInfo *wi = d->widgets.find(classname);
00517     if(wi)
00518         return wi->includeFileName();
00519 
00520     return QString::null;
00521 }
00522 
00523 QString
00524 WidgetLibrary::iconName(const QCString &classname)
00525 {
00526     loadFactories();
00527     WidgetInfo *wi = d->widgets.find(classname);
00528     if(wi)
00529         return wi->pixmap();
00530 
00531     return QString::fromLatin1("unknown_widget");
00532 }
00533 
00534 bool
00535 WidgetLibrary::saveSpecialProperty(const QCString &classname, const QString &name, const QVariant &value, QWidget *w, QDomElement &parentNode, QDomDocument &parent)
00536 {
00537     loadFactories();
00538     WidgetInfo *wi = d->widgets.find(classname);
00539     if (!wi)
00540         return false;
00541 
00542     if (wi->factory()->saveSpecialProperty(classname, name, value, w, parentNode, parent))
00543         return true;
00544     //try from inherited class
00545     if (wi->inheritedClass())
00546         return wi->inheritedClass()->factory()->saveSpecialProperty(wi->className(), name, value, w, parentNode, parent);
00547     return false;
00548 }
00549 
00550 bool
00551 WidgetLibrary::readSpecialProperty(const QCString &classname, QDomElement &node, QWidget *w, ObjectTreeItem *item)
00552 {
00553     loadFactories();
00554     WidgetInfo *wi = d->widgets.find(classname);
00555     if (!wi)
00556         return false;
00557     if (wi->factory()->readSpecialProperty(classname, node, w, item))
00558         return true;
00559     //try from inherited class
00560     if (wi->inheritedClass())
00561         return wi->inheritedClass()->factory()->readSpecialProperty(wi->className(), node, w, item);
00562     return false;
00563 }
00564 
00565 void WidgetLibrary::setAdvancedPropertiesVisible(bool set)
00566 {
00567     d->showAdvancedProperties = set;
00568 }
00569 
00570 bool WidgetLibrary::advancedPropertiesVisible() const
00571 {
00572     return d->showAdvancedProperties;
00573 }
00574 
00575 bool
00576 WidgetLibrary::isPropertyVisible(const QCString &classname, QWidget *w,
00577     const QCString &property, bool multiple, bool isTopLevel)
00578 {
00579     if (isTopLevel) {
00580         // no focus policy for top-level form widget...
00581         if (!d->showAdvancedProperties && property == "focusPolicy")
00582             return false;
00583     }
00584 
00585     loadFactories();
00586     WidgetInfo *wi = d->widgets.find(classname);
00587     if (!wi)
00588         return false;
00589     if (!d->showAdvancedProperties && d->advancedProperties[ property ]) {
00590         //this is advanced property, should we hide it?
00591         if (wi->factory()->internalProperty(classname, "forceShowAdvancedProperty:"+property).isEmpty()
00592             && (!wi->inheritedClass() || wi->inheritedClass()->factory()->internalProperty(classname, "forceShowAdvancedProperty:"+property).isEmpty()))
00593         {
00594             return false; //hide it
00595         }
00596     }
00597 
00598     if (!wi->factory()->isPropertyVisible(classname, w, property, multiple, isTopLevel))
00599         return false;
00600     //try from inherited class
00601     if (wi->inheritedClass()
00602         && !wi->inheritedClass()->factory()->isPropertyVisible(wi->className(), w, property, multiple, isTopLevel))
00603         return false;
00604 
00605     return true;
00606 }
00607 
00608 QValueList<QCString>
00609 WidgetLibrary::autoSaveProperties(const QCString &classname)
00610 {
00611     loadFactories();
00612     WidgetInfo *wi = d->widgets.find(classname);
00613     if(!wi)
00614         return QValueList<QCString>();
00615     QValueList<QCString> lst;
00616     //prepend from inherited class
00617     if (wi->inheritedClass())
00618         lst = wi->inheritedClass()->factory()->autoSaveProperties(wi->className());
00619     lst += wi->factory()->autoSaveProperties(classname);
00620     return lst;
00621 }
00622 
00623 WidgetInfo*
00624 WidgetLibrary::widgetInfoForClassName(const char* classname)
00625 {
00626     loadFactories();
00627     return d->widgets.find(classname);
00628 }
00629 
00630 WidgetFactory*
00631 WidgetLibrary::factoryForClassName(const char* classname)
00632 {
00633     WidgetInfo *wi = widgetInfoForClassName(classname);
00634     return wi ? wi->factory() : 0;
00635 }
00636 
00637 QString WidgetLibrary::propertyDescForName(WidgetInfo *winfo, const QCString& propertyName)
00638 {
00639     if (!winfo || !winfo->factory())
00640         return QString::null;
00641     QString desc( winfo->factory()->propertyDescForName(propertyName) );
00642     if (!desc.isEmpty())
00643         return desc;
00644     if (winfo->m_parentFactoryName.isEmpty())
00645         return QString::null;
00646 
00647     //try in parent factory, if exists
00648     WidgetFactory *parentFactory = d->factories[winfo->m_parentFactoryName];
00649     if (!parentFactory)
00650         return QString::null;
00651 
00652     return parentFactory->propertyDescForName(propertyName);
00653 }
00654 
00655 QString WidgetLibrary::propertyDescForValue(WidgetInfo *winfo, const QCString& name)
00656 {
00657     if (!winfo->factory())
00658         return QString::null;
00659     QString desc( winfo->factory()->propertyDescForValue(name) );
00660     if (!desc.isEmpty())
00661         return desc;
00662     if (winfo->m_parentFactoryName.isEmpty())
00663         return QString::null;
00664 
00665     //try in parent factory, if exists
00666     WidgetFactory *parentFactory = d->factories[winfo->m_parentFactoryName];
00667     if (!parentFactory)
00668         return QString::null;
00669 
00670     return parentFactory->propertyDescForValue(name);
00671 }
00672 
00673 void WidgetLibrary::setPropertyOptions( WidgetPropertySet& buf, const WidgetInfo& winfo, QWidget* w )
00674 {
00675     if (!winfo.factory())
00676         return;
00677     winfo.factory()->setPropertyOptions(buf, winfo, w);
00678     if (winfo.m_parentFactoryName.isEmpty())
00679         return;
00680     WidgetFactory *parentFactory = d->factories[winfo.m_parentFactoryName];
00681     if (!parentFactory)
00682         return;
00683     parentFactory->setPropertyOptions(buf, winfo, w);
00684 }
00685 
00686 WidgetFactory* WidgetLibrary::factory(const char* factoryName) const
00687 {
00688     return d->factories[factoryName];
00689 }
00690 
00691 QString WidgetLibrary::internalProperty(const QCString& classname, const QCString& property)
00692 {
00693     loadFactories();
00694     WidgetInfo *wclass = d->widgets[classname];
00695     if(!wclass)
00696         return QString::null;
00697     QString value( wclass->factory()->internalProperty(classname, property) );
00698     if (value.isEmpty() && wclass->inheritedClass())
00699         return wclass->inheritedClass()->factory()->internalProperty(classname, property);
00700     return value;
00701 }
00702 
00703 WidgetFactory::CreateWidgetOptions WidgetLibrary::showOrientationSelectionPopup(
00704     const QCString &classname, QWidget* parent, const QPoint& pos)
00705 {
00706     loadFactories();
00707     WidgetInfo *wclass = d->widgets[classname];
00708     if(!wclass)
00709         return WidgetFactory::AnyOrientation;
00710 
00711     //get custom icons and strings
00712     QPixmap iconHorizontal, iconVertical;
00713     QString iconName( wclass->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalIcon") );
00714     if (iconName.isEmpty() && wclass->inheritedClass())
00715         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalIcon");
00716     if (!iconName.isEmpty())
00717         iconHorizontal = SmallIcon(iconName);
00718 
00719     iconName = wclass->factory()->internalProperty(classname, "orientationSelectionPopup:verticalIcon");
00720     if (iconName.isEmpty() && wclass->inheritedClass())
00721         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:verticalIcon");
00722     if (!iconName.isEmpty())
00723         iconVertical = SmallIcon(iconName);
00724 
00725     QString textHorizontal = wclass->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalText");
00726     if (textHorizontal.isEmpty() && wclass->inheritedClass())
00727         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalText");
00728     if (textHorizontal.isEmpty()) //default
00729         textHorizontal = i18n("Insert Horizontal Widget", "Insert Horizontal");
00730 
00731     QString textVertical = wclass->factory()->internalProperty(classname, "orientationSelectionPopup:verticalText");
00732     if (textVertical.isEmpty() && wclass->inheritedClass())
00733         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:verticalText");
00734     if (textVertical.isEmpty()) //default
00735         textVertical = i18n("Insert Vertical Widget", "Insert Vertical");
00736 
00737     KPopupMenu* popup = new KPopupMenu(parent, "orientationSelectionPopup");
00738     popup->insertTitle(SmallIcon(wclass->pixmap()), i18n("Insert Widget: %1").arg(wclass->name()));
00739     popup->insertItem(iconHorizontal, textHorizontal, 1);
00740     popup->insertItem(iconVertical, textVertical, 2);
00741     popup->insertSeparator();
00742     popup->insertItem(SmallIcon("button_cancel"), i18n("Cancel"), 3);
00743     WidgetFactory::CreateWidgetOptions result;
00744     switch (popup->exec(pos)) {
00745     case 1:
00746         result = WidgetFactory::HorizontalOrientation; break;
00747     case 2:
00748         result = WidgetFactory::VerticalOrientation; break;
00749     default:
00750         result = WidgetFactory::AnyOrientation; //means "cancelled"
00751     }
00752     delete popup;
00753     return result;
00754 }
00755 
00756 bool WidgetLibrary::propertySetShouldBeReloadedAfterPropertyChange(
00757     const QCString& classname, QWidget *w, const QCString& property)
00758 {
00759     WidgetInfo *winfo = widgetInfoForClassName(classname);
00760     if (!winfo)
00761         return false;
00762     return winfo->factory()->propertySetShouldBeReloadedAfterPropertyChange(classname, w, property);
00763 }
00764 
00765 #include "widgetlibrary.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys