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     return widget;
00377 }
00378 
00379 bool
00380 WidgetLibrary::createMenuActions(const QCString &c, QWidget *w, QPopupMenu *menu,
00381     KFormDesigner::Container *container)
00382 {
00383     loadFactories();
00384     WidgetInfo *wclass = d->widgets[c];
00385     if(!wclass)
00386         return false;
00387 
00388     wclass->factory()->m_widget = w;
00389     wclass->factory()->m_container = container;
00390     if (wclass->factory()->createMenuActions(c, w, menu, container))
00391         return true;
00392     //try from inherited class
00393     if (wclass->inheritedClass())
00394         return wclass->inheritedClass()->factory()
00395             ->createMenuActions(wclass->className(), w, menu, container);
00396     return false;
00397 }
00398 
00399 bool
00400 WidgetLibrary::startEditing(const QCString &classname, QWidget *w, Container *container)
00401 {
00402     loadFactories();
00403     WidgetInfo *wclass = d->widgets[classname];
00404     if(!wclass)
00405         return false;
00406 
00407     if (wclass->factory()->startEditing(classname, w, container))
00408         return true;
00409     //try from inherited class
00410     if (wclass->inheritedClass())
00411         return wclass->inheritedClass()->factory()->startEditing(wclass->className(), w, container);
00412     return false;
00413 }
00414 
00415 bool
00416 WidgetLibrary::previewWidget(const QCString &classname, QWidget *widget, Container *container)
00417 {
00418     loadFactories();
00419     WidgetInfo *wclass = d->widgets[classname];
00420     if(!wclass)
00421         return false;
00422 
00423     if (wclass->factory()->previewWidget(classname, widget, container))
00424         return true;
00425     //try from inherited class
00426     if (wclass->inheritedClass())
00427         return wclass->inheritedClass()->factory()->previewWidget(wclass->className(), widget, container);
00428     return false;
00429 }
00430 
00431 bool
00432 WidgetLibrary::clearWidgetContent(const QCString &classname, QWidget *w)
00433 {
00434     loadFactories();
00435     WidgetInfo *wclass = d->widgets[classname];
00436     if(!wclass)
00437         return false;
00438 
00439     if (wclass->factory()->clearWidgetContent(classname, w))
00440         return true;
00441     //try from inherited class
00442     if (wclass->inheritedClass())
00443         return wclass->inheritedClass()->factory()->clearWidgetContent(wclass->className(), w);
00444     return false;
00445 }
00446 
00447 QString
00448 WidgetLibrary::displayName(const QCString &classname)
00449 {
00450     loadFactories();
00451     WidgetInfo *wi = d->widgets.find(classname);
00452     if(wi)
00453         return wi->name();
00454 
00455     return classname;
00456 }
00457 
00458 QString
00459 WidgetLibrary::savingName(const QCString &classname)
00460 {
00461     loadFactories();
00462     QString s;
00463     WidgetInfo *wi = d->widgets.find(classname);
00464     if(wi && !wi->savingName().isEmpty())
00465         return wi->savingName();
00466 
00467     return classname;
00468 }
00469 
00470 QString
00471 WidgetLibrary::namePrefix(const QCString &classname)
00472 {
00473     loadFactories();
00474     WidgetInfo *wi = d->widgets.find(classname);
00475     if(wi)
00476         return wi->namePrefix();
00477 
00478     return classname;
00479 }
00480 
00481 QString
00482 WidgetLibrary::textForWidgetName(const QCString &name, const QCString &className)
00483 {
00484     loadFactories();
00485     WidgetInfo *widget = d->widgets[className];
00486     if(!widget)
00487         return QString::null;
00488 
00489     QString newName = name;
00490     newName.remove(widget->namePrefix());
00491     newName = widget->name() + " " + newName;
00492     return newName;
00493 }
00494 
00495 QCString
00496 WidgetLibrary::classNameForAlternate(const QCString &classname)
00497 {
00498     loadFactories();
00499     if(d->widgets.find(classname))
00500         return classname;
00501 
00502     WidgetInfo *wi =  d->widgets[classname];
00503     if (wi) {
00504         return wi->className();
00505     }
00506 
00507     // widget not supported
00508     return "CustomWidget";
00509 }
00510 
00511 QString
00512 WidgetLibrary::includeFileName(const QCString &classname)
00513 {
00514     loadFactories();
00515     WidgetInfo *wi = d->widgets.find(classname);
00516     if(wi)
00517         return wi->includeFileName();
00518 
00519     return QString::null;
00520 }
00521 
00522 QString
00523 WidgetLibrary::iconName(const QCString &classname)
00524 {
00525     loadFactories();
00526     WidgetInfo *wi = d->widgets.find(classname);
00527     if(wi)
00528         return wi->pixmap();
00529 
00530     return QString::fromLatin1("unknown_widget");
00531 }
00532 
00533 bool
00534 WidgetLibrary::saveSpecialProperty(const QCString &classname, const QString &name, const QVariant &value, QWidget *w, QDomElement &parentNode, QDomDocument &parent)
00535 {
00536     loadFactories();
00537     WidgetInfo *wi = d->widgets.find(classname);
00538     if (!wi)
00539         return false;
00540 
00541     if (wi->factory()->saveSpecialProperty(classname, name, value, w, parentNode, parent))
00542         return true;
00543     //try from inherited class
00544     if (wi->inheritedClass())
00545         return wi->inheritedClass()->factory()->saveSpecialProperty(wi->className(), name, value, w, parentNode, parent);
00546     return false;
00547 }
00548 
00549 bool
00550 WidgetLibrary::readSpecialProperty(const QCString &classname, QDomElement &node, QWidget *w, ObjectTreeItem *item)
00551 {
00552     loadFactories();
00553     WidgetInfo *wi = d->widgets.find(classname);
00554     if (!wi)
00555         return false;
00556     if (wi->factory()->readSpecialProperty(classname, node, w, item))
00557         return true;
00558     //try from inherited class
00559     if (wi->inheritedClass())
00560         return wi->inheritedClass()->factory()->readSpecialProperty(wi->className(), node, w, item);
00561     return false;
00562 }
00563 
00564 void WidgetLibrary::setAdvancedPropertiesVisible(bool set)
00565 {
00566     d->showAdvancedProperties = set;
00567 }
00568 
00569 bool WidgetLibrary::advancedPropertiesVisible() const
00570 {
00571     return d->showAdvancedProperties;
00572 }
00573 
00574 bool
00575 WidgetLibrary::isPropertyVisible(const QCString &classname, QWidget *w,
00576     const QCString &property, bool multiple, bool isTopLevel)
00577 {
00578     if (isTopLevel) {
00579         // no focus policy for top-level form widget...
00580         if (!d->showAdvancedProperties && property == "focusPolicy")
00581             return false;
00582     }
00583 
00584     loadFactories();
00585     WidgetInfo *wi = d->widgets.find(classname);
00586     if (!wi)
00587         return false;
00588     if (!d->showAdvancedProperties && d->advancedProperties[ property ]) {
00589         //this is advanced property, should we hide it?
00590         if (wi->factory()->internalProperty(classname, "forceShowAdvancedProperty:"+property).isEmpty()
00591             && (!wi->inheritedClass() || wi->inheritedClass()->factory()->internalProperty(classname, "forceShowAdvancedProperty:"+property).isEmpty()))
00592         {
00593             return false; //hide it
00594         }
00595     }
00596 
00597     if (!wi->factory()->isPropertyVisible(classname, w, property, multiple, isTopLevel))
00598         return false;
00599     //try from inherited class
00600     if (wi->inheritedClass()
00601         && !wi->inheritedClass()->factory()->isPropertyVisible(wi->className(), w, property, multiple, isTopLevel))
00602         return false;
00603 
00604     return true;
00605 }
00606 
00607 QValueList<QCString>
00608 WidgetLibrary::autoSaveProperties(const QCString &classname)
00609 {
00610     loadFactories();
00611     WidgetInfo *wi = d->widgets.find(classname);
00612     if(!wi)
00613         return QValueList<QCString>();
00614     QValueList<QCString> lst;
00615     //prepend from inherited class
00616     if (wi->inheritedClass())
00617         lst = wi->inheritedClass()->factory()->autoSaveProperties(wi->className());
00618     lst += wi->factory()->autoSaveProperties(classname);
00619     return lst;
00620 }
00621 
00622 WidgetInfo*
00623 WidgetLibrary::widgetInfoForClassName(const char* classname)
00624 {
00625     loadFactories();
00626     return d->widgets.find(classname);
00627 }
00628 
00629 WidgetFactory*
00630 WidgetLibrary::factoryForClassName(const char* classname)
00631 {
00632     WidgetInfo *wi = widgetInfoForClassName(classname);
00633     return wi ? wi->factory() : 0;
00634 }
00635 
00636 QString WidgetLibrary::propertyDescForName(WidgetInfo *winfo, const QCString& propertyName)
00637 {
00638     if (!winfo || !winfo->factory())
00639         return QString::null;
00640     QString desc( winfo->factory()->propertyDescForName(propertyName) );
00641     if (!desc.isEmpty())
00642         return desc;
00643     if (winfo->m_parentFactoryName.isEmpty())
00644         return QString::null;
00645 
00646     //try in parent factory, if exists
00647     WidgetFactory *parentFactory = d->factories[winfo->m_parentFactoryName];
00648     if (!parentFactory)
00649         return QString::null;
00650 
00651     return parentFactory->propertyDescForName(propertyName);
00652 }
00653 
00654 QString WidgetLibrary::propertyDescForValue(WidgetInfo *winfo, const QCString& name)
00655 {
00656     if (!winfo->factory())
00657         return QString::null;
00658     QString desc( winfo->factory()->propertyDescForValue(name) );
00659     if (!desc.isEmpty())
00660         return desc;
00661     if (winfo->m_parentFactoryName.isEmpty())
00662         return QString::null;
00663 
00664     //try in parent factory, if exists
00665     WidgetFactory *parentFactory = d->factories[winfo->m_parentFactoryName];
00666     if (!parentFactory)
00667         return QString::null;
00668 
00669     return parentFactory->propertyDescForValue(name);
00670 }
00671 
00672 void WidgetLibrary::setPropertyOptions( WidgetPropertySet& buf, const WidgetInfo& winfo, QWidget* w )
00673 {
00674     if (!winfo.factory())
00675         return;
00676     winfo.factory()->setPropertyOptions(buf, winfo, w);
00677     if (winfo.m_parentFactoryName.isEmpty())
00678         return;
00679     WidgetFactory *parentFactory = d->factories[winfo.m_parentFactoryName];
00680     if (!parentFactory)
00681         return;
00682     parentFactory->setPropertyOptions(buf, winfo, w);
00683 }
00684 
00685 WidgetFactory* WidgetLibrary::factory(const char* factoryName) const
00686 {
00687     return d->factories[factoryName];
00688 }
00689 
00690 QString WidgetLibrary::internalProperty(const QCString& classname, const QCString& property)
00691 {
00692     loadFactories();
00693     WidgetInfo *wclass = d->widgets[classname];
00694     if(!wclass)
00695         return QString::null;
00696     QString value( wclass->factory()->internalProperty(classname, property) );
00697     if (value.isEmpty() && wclass->inheritedClass())
00698         return wclass->inheritedClass()->factory()->internalProperty(classname, property);
00699     return value;
00700 }
00701 
00702 WidgetFactory::CreateWidgetOptions WidgetLibrary::showOrientationSelectionPopup(
00703     const QCString &classname, QWidget* parent, const QPoint& pos)
00704 {
00705     loadFactories();
00706     WidgetInfo *wclass = d->widgets[classname];
00707     if(!wclass)
00708         return WidgetFactory::AnyOrientation;
00709 
00710     //get custom icons and strings
00711     QPixmap iconHorizontal, iconVertical;
00712     QString iconName( wclass->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalIcon") );
00713     if (iconName.isEmpty() && wclass->inheritedClass())
00714         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalIcon");
00715     if (!iconName.isEmpty())
00716         iconHorizontal = SmallIcon(iconName);
00717 
00718     iconName = wclass->factory()->internalProperty(classname, "orientationSelectionPopup:verticalIcon");
00719     if (iconName.isEmpty() && wclass->inheritedClass())
00720         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:verticalIcon");
00721     if (!iconName.isEmpty())
00722         iconVertical = SmallIcon(iconName);
00723 
00724     QString textHorizontal = wclass->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalText");
00725     if (textHorizontal.isEmpty() && wclass->inheritedClass())
00726         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:horizontalText");
00727     if (textHorizontal.isEmpty()) //default
00728         textHorizontal = i18n("Insert Horizontal Widget", "Insert Horizontal");
00729 
00730     QString textVertical = wclass->factory()->internalProperty(classname, "orientationSelectionPopup:verticalText");
00731     if (textVertical.isEmpty() && wclass->inheritedClass())
00732         iconName = wclass->inheritedClass()->factory()->internalProperty(classname, "orientationSelectionPopup:verticalText");
00733     if (textVertical.isEmpty()) //default
00734         textVertical = i18n("Insert Vertical Widget", "Insert Vertical");
00735 
00736     KPopupMenu* popup = new KPopupMenu(parent, "orientationSelectionPopup");
00737     popup->insertTitle(SmallIcon(wclass->pixmap()), i18n("Insert Widget: %1").arg(wclass->name()));
00738     popup->insertItem(iconHorizontal, textHorizontal, 1);
00739     popup->insertItem(iconVertical, textVertical, 2);
00740     popup->insertSeparator();
00741     popup->insertItem(SmallIcon("button_cancel"), i18n("Cancel"), 3);
00742     WidgetFactory::CreateWidgetOptions result;
00743     switch (popup->exec(pos)) {
00744     case 1:
00745         result = WidgetFactory::HorizontalOrientation; break;
00746     case 2:
00747         result = WidgetFactory::VerticalOrientation; break;
00748     default:
00749         result = WidgetFactory::AnyOrientation; //means "cancelled"
00750     }
00751     delete popup;
00752     return result;
00753 }
00754 
00755 bool WidgetLibrary::propertySetShouldBeReloadedAfterPropertyChange(
00756     const QCString& classname, QWidget *w, const QCString& property)
00757 {
00758     WidgetInfo *winfo = widgetInfoForClassName(classname);
00759     if (!winfo)
00760         return false;
00761     return winfo->factory()->propertySetShouldBeReloadedAfterPropertyChange(classname, w, property);
00762 }
00763 
00764 #include "widgetlibrary.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys