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