# kdeui Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kedittoolbar.cpp

    00001 // -*- mode: c++; c-basic-offset: 2 -*-
    00002 /* This file is part of the KDE libraries
    00003    Copyright (C) 2000 Kurt Granroth <granroth@kde.org>
    00004
    00005    This library is free software; you can redistribute it and/or
    00006    modify it under the terms of the GNU Library General Public
    00007    License version 2 as published by the Free Software Foundation.
    00008
    00009    This library is distributed in the hope that it will be useful,
    00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00012    Library General Public License for more details.
    00013
    00014    You should have received a copy of the GNU Library General Public License
    00015    along with this library; see the file COPYING.LIB.  If not, write to
    00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00017    Boston, MA 02111-1307, USA.
    00018 */
    00019 #include <kedittoolbar.h>
    00020
    00021 #include <qdom.h>
    00022 #include <qlayout.h>
    00023 #include <qdir.h>
    00024 #include <qfile.h>
    00025 #include <qheader.h>
    00026 #include <qcombobox.h>
    00027 #include <qdragobject.h>
    00028 #include <qtoolbutton.h>
    00029 #include <qlabel.h>
    00030 #include <qvaluelist.h>
    00031 #include <qapplication.h>
    00032 #include <qtextstream.h>
    00033
    00034 #include <kaction.h>
    00035 #include <kstandarddirs.h>
    00036 #include <klocale.h>
    00037 #include <kicontheme.h>
    00038 #include <kiconloader.h>
    00039 #include <kinstance.h>
    00040 #include <kxmlguifactory.h>
    00041 #include <kseparator.h>
    00042 #include <kconfig.h>
    00043 #include <klistview.h>
    00044 #include <kdebug.h>
    00045 #include <kpushbutton.h>
    00046 #include <kprocio.h>
    00047
    00048 static const char * const lineseparatorstring = I18N_NOOP("--- line separator ---");
    00049 static const char * const separatorstring = I18N_NOOP("--- separator ---");
    00050
    00051 #define LINESEPARATORSTRING i18n(lineseparatorstring)
    00052 #define SEPARATORSTRING i18n(separatorstring)
    00053
    00054 static void dump_xml(const QDomDocument& doc)
    00055 {
    00056     QString str;
    00057     QTextStream ts(&str, IO_WriteOnly);
    00058     ts << doc;
    00059     kdDebug() << str << endl;
    00060 }
    00061
    00062 typedef QValueList<QDomElement> ToolbarList;
    00063
    00064 namespace
    00065 {
    00066 class XmlData
    00067 {
    00068 public:
    00069   enum XmlType { Shell = 0, Part, Local, Merged };
    00070   XmlData()
    00071   {
    00072     m_isModified = false;
    00073     m_actionCollection = 0;
    00074   }
    00075
    00076   QString      m_xmlFile;
    00077   QDomDocument m_document;
    00078   XmlType      m_type;
    00079   bool         m_isModified;
    00080   KActionCollection* m_actionCollection;
    00081
    00082   ToolbarList  m_barList;
    00083 };
    00084
    00085 typedef QValueList<XmlData> XmlDataList;
    00086
    00087 class ToolbarItem : public QListViewItem
    00088 {
    00089 public:
    00090   ToolbarItem(KListView *parent, const QString& tag = QString::null, const QString& name = QString::null, const QString& statusText = QString::null)
    00091     : QListViewItem(parent),
    00092       m_tag(tag),
    00093       m_name(name),
    00094       m_statusText(statusText)
    00095   {
    00096   }
    00097
    00098   ToolbarItem(KListView *parent, QListViewItem *item, const QString &tag = QString::null, const QString& name = QString::null, const QString& statusText = QString::null)
    00099     : QListViewItem(parent, item),
    00100       m_tag(tag),
    00101       m_name(name),
    00102       m_statusText(statusText)
    00103   {
    00104   }
    00105
    00106   virtual QString key(int column, bool) const
    00107   {
    00108     QString s = text( column );
    00109     if ( s == LINESEPARATORSTRING )
    00110       return "0";
    00111     if ( s == SEPARATORSTRING )
    00112       return "1";
    00113     return "2" + s;
    00114   }
    00115
    00116   void setInternalTag(const QString &tag) { m_tag = tag; }
    00117   void setInternalName(const QString &name) { m_name = name; }
    00118   void setStatusText(const QString &text) { m_statusText = text; }
    00119   QString internalTag() const { return m_tag; }
    00120   QString internalName() const { return m_name; }
    00121   QString statusText() const { return m_statusText; }
    00122 private:
    00123   QString m_tag;
    00124   QString m_name;
    00125   QString m_statusText;
    00126 };
    00127
    00128 #define TOOLBARITEMMIMETYPE "data/x-kde.toolbar.item"
    00129 class ToolbarItemDrag : public QStoredDrag
    00130 {
    00131 public:
    00132   ToolbarItemDrag(ToolbarItem *toolbarItem,
    00133                     QWidget *dragSource = 0, const char *name = 0)
    00134     : QStoredDrag( TOOLBARITEMMIMETYPE, dragSource, name )
    00135   {
    00136     if (toolbarItem) {
    00137       QByteArray data;
    00138       QDataStream out(data, IO_WriteOnly);
    00139       out << toolbarItem->internalTag();
    00140       out << toolbarItem->internalName();
    00141       out << toolbarItem->statusText();
    00142       out << toolbarItem->text(1); // separators need this.
    00143       setEncodedData(data);
    00144     }
    00145   }
    00146
    00147   static bool canDecode(QMimeSource* e)
    00148   {
    00149     return e->provides(TOOLBARITEMMIMETYPE);
    00150   }
    00151
    00152   static bool decode( const QMimeSource* e, ToolbarItem& item )
    00153   {
    00154     if (!e)
    00155       return false;
    00156
    00157     QByteArray data = e->encodedData(TOOLBARITEMMIMETYPE);
    00158     if ( data.isEmpty() )
    00159       return false;
    00160
    00161     QString internalTag, internalName, statusText, text;
    00162     QDataStream in(data, IO_ReadOnly);
    00163     in >> internalTag;
    00164     in >> internalName;
    00165     in >> statusText;
    00166     in >> text;
    00167
    00168     item.setInternalTag( internalTag );
    00169     item.setInternalName( internalName );
    00170     item.setStatusText( statusText );
    00171     item.setText(1, text);
    00172
    00173     return true;
    00174   }
    00175 };
    00176
    00177 class ToolbarListView : public KListView
    00178 {
    00179 public:
    00180   ToolbarListView(QWidget *parent=0, const char *name=0)
    00181     : KListView(parent, name)
    00182   {
    00183   }
    00184 protected:
    00185   virtual QDragObject *dragObject()
    00186   {
    00187     ToolbarItem *item = dynamic_cast<ToolbarItem*>(selectedItem());
    00188     if ( item ) {
    00189       ToolbarItemDrag *obj = new ToolbarItemDrag(item,
    00190                                  this, "ToolbarAction drag item");
    00191       const QPixmap *pm = item->pixmap(0);
    00192       if( pm )
    00193         obj->setPixmap( *pm );
    00194       return obj;
    00195     }
    00196     return 0;
    00197   }
    00198
    00199   virtual bool acceptDrag(QDropEvent *event) const
    00200   {
    00201     return ToolbarItemDrag::canDecode( event );
    00202   }
    00203 };
    00204 } // namespace
    00205
    00206 class KEditToolbarWidgetPrivate
    00207 {
    00208 public:
    00216   KEditToolbarWidgetPrivate(KInstance *instance, KActionCollection* collection)
    00217       : m_collection( collection )
    00218   {
    00219     m_instance = instance;
    00220     m_isPart   = false;
    00221     m_helpArea = 0L;
    00222     m_kdialogProcess = 0;
    00223   }
    00224   ~KEditToolbarWidgetPrivate()
    00225   {
    00226   }
    00227
    00228   QString xmlFile(const QString& xml_file)
    00229   {
    00230     return xml_file.isNull() ? QString(m_instance->instanceName()) + "ui.rc" :
    00231                                xml_file;
    00232   }
    00233
    00237   QString loadXMLFile(const QString& _xml_file)
    00238   {
    00239     QString raw_xml;
    00240     QString xml_file = xmlFile(_xml_file);
    00241     //kdDebug() << "loadXMLFile xml_file=" << xml_file << endl;
    00242
    00243     if ( !QDir::isRelativePath(xml_file) )
    00244       raw_xml = KXMLGUIFactory::readConfigFile(xml_file);
    00245     else
    00246       raw_xml = KXMLGUIFactory::readConfigFile(xml_file, m_instance);
    00247
    00248     return raw_xml;
    00249   }
    00250
    00254   ToolbarList findToolbars(QDomNode n)
    00255   {
    00256     static const QString &tagToolbar = KGlobal::staticQString( "ToolBar" );
    00257     static const QString &attrNoEdit = KGlobal::staticQString( "noEdit" );
    00258     ToolbarList list;
    00259
    00260     for( ; !n.isNull(); n = n.nextSibling() )
    00261     {
    00262       QDomElement elem = n.toElement();
    00263       if (elem.isNull())
    00264         continue;
    00265
    00266       if (elem.tagName() == tagToolbar && elem.attribute( attrNoEdit ) != "true" )
    00267         list.append(elem);
    00268
    00269       list += findToolbars(elem.firstChild());
    00270     }
    00271
    00272     return list;
    00273   }
    00274
    00278   QString toolbarName( const XmlData& xmlData, const QDomElement& it ) const
    00279   {
    00280       static const QString &tagText = KGlobal::staticQString( "text" );
    00281       static const QString &tagText2 = KGlobal::staticQString( "Text" );
    00282       static const QString &attrName = KGlobal::staticQString( "name" );
    00283
    00284       QString name;
    00285       QCString txt( it.namedItem( tagText ).toElement().text().utf8() );
    00286       if ( txt.isEmpty() )
    00287           txt = it.namedItem( tagText2 ).toElement().text().utf8();
    00288       if ( txt.isEmpty() )
    00289           name = it.attribute( attrName );
    00290       else
    00291           name = i18n( txt );
    00292
    00293       // the name of the toolbar might depend on whether or not
    00294       // it is in kparts
    00295       if ( ( xmlData.m_type == XmlData::Shell ) ||
    00296            ( xmlData.m_type == XmlData::Part ) )
    00297       {
    00298         QString doc_name(xmlData.m_document.documentElement().attribute( attrName ));
    00299         name += " <" + doc_name + ">";
    00300       }
    00301       return name;
    00302   }
    00306   QDomElement findElementForToolbarItem( const ToolbarItem* item ) const
    00307   {
    00308     static const QString &attrName    = KGlobal::staticQString( "name" );
    00309     for(QDomNode n = m_currentToolbarElem.firstChild(); !n.isNull(); n = n.nextSibling())
    00310     {
    00311       QDomElement elem = n.toElement();
    00312       if ((elem.attribute(attrName) == item->internalName()) &&
    00313           (elem.tagName() == item->internalTag()))
    00314         return elem;
    00315     }
    00316     return QDomElement();
    00317   }
    00318
    00319 #ifndef NDEBUG
    00320   void dump()
    00321   {
    00322     static const char* s_XmlTypeToString[] = { "Shell", "Part", "Local", "Merged" };
    00323     XmlDataList::Iterator xit = m_xmlFiles.begin();
    00324     for ( ; xit != m_xmlFiles.end(); ++xit )
    00325     {
    00326         kdDebug(240) << "XmlData type " << s_XmlTypeToString[(*xit).m_type] << " xmlFile: " << (*xit).m_xmlFile << endl;
    00327         for( QValueList<QDomElement>::Iterator it = (*xit).m_barList.begin();
    00328              it != (*xit).m_barList.end(); ++it ) {
    00329             kdDebug(240) << "    Toolbar: " << toolbarName( *xit, *it ) << endl;
    00330         }
    00331         if ( (*xit).m_actionCollection )
    00332             kdDebug(240) << "    " << (*xit).m_actionCollection->count() << " actions in the collection." << endl;
    00333         else
    00334             kdDebug(240) << "    no action collection." << endl;
    00335     }
    00336   }
    00337 #endif
    00338
    00339   //QValueList<KAction*> m_actionList;
    00340   KActionCollection* m_collection;
    00341   KInstance         *m_instance;
    00342
    00343   XmlData*     m_currentXmlData;
    00344   QDomElement m_currentToolbarElem;
    00345
    00346   QString            m_xmlFile;
    00347   QString            m_globalFile;
    00348   QString            m_rcFile;
    00349   QDomDocument       m_localDoc;
    00350   bool               m_isPart;
    00351
    00352   ToolbarList        m_barList;
    00353
    00354   XmlDataList m_xmlFiles;
    00355
    00356   QLabel     *m_comboLabel;
    00357   KSeparator *m_comboSeparator;
    00358   QLabel * m_helpArea;
    00359   KPushButton* m_changeIcon;
    00360   KProcIO* m_kdialogProcess;
    00361   bool m_hasKDialog;
    00362 };
    00363
    00364 class KEditToolbarPrivate {
    00365 public:
    00366     bool m_accept;
    00367 };
    00368
    00369 const char *KEditToolbar::s_defaultToolbar = 0L;
    00370
    00371 KEditToolbar::KEditToolbar(KActionCollection *collection, const QString& file,
    00372                            bool global, QWidget* parent, const char* name)
    00373   : KDialogBase(Swallow, i18n("Configure Toolbars"), Ok|Apply|Cancel, Ok, parent, name),
    00374     m_widget(new KEditToolbarWidget(QString::fromLatin1(s_defaultToolbar), collection, file, global, this))
    00375 {
    00376     init();
    00377 }
    00378
    00379 KEditToolbar::KEditToolbar(const QString& defaultToolbar, KActionCollection *collection,
    00380                            const QString& file, bool global,
    00381                            QWidget* parent, const char* name)
    00382   : KDialogBase(Swallow, i18n("Configure Toolbars"), Ok|Apply|Cancel, Ok, parent, name),
    00383     m_widget(new KEditToolbarWidget(defaultToolbar, collection, file, global, this))
    00384 {
    00385     init();
    00386 }
    00387
    00388 KEditToolbar::KEditToolbar(KXMLGUIFactory* factory, QWidget* parent, const char* name)
    00389     : KDialogBase(Swallow, i18n("Configure Toolbars"), Ok|Apply|Cancel, Ok, parent, name),
    00390       m_widget(new KEditToolbarWidget(QString::fromLatin1(s_defaultToolbar), factory, this))
    00391 {
    00392     init();
    00393 }
    00394
    00395 KEditToolbar::KEditToolbar(const QString& defaultToolbar,KXMLGUIFactory* factory,
    00396                            QWidget* parent, const char* name)
    00397     : KDialogBase(Swallow, i18n("Configure Toolbars"), Ok|Apply|Cancel, Ok, parent, name),
    00398       m_widget(new KEditToolbarWidget(defaultToolbar, factory, this))
    00399 {
    00400     init();
    00401 }
    00402
    00403 void KEditToolbar::init()
    00404 {
    00405     d = new KEditToolbarPrivate();
    00406     d->m_accept = false;
    00407
    00408     setMainWidget(m_widget);
    00409
    00410     connect(m_widget, SIGNAL(enableOk(bool)), SLOT(acceptOK(bool)));
    00411     connect(m_widget, SIGNAL(enableOk(bool)), SLOT(enableButtonApply(bool)));
    00412     enableButtonApply(false);
    00413
    00414     setMinimumSize(sizeHint());
    00415     s_defaultToolbar = 0L;
    00416 }
    00417
    00418 KEditToolbar::~KEditToolbar()
    00419 {
    00420     delete d;
    00421 }
    00422
    00423 void KEditToolbar::acceptOK(bool b)
    00424 {
    00425     enableButtonOK(b);
    00426     d->m_accept = b;
    00427 }
    00428
    00429 void KEditToolbar::slotOk()
    00430 {
    00431   if (!d->m_accept) {
    00432       reject();
    00433       return;
    00434   }
    00435
    00436   if (!m_widget->save())
    00437   {
    00438     // some error box here is needed
    00439   }
    00440   else
    00441   {
    00442     emit newToolbarConfig();
    00443     accept();
    00444   }
    00445 }
    00446
    00447 void KEditToolbar::slotApply()
    00448 {
    00449     (void)m_widget->save();
    00450     enableButtonApply(false);
    00451     emit newToolbarConfig();
    00452 }
    00453
    00454 void KEditToolbar::setDefaultToolbar(const char *toolbarName)
    00455 {
    00456     s_defaultToolbar = toolbarName;
    00457 }
    00458
    00459 KEditToolbarWidget::KEditToolbarWidget(KActionCollection *collection,
    00460                                        const QString& file,
    00461                                        bool global, QWidget *parent)
    00462   : QWidget(parent),
    00463     d(new KEditToolbarWidgetPrivate(instance(), collection))
    00464 {
    00465   initNonKPart(collection, file, global);
    00466   // now load in our toolbar combo box
    00467   loadToolbarCombo();
    00468   adjustSize();
    00469   setMinimumSize(sizeHint());
    00470 }
    00471
    00472 KEditToolbarWidget::KEditToolbarWidget(const QString& defaultToolbar,
    00473                                        KActionCollection *collection,
    00474                                        const QString& file, bool global,
    00475                                        QWidget *parent)
    00476   : QWidget(parent),
    00477     d(new KEditToolbarWidgetPrivate(instance(), collection))
    00478 {
    00479   initNonKPart(collection, file, global);
    00480   // now load in our toolbar combo box
    00481   loadToolbarCombo(defaultToolbar);
    00482   adjustSize();
    00483   setMinimumSize(sizeHint());
    00484 }
    00485
    00486 KEditToolbarWidget::KEditToolbarWidget( KXMLGUIFactory* factory,
    00487                                         QWidget *parent)
    00488   : QWidget(parent),
    00489     d(new KEditToolbarWidgetPrivate(instance(), KXMLGUIClient::actionCollection() /*create new one*/))
    00490 {
    00491   initKPart(factory);
    00492   // now load in our toolbar combo box
    00493   loadToolbarCombo();
    00494   adjustSize();
    00495   setMinimumSize(sizeHint());
    00496 }
    00497
    00498 KEditToolbarWidget::KEditToolbarWidget( const QString& defaultToolbar,
    00499                                         KXMLGUIFactory* factory,
    00500                                         QWidget *parent)
    00501   : QWidget(parent),
    00502     d(new KEditToolbarWidgetPrivate(instance(), KXMLGUIClient::actionCollection() /*create new one*/))
    00503 {
    00504   initKPart(factory);
    00505   // now load in our toolbar combo box
    00506   loadToolbarCombo(defaultToolbar);
    00507   adjustSize();
    00508   setMinimumSize(sizeHint());
    00509 }
    00510
    00511 KEditToolbarWidget::~KEditToolbarWidget()
    00512 {
    00513     delete d;
    00514 }
    00515
    00516 void KEditToolbarWidget::initNonKPart(KActionCollection *collection,
    00517                                       const QString& file, bool global)
    00518 {
    00519   //d->m_actionList = collection->actions();
    00520
    00521   // handle the merging
    00522   if (global)
    00523     setXMLFile(locate("config", "ui/ui_standards.rc"));
    00524   QString localXML = d->loadXMLFile(file);
    00525   setXML(localXML, true);
    00526
    00527   // reusable vars
    00528   QDomElement elem;
    00529
    00530   // first, get all of the necessary info for our local xml
    00531   XmlData local;
    00532   local.m_xmlFile = d->xmlFile(file);
    00533   local.m_type    = XmlData::Local;
    00534   local.m_document.setContent(localXML);
    00535   elem = local.m_document.documentElement().toElement();
    00536   local.m_barList = d->findToolbars(elem);
    00537   local.m_actionCollection = collection;
    00538   d->m_xmlFiles.append(local);
    00539
    00540   // then, the merged one (ui_standards + local xml)
    00541   XmlData merge;
    00542   merge.m_xmlFile  = QString::null;
    00543   merge.m_type     = XmlData::Merged;
    00544   merge.m_document = domDocument();
    00545   elem = merge.m_document.documentElement().toElement();
    00546   merge.m_barList  = d->findToolbars(elem);
    00547   merge.m_actionCollection = collection;
    00548   d->m_xmlFiles.append(merge);
    00549
    00550 #ifndef NDEBUG
    00551   //d->dump();
    00552 #endif
    00553
    00554   // okay, that done, we concern ourselves with the GUI aspects
    00555   setupLayout();
    00556 }
    00557
    00558 void KEditToolbarWidget::initKPart(KXMLGUIFactory* factory)
    00559 {
    00560   // reusable vars
    00561   QDomElement elem;
    00562
    00563   setFactory( factory );
    00564   actionCollection()->setWidget( this );
    00565
    00566   // add all of the client data
    00567   QPtrList<KXMLGUIClient> clients(factory->clients());
    00568   QPtrListIterator<KXMLGUIClient> it( clients );
    00569   for( ; it.current(); ++it)
    00570   {
    00571     KXMLGUIClient *client = it.current();
    00572
    00573     if (client->xmlFile().isNull())
    00574       continue;
    00575
    00576     XmlData data;
    00577     data.m_xmlFile = client->localXMLFile();
    00578     if ( it.atFirst() )
    00579       data.m_type = XmlData::Shell;
    00580     else
    00581       data.m_type = XmlData::Part;
    00582     data.m_document.setContent( KXMLGUIFactory::readConfigFile( client->xmlFile(), client->instance() ) );
    00583     elem = data.m_document.documentElement().toElement();
    00584     data.m_barList = d->findToolbars(elem);
    00585     data.m_actionCollection = client->actionCollection();
    00586     d->m_xmlFiles.append(data);
    00587
    00588     //d->m_actionList += client->actionCollection()->actions();
    00589   }
    00590
    00591 #ifndef NDEBUG
    00592   //d->dump();
    00593 #endif
    00594
    00595   // okay, that done, we concern ourselves with the GUI aspects
    00596   setupLayout();
    00597 }
    00598
    00599 bool KEditToolbarWidget::save()
    00600 {
    00601   //kdDebug(240) << "KEditToolbarWidget::save" << endl;
    00602   XmlDataList::Iterator it = d->m_xmlFiles.begin();
    00603   for ( ; it != d->m_xmlFiles.end(); ++it)
    00604   {
    00605     // let's not save non-modified files
    00606     if ( !((*it).m_isModified) )
    00607       continue;
    00608
    00609     // let's also skip (non-existent) merged files
    00610     if ( (*it).m_type == XmlData::Merged )
    00611       continue;
    00612
    00613     dump_xml((*it).m_document);
    00614
    00615     kdDebug(240) << "Saving " << (*it).m_xmlFile << endl;
    00616     // if we got this far, we might as well just save it
    00617     KXMLGUIFactory::saveConfigFile((*it).m_document, (*it).m_xmlFile);
    00618   }
    00619
    00620   if ( !factory() )
    00621     return true;
    00622
    00623   QPtrList<KXMLGUIClient> clients(factory()->clients());
    00624   //kdDebug(240) << "factory: " << clients.count() << " clients" << endl;
    00625
    00626   // remove the elements starting from the last going to the first
    00627   KXMLGUIClient *client = clients.last();
    00628   while ( client )
    00629   {
    00630     //kdDebug(240) << "factory->removeClient " << client << endl;
    00631     factory()->removeClient( client );
    00632     client = clients.prev();
    00633   }
    00634
    00635   KXMLGUIClient *firstClient = clients.first();
    00636
    00637   // now, rebuild the gui from the first to the last
    00638   //kdDebug(240) << "rebuilding the gui" << endl;
    00639   QPtrListIterator<KXMLGUIClient> cit( clients );
    00640   for( ; cit.current(); ++cit)
    00641   {
    00642     KXMLGUIClient* client = cit.current();
    00643     //kdDebug(240) << "updating client " << client << " " << client->instance()->instanceName() << "  xmlFile=" << client->xmlFile() << endl;
    00644     QString file( client->xmlFile() ); // before setting ui_standards!
    00645     if ( !file.isEmpty() )
    00646     {
    00647         // passing an empty stream forces the clients to reread the XML
    00648         client->setXMLGUIBuildDocument( QDomDocument() );
    00649
    00650         // for the shell, merge in ui_standards.rc
    00651         if ( client == firstClient ) // same assumption as in the ctor: first==shell
    00652             client->setXMLFile(locate("config", "ui/ui_standards.rc"));
    00653
    00654         // and this forces it to use the *new* XML file
    00655         client->setXMLFile( file, client == firstClient /* merge if shell */ );
    00656     }
    00657   }
    00658
    00659   // Now we can add the clients to the factory
    00660   // We don't do it in the loop above because adding a part automatically
    00661   // adds its plugins, so we must make sure the plugins were updated first.
    00662   cit.toFirst();
    00663   for( ; cit.current(); ++cit)
    00664     factory()->addClient( cit.current() );
    00665
    00666   return true;
    00667 }
    00668
    00669 void KEditToolbarWidget::setupLayout()
    00670 {
    00671   // the toolbar name combo
    00672   d->m_comboLabel = new QLabel(i18n("&Toolbar:"), this);
    00673   m_toolbarCombo = new QComboBox(this);
    00674   m_toolbarCombo->setEnabled(false);
    00675   d->m_comboLabel->setBuddy(m_toolbarCombo);
    00676   d->m_comboSeparator = new KSeparator(this);
    00677   connect(m_toolbarCombo, SIGNAL(activated(const QString&)),
    00678           this,           SLOT(slotToolbarSelected(const QString&)));
    00679
    00680 //  QPushButton *new_toolbar = new QPushButton(i18n("&New"), this);
    00681 //  new_toolbar->setPixmap(BarIcon("filenew", KIcon::SizeSmall));
    00682 //  new_toolbar->setEnabled(false); // disabled until implemented
    00683 //  QPushButton *del_toolbar = new QPushButton(i18n("&Delete"), this);
    00684 //  del_toolbar->setPixmap(BarIcon("editdelete", KIcon::SizeSmall));
    00685 //  del_toolbar->setEnabled(false); // disabled until implemented
    00686
    00687   // our list of inactive actions
    00688   QLabel *inactive_label = new QLabel(i18n("A&vailable actions:"), this);
    00689   m_inactiveList = new ToolbarListView(this);
    00690   m_inactiveList->setDragEnabled(true);
    00691   m_inactiveList->setAcceptDrops(true);
    00692   m_inactiveList->setDropVisualizer(false);
    00693   m_inactiveList->setAllColumnsShowFocus(true);
    00694   m_inactiveList->setMinimumSize(180, 250);
    00695   m_inactiveList->header()->hide();
    00696   m_inactiveList->addColumn(""); // icon
    00697   int column2 = m_inactiveList->addColumn(""); // text
    00698   m_inactiveList->setSorting( column2 );
    00699   inactive_label->setBuddy(m_inactiveList);
    00700   connect(m_inactiveList, SIGNAL(selectionChanged(QListViewItem *)),
    00701           this,           SLOT(slotInactiveSelected(QListViewItem *)));
    00702   connect(m_inactiveList, SIGNAL( doubleClicked( QListViewItem *, const QPoint &, int  )),
    00703           this,           SLOT(slotInsertButton()));
    00704
    00705   // our list of active actions
    00706   QLabel *active_label = new QLabel(i18n("Curr&ent actions:"), this);
    00707   m_activeList = new ToolbarListView(this);
    00708   m_activeList->setDragEnabled(true);
    00709   m_activeList->setAcceptDrops(true);
    00710   m_activeList->setDropVisualizer(true);
    00711   m_activeList->setAllColumnsShowFocus(true);
    00712   m_activeList->setMinimumWidth(m_inactiveList->minimumWidth());
    00713   m_activeList->header()->hide();
    00714   m_activeList->addColumn(""); // icon
    00715   m_activeList->addColumn(""); // text
    00716   m_activeList->setSorting(-1);
    00717   active_label->setBuddy(m_activeList);
    00718
    00719   connect(m_inactiveList, SIGNAL(dropped(KListView*,QDropEvent*,QListViewItem*)),
    00720           this,              SLOT(slotDropped(KListView*,QDropEvent*,QListViewItem*)));
    00721   connect(m_activeList, SIGNAL(dropped(KListView*,QDropEvent*,QListViewItem*)),
    00722           this,            SLOT(slotDropped(KListView*,QDropEvent*,QListViewItem*)));
    00723   connect(m_activeList, SIGNAL(selectionChanged(QListViewItem *)),
    00724           this,         SLOT(slotActiveSelected(QListViewItem *)));
    00725   connect(m_activeList, SIGNAL( doubleClicked( QListViewItem *, const QPoint &, int  )),
    00726           this,           SLOT(slotRemoveButton()));
    00727
    00728   // "change icon" button
    00729   d->m_changeIcon = new KPushButton( i18n( "Change &Icon..." ), this );
    00730   QString kdialogExe = KStandardDirs::findExe(QString::fromLatin1("kdialog"));
    00731   d->m_hasKDialog = !kdialogExe.isEmpty();
    00732   d->m_changeIcon->setEnabled( d->m_hasKDialog );
    00733
    00734   connect( d->m_changeIcon, SIGNAL( clicked() ),
    00735            this, SLOT( slotChangeIcon() ) );
    00736
    00737   // The buttons in the middle
    00738   QIconSet iconSet;
    00739
    00740   m_upAction     = new QToolButton(this);
    00741   iconSet = SmallIconSet( "up" );
    00742   m_upAction->setIconSet( iconSet );
    00743   m_upAction->setEnabled(false);
    00744   m_upAction->setAutoRepeat(true);
    00745   connect(m_upAction, SIGNAL(clicked()), SLOT(slotUpButton()));
    00746
    00747   m_insertAction = new QToolButton(this);
    00748   iconSet = QApplication::reverseLayout() ? SmallIconSet( "back" ) : SmallIconSet( "forward" );
    00749   m_insertAction->setIconSet( iconSet );
    00750   m_insertAction->setEnabled(false);
    00751   connect(m_insertAction, SIGNAL(clicked()), SLOT(slotInsertButton()));
    00752
    00753   m_removeAction = new QToolButton(this);
    00754   iconSet = QApplication::reverseLayout() ? SmallIconSet( "forward" ) : SmallIconSet( "back" );
    00755   m_removeAction->setIconSet( iconSet );
    00756   m_removeAction->setEnabled(false);
    00757   connect(m_removeAction, SIGNAL(clicked()), SLOT(slotRemoveButton()));
    00758
    00759   m_downAction   = new QToolButton(this);
    00760   iconSet = SmallIconSet( "down" );
    00761   m_downAction->setIconSet( iconSet );
    00762   m_downAction->setEnabled(false);
    00763   m_downAction->setAutoRepeat(true);
    00764   connect(m_downAction, SIGNAL(clicked()), SLOT(slotDownButton()));
    00765
    00766   d->m_helpArea = new QLabel(this);
    00767   d->m_helpArea->setAlignment( Qt::WordBreak );
    00768
    00769   // now start with our layouts
    00770   QVBoxLayout *top_layout = new QVBoxLayout(this, 0, KDialog::spacingHint());
    00771
    00772   QVBoxLayout *name_layout = new QVBoxLayout(KDialog::spacingHint());
    00773   QHBoxLayout *list_layout = new QHBoxLayout(KDialog::spacingHint());
    00774
    00775   QVBoxLayout *inactive_layout = new QVBoxLayout(KDialog::spacingHint());
    00776   QVBoxLayout *active_layout = new QVBoxLayout(KDialog::spacingHint());
    00777   QHBoxLayout *changeIcon_layout = new QHBoxLayout(KDialog::spacingHint());
    00778
    00779   QGridLayout *button_layout = new QGridLayout(5, 3, 0);
    00780
    00781   name_layout->addWidget(d->m_comboLabel);
    00782   name_layout->addWidget(m_toolbarCombo);
    00783 //  name_layout->addWidget(new_toolbar);
    00784 //  name_layout->addWidget(del_toolbar);
    00785
    00786   button_layout->setRowStretch( 0, 10 );
    00787   button_layout->addWidget(m_upAction, 1, 1);
    00788   button_layout->addWidget(m_removeAction, 2, 0);
    00789   button_layout->addWidget(m_insertAction, 2, 2);
    00790   button_layout->addWidget(m_downAction, 3, 1);
    00791   button_layout->setRowStretch( 4, 10 );
    00792
    00793   inactive_layout->addWidget(inactive_label);
    00794   inactive_layout->addWidget(m_inactiveList, 1);
    00795
    00796   active_layout->addWidget(active_label);
    00797   active_layout->addWidget(m_activeList, 1);
    00798   active_layout->addLayout(changeIcon_layout);
    00799
    00800   changeIcon_layout->addStretch( 1 );
    00801   changeIcon_layout->addWidget( d->m_changeIcon );
    00802   changeIcon_layout->addStretch( 1 );
    00803
    00804   list_layout->addLayout(inactive_layout);
    00805   list_layout->addLayout(button_layout);
    00806   list_layout->addLayout(active_layout);
    00807
    00808   top_layout->addLayout(name_layout);
    00809   top_layout->addWidget(d->m_comboSeparator);
    00810   top_layout->addLayout(list_layout,10);
    00811   top_layout->addWidget(d->m_helpArea);
    00812   top_layout->addWidget(new KSeparator(this));
    00813 }
    00814
    00815 void KEditToolbarWidget::loadToolbarCombo(const QString& defaultToolbar)
    00816 {
    00817   static const QString &attrName = KGlobal::staticQString( "name" );
    00818   // just in case, we clear our combo
    00819   m_toolbarCombo->clear();
    00820
    00821   int defaultToolbarId = -1;
    00822   int count = 0;
    00823   // load in all of the toolbar names into this combo box
    00824   XmlDataList::Iterator xit = d->m_xmlFiles.begin();
    00825   for ( ; xit != d->m_xmlFiles.end(); ++xit)
    00826   {
    00827     // skip the local one in favor of the merged
    00828     if ( (*xit).m_type == XmlData::Local )
    00829       continue;
    00830
    00831     // each xml file may have any number of toolbars
    00832     ToolbarList::Iterator it = (*xit).m_barList.begin();
    00833     for ( ; it != (*xit).m_barList.end(); ++it)
    00834     {
    00835       QString name = d->toolbarName( *xit, *it );
    00836       m_toolbarCombo->setEnabled( true );
    00837       m_toolbarCombo->insertItem( name );
    00838       if (defaultToolbarId == -1 && (name == defaultToolbar || defaultToolbar == (*it).attribute( attrName )))
    00839           defaultToolbarId = count;
    00840       count++;
    00841     }
    00842   }
    00843   bool showCombo = (count > 1);
    00844   d->m_comboLabel->setShown(showCombo);
    00845   d->m_comboSeparator->setShown(showCombo);
    00846   m_toolbarCombo->setShown(showCombo);
    00847   if (defaultToolbarId == -1)
    00848       defaultToolbarId = 0;
    00849   // we want to the specified item selected and its actions loaded
    00850   m_toolbarCombo->setCurrentItem(defaultToolbarId);
    00851   slotToolbarSelected(m_toolbarCombo->currentText());
    00852 }
    00853
    00854 // KDE4: rename method to e.g. fillLists to disambiguate from <ActionList>
    00855 void KEditToolbarWidget::loadActionList(QDomElement& elem) // KDE4: const QDomElement&
    00856 {
    00857   static const QString &tagSeparator = KGlobal::staticQString( "Separator" );
    00858   static const QString &tagMerge     = KGlobal::staticQString( "Merge" );
    00859   static const QString &tagActionList= KGlobal::staticQString( "ActionList" );
    00860   static const QString &attrName     = KGlobal::staticQString( "name" );
    00861   static const QString &attrLineSeparator = KGlobal::staticQString( "lineSeparator" );
    00862
    00863   int     sep_num = 0;
    00864   QString sep_name("separator_%1");
    00865
    00866   // clear our lists
    00867   m_inactiveList->clear();
    00868   m_activeList->clear();
    00869   m_insertAction->setEnabled(false);
    00870   m_removeAction->setEnabled(false);
    00871   m_upAction->setEnabled(false);
    00872   m_downAction->setEnabled(false);
    00873
    00874   // We'll use this action collection
    00875   KActionCollection* actionCollection = d->m_currentXmlData->m_actionCollection;
    00876
    00877   // store the names of our active actions
    00878   QMap<QString, bool> active_list;
    00879
    00880   // see if our current action is in this toolbar
    00881   QDomNode n = elem.lastChild();
    00882   for( ; !n.isNull(); n = n.previousSibling() )
    00883   {
    00884     QDomElement it = n.toElement();
    00885     if (it.isNull()) continue;
    00886     if (it.tagName() == tagSeparator)
    00887     {
    00888       ToolbarItem *act = new ToolbarItem(m_activeList, tagSeparator, sep_name.arg(sep_num++), QString::null);
    00889       bool isLineSep = ( it.attribute(attrLineSeparator, "true").lower() == QString::fromLatin1("true") );
    00890       if(isLineSep)
    00891         act->setText(1, LINESEPARATORSTRING);
    00892       else
    00893         act->setText(1, SEPARATORSTRING);
    00894       it.setAttribute( attrName, act->internalName() );
    00895       continue;
    00896     }
    00897
    00898     if (it.tagName() == tagMerge)
    00899     {
    00900       // Merge can be named or not - use the name if there is one
    00901       QString name = it.attribute( attrName );
    00902       ToolbarItem *act = new ToolbarItem(m_activeList, tagMerge, name, i18n("This element will be replaced with all the elements of an embedded component."));
    00903       if ( name.isEmpty() )
    00904           act->setText(1, i18n("<Merge>"));
    00905       else
    00906           act->setText(1, i18n("<Merge %1>").arg(name));
    00907       continue;
    00908     }
    00909
    00910     if (it.tagName() == tagActionList)
    00911     {
    00912       ToolbarItem *act = new ToolbarItem(m_activeList, tagActionList, it.attribute(attrName), i18n("This is a dynamic list of actions. You can move it, but if you remove it you won't be able to re-add it.") );
    00913       act->setText(1, i18n("ActionList: %1").arg(it.attribute(attrName)));
    00914       continue;
    00915     }
    00916
    00917     // iterate through this client's actions
    00918     // This used to iterate through _all_ actions, but we don't support
    00919     // putting any action into any client...
    00920     for (unsigned int i = 0;  i < actionCollection->count(); i++)
    00921     {
    00922       KAction *action = actionCollection->action( i );
    00923
    00924       // do we have a match?
    00925       if (it.attribute( attrName ) == action->name())
    00926       {
    00927         // we have a match!
    00928         ToolbarItem *act = new ToolbarItem(m_activeList, it.tagName(), action->name(), action->toolTip());
    00929         act->setText(1, action->plainText());
    00930         if (action->hasIcon())
    00931           if (!action->icon().isEmpty())
    00932             act->setPixmap(0, BarIcon(action->icon(), 16));
    00933           else // Has iconset
    00934             act->setPixmap(0, action->iconSet(KIcon::Toolbar).pixmap());
    00935
    00936         active_list.insert(action->name(), true);
    00937         break;
    00938       }
    00939     }
    00940   }
    00941
    00942   // go through the rest of the collection
    00943   for (int i = actionCollection->count() - 1; i > -1; --i)
    00944   {
    00945     KAction *action = actionCollection->action( i );
    00946
    00947     // skip our active ones
    00948     if (active_list.contains(action->name()))
    00949       continue;
    00950
    00951     ToolbarItem *act = new ToolbarItem(m_inactiveList, tagActionList, action->name(), action->toolTip());
    00952     act->setText(1, action->plainText());
    00953     if (action->hasIcon())
    00954       if (!action->icon().isEmpty())
    00955         act->setPixmap(0, BarIcon(action->icon(), 16));
    00956       else // Has iconset
    00957         act->setPixmap(0, action->iconSet(KIcon::Toolbar).pixmap());
    00958   }
    00959
    00960   // finally, add default separators to the inactive list
    00961   ToolbarItem *act = new ToolbarItem(m_inactiveList, tagSeparator, sep_name.arg(sep_num++), QString::null);
    00962   act->setText(1, LINESEPARATORSTRING);
    00963   act = new ToolbarItem(m_inactiveList, tagSeparator, sep_name.arg(sep_num++), QString::null);
    00964   act->setText(1, SEPARATORSTRING);
    00965 }
    00966
    00967 KActionCollection *KEditToolbarWidget::actionCollection() const
    00968 {
    00969   return d->m_collection;
    00970 }
    00971
    00972 void KEditToolbarWidget::slotToolbarSelected(const QString& _text)
    00973 {
    00974   // iterate through everything
    00975   XmlDataList::Iterator xit = d->m_xmlFiles.begin();
    00976   for ( ; xit != d->m_xmlFiles.end(); ++xit)
    00977   {
    00978     // each xml file may have any number of toolbars
    00979     ToolbarList::Iterator it = (*xit).m_barList.begin();
    00980     for ( ; it != (*xit).m_barList.end(); ++it)
    00981     {
    00982       QString name = d->toolbarName( *xit, *it );
    00983       // is this our toolbar?
    00984       if ( name == _text )
    00985       {
    00986         // save our current settings
    00987         d->m_currentXmlData     = & (*xit);
    00988         d->m_currentToolbarElem = (*it);
    00989
    00990         // load in our values
    00991         loadActionList(d->m_currentToolbarElem);
    00992
    00993         if ((*xit).m_type == XmlData::Part || (*xit).m_type == XmlData::Shell)
    00994           setDOMDocument( (*xit).m_document );
    00995         return;
    00996       }
    00997     }
    00998   }
    00999 }
    01000
    01001 void KEditToolbarWidget::slotInactiveSelected(QListViewItem *item)
    01002 {
    01003   ToolbarItem* toolitem = static_cast<ToolbarItem *>(item);
    01004   if (item)
    01005   {
    01006     m_insertAction->setEnabled(true);
    01007     QString statusText = toolitem->statusText();
    01008     d->m_helpArea->setText( statusText );
    01009   }
    01010   else
    01011   {
    01012     m_insertAction->setEnabled(false);
    01013     d->m_helpArea->setText( QString::null );
    01014   }
    01015 }
    01016
    01017 void KEditToolbarWidget::slotActiveSelected(QListViewItem *item)
    01018 {
    01019   ToolbarItem* toolitem = static_cast<ToolbarItem *>(item);
    01020   m_removeAction->setEnabled( item );
    01021
    01022   static const QString &tagAction = KGlobal::staticQString( "Action" );
    01023   d->m_changeIcon->setEnabled( item &&
    01024                                d->m_hasKDialog &&
    01025                                toolitem->internalTag() == tagAction );
    01026
    01027   if (item)
    01028   {
    01029     if (item->itemAbove())
    01030       m_upAction->setEnabled(true);
    01031     else
    01032       m_upAction->setEnabled(false);
    01033
    01034     if (item->itemBelow())
    01035       m_downAction->setEnabled(true);
    01036     else
    01037       m_downAction->setEnabled(false);
    01038     QString statusText = toolitem->statusText();
    01039     d->m_helpArea->setText( statusText );
    01040   }
    01041   else
    01042   {
    01043     m_upAction->setEnabled(false);
    01044     m_downAction->setEnabled(false);
    01045     d->m_helpArea->setText( QString::null );
    01046   }
    01047 }
    01048
    01049 void KEditToolbarWidget::slotDropped(KListView *list, QDropEvent *e, QListViewItem *after)
    01050 {
    01051   ToolbarItem *item = new ToolbarItem(m_inactiveList); // needs parent, use inactiveList temporarily
    01052   if(!ToolbarItemDrag::decode(e, *item)) {
    01053     delete item;
    01054     return;
    01055   }
    01056
    01057   if (list == m_activeList) {
    01058     if (e->source() == m_activeList) {
    01059       // has been dragged within the active list (moved) -> remove the old item.
    01060       removeActive(item);
    01061     }
    01062
    01063     insertActive(item, after, true);
    01064   } else if (list == m_inactiveList) {
    01065     // has been dragged to the inactive list -> remove from the active list.
    01066     removeActive(item);
    01067   }
    01068
    01069   delete item; item = 0; // not neded anymore
    01070
    01071   // we're modified, so let this change
    01072   emit enableOk(true);
    01073
    01074   slotToolbarSelected( m_toolbarCombo->currentText() );
    01075 }
    01076
    01077 void KEditToolbarWidget::slotInsertButton()
    01078 {
    01079   ToolbarItem *item = static_cast<ToolbarItem *>( m_inactiveList->currentItem() );
    01080   insertActive(item, m_activeList->currentItem(), false);
    01081
    01082   // we're modified, so let this change
    01083   emit enableOk(true);
    01084
    01085   slotToolbarSelected( m_toolbarCombo->currentText() );
    01086 }
    01087
    01088 void KEditToolbarWidget::slotRemoveButton()
    01089 {
    01090   ToolbarItem *item = dynamic_cast<ToolbarItem *>( m_activeList->currentItem() );
    01091   removeActive( item );
    01092
    01093   // we're modified, so let this change
    01094   emit enableOk(true);
    01095
    01096   slotToolbarSelected( m_toolbarCombo->currentText() );
    01097 }
    01098
    01099 void KEditToolbarWidget::insertActive(ToolbarItem *item, QListViewItem *before, bool prepend)
    01100 {
    01101   if (!item)
    01102     return;
    01103
    01104   static const QString &tagAction    = KGlobal::staticQString( "Action" );
    01105   static const QString &tagSeparator = KGlobal::staticQString( "Separator" );
    01106   static const QString &attrName     = KGlobal::staticQString( "name" );
    01107   static const QString &attrLineSeparator = KGlobal::staticQString( "lineSeparator" );
    01108   static const QString &attrNoMerge  = KGlobal::staticQString( "noMerge" );
    01109
    01110   QDomElement new_item;
    01111   // let's handle the separator specially
    01112   if (item->text(1) == LINESEPARATORSTRING) {
    01113     new_item = domDocument().createElement(tagSeparator);
    01114   } else if (item->text(1) == SEPARATORSTRING) {
    01115     new_item = domDocument().createElement(tagSeparator);
    01116     new_item.setAttribute(attrLineSeparator, "false");
    01117   } else
    01118     new_item = domDocument().createElement(tagAction);
    01119   new_item.setAttribute(attrName, item->internalName());
    01120
    01121   if (before)
    01122   {
    01123     // we have the item in the active list which is before the new
    01124     // item.. so let's try our best to add our new item right after it
    01125     ToolbarItem *act_item = (ToolbarItem*)before;
    01126     QDomElement elem = d->findElementForToolbarItem( act_item );
    01127     Q_ASSERT( !elem.isNull() );
    01128     d->m_currentToolbarElem.insertAfter(new_item, elem);
    01129   }
    01130   else
    01131   {
    01132     // simply put it at the beginning or the end of the list.
    01133     if (prepend)
    01134       d->m_currentToolbarElem.insertBefore(new_item, d->m_currentToolbarElem.firstChild());
    01135     else
    01136       d->m_currentToolbarElem.appendChild(new_item);
    01137   }
    01138
    01139   // and set this container as a noMerge
    01140   d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
    01141
    01142   // update the local doc
    01143   updateLocal(d->m_currentToolbarElem);
    01144 }
    01145
    01146 void KEditToolbarWidget::removeActive(ToolbarItem *item)
    01147 {
    01148   if (!item)
    01149     return;
    01150
    01151   static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
    01152
    01153   // we're modified, so let this change
    01154   emit enableOk(true);
    01155
    01156   // now iterate through to find the child to nuke
    01157   QDomElement elem = d->findElementForToolbarItem( item );
    01158   if ( !elem.isNull() )
    01159   {
    01160     // nuke myself!
    01161     d->m_currentToolbarElem.removeChild(elem);
    01162
    01163     // and set this container as a noMerge
    01164     d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
    01165
    01166     // update the local doc
    01167     updateLocal(d->m_currentToolbarElem);
    01168   }
    01169 }
    01170
    01171 void KEditToolbarWidget::slotUpButton()
    01172 {
    01173   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
    01174
    01175   // make sure we're not the top item already
    01176   if (!item->itemAbove())
    01177     return;
    01178
    01179   static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
    01180
    01181   // we're modified, so let this change
    01182   emit enableOk(true);
    01183
    01184   // now iterate through to find where we are
    01185   QDomElement elem = d->findElementForToolbarItem( item );
    01186   if ( !elem.isNull() )
    01187   {
    01188     // cool, i found me.  now clone myself
    01189     ToolbarItem *clone = new ToolbarItem(m_activeList,
    01190                                          item->itemAbove()->itemAbove(),
    01191                                          item->internalTag(),
    01192                                          item->internalName(),
    01193                                          item->statusText());
    01194     clone->setText(1, item->text(1));
    01195
    01196     // only set new pixmap if exists
    01197     if( item->pixmap(0) )
    01198       clone->setPixmap(0, *item->pixmap(0));
    01199
    01200     // remove the old me
    01201     m_activeList->takeItem(item);
    01202     delete item;
    01203
    01204     // select my clone
    01205     m_activeList->setSelected(clone, true);
    01206
    01207     // make clone visible
    01208     m_activeList->ensureItemVisible(clone);
    01209
    01210     // and do the real move in the DOM
    01211     QDomNode prev = elem.previousSibling();
    01212     while ( prev.toElement().tagName() == QString( "WeakSeparator" ) )
    01213         prev = prev.previousSibling();
    01214     d->m_currentToolbarElem.insertBefore(elem, prev);
    01215
    01216     // and set this container as a noMerge
    01217     d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
    01218
    01219     // update the local doc
    01220     updateLocal(d->m_currentToolbarElem);
    01221   }
    01222 }
    01223
    01224 void KEditToolbarWidget::slotDownButton()
    01225 {
    01226   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
    01227
    01228   // make sure we're not the bottom item already
    01229   if (!item->itemBelow())
    01230     return;
    01231
    01232   static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
    01233
    01234   // we're modified, so let this change
    01235   emit enableOk(true);
    01236
    01237   // now iterate through to find where we are
    01238   QDomElement elem = d->findElementForToolbarItem( item );
    01239   if ( !elem.isNull() )
    01240   {
    01241     // cool, i found me.  now clone myself
    01242     ToolbarItem *clone = new ToolbarItem(m_activeList,
    01243                                          item->itemBelow(),
    01244                                          item->internalTag(),
    01245                                          item->internalName(),
    01246                                          item->statusText());
    01247     clone->setText(1, item->text(1));
    01248
    01249     // only set new pixmap if exists
    01250     if( item->pixmap(0) )
    01251       clone->setPixmap(0, *item->pixmap(0));
    01252
    01253     // remove the old me
    01254     m_activeList->takeItem(item);
    01255     delete item;
    01256
    01257     // select my clone
    01258     m_activeList->setSelected(clone, true);
    01259
    01260     // make clone visible
    01261     m_activeList->ensureItemVisible(clone);
    01262
    01263     // and do the real move in the DOM
    01264     QDomNode next = elem.nextSibling();
    01265     while ( next.toElement().tagName() == QString( "WeakSeparator" ) )
    01266       next = next.nextSibling();
    01267     d->m_currentToolbarElem.insertAfter(elem, next);
    01268
    01269     // and set this container as a noMerge
    01270     d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
    01271
    01272     // update the local doc
    01273     updateLocal(d->m_currentToolbarElem);
    01274   }
    01275 }
    01276
    01277 void KEditToolbarWidget::updateLocal(QDomElement& elem)
    01278 {
    01279   static const QString &attrName = KGlobal::staticQString( "name" );
    01280
    01281   XmlDataList::Iterator xit = d->m_xmlFiles.begin();
    01282   for ( ; xit != d->m_xmlFiles.end(); ++xit)
    01283   {
    01284     if ( (*xit).m_type == XmlData::Merged )
    01285       continue;
    01286
    01287     if ( (*xit).m_type == XmlData::Shell ||
    01288          (*xit).m_type == XmlData::Part )
    01289     {
    01290       if ( d->m_currentXmlData->m_xmlFile == (*xit).m_xmlFile )
    01291       {
    01292         (*xit).m_isModified = true;
    01293         return;
    01294       }
    01295
    01296       continue;
    01297     }
    01298
    01299     (*xit).m_isModified = true;
    01300
    01301     ToolbarList::Iterator it = (*xit).m_barList.begin();
    01302     for ( ; it != (*xit).m_barList.end(); ++it)
    01303     {
    01304       QString name( (*it).attribute( attrName ) );
    01305       QString tag( (*it).tagName() );
    01306       if ( (tag != elem.tagName()) || (name != elem.attribute(attrName)) )
    01307         continue;
    01308
    01309       QDomElement toolbar = (*xit).m_document.documentElement().toElement();
    01310       toolbar.replaceChild(elem, (*it));
    01311       return;
    01312     }
    01313
    01314     // just append it
    01315     QDomElement toolbar = (*xit).m_document.documentElement().toElement();
    01316     toolbar.appendChild(elem);
    01317   }
    01318 }
    01319
    01320 void KEditToolbarWidget::slotChangeIcon()
    01321 {
    01322   // We can't use KIconChooser here, since it's in libkio
    01323   // ##### KDE4: reconsider this, e.g. move KEditToolbar to libkio
    01324   d->m_kdialogProcess = new KProcIO;
    01325   QString kdialogExe = KStandardDirs::findExe(QString::fromLatin1("kdialog"));
    01326   (*d->m_kdialogProcess) << kdialogExe;
    01327   (*d->m_kdialogProcess) << "--embed";
    01328   (*d->m_kdialogProcess) << QString::number( (ulong)topLevelWidget()->winId() );
    01329   (*d->m_kdialogProcess) << "--geticon";
    01330   (*d->m_kdialogProcess) << "Toolbar";
    01331   (*d->m_kdialogProcess) << "Actions";
    01332   if ( !d->m_kdialogProcess->start( KProcess::NotifyOnExit ) ) {
    01333     kdError(240) << "Can't run " << kdialogExe << endl;
    01334     delete d->m_kdialogProcess;
    01335     d->m_kdialogProcess = 0;
    01336     return;
    01337   }
    01338
    01339   m_activeList->setEnabled( false ); // don't change the current item
    01340   m_toolbarCombo->setEnabled( false ); // don't change the current toolbar
    01341
    01342   connect( d->m_kdialogProcess, SIGNAL( processExited( KProcess* ) ),
    01343            this, SLOT( slotProcessExited( KProcess* ) ) );
    01344 }
    01345
    01346 void KEditToolbarWidget::slotProcessExited( KProcess* )
    01347 {
    01348   m_activeList->setEnabled( true );
    01349   m_toolbarCombo->setEnabled( true );
    01350
    01351   QString icon;
    01352   if ( !d->m_kdialogProcess->normalExit() ||
    01353        d->m_kdialogProcess->exitStatus() ||
    01354        d->m_kdialogProcess->readln(icon, true) <= 0 ) {
    01355     delete d->m_kdialogProcess;
    01356     d->m_kdialogProcess = 0;
    01357     return;
    01358   }
    01359
    01360   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
    01361   if(item){
    01362     item->setPixmap(0, BarIcon(icon, 16));
    01363
    01364     Q_ASSERT( d->m_currentXmlData->m_type != XmlData::Merged );
    01365
    01366     d->m_currentXmlData->m_isModified = true;
    01367
    01368     // Get hold of ActionProperties tag
    01369     QDomElement elem = KXMLGUIFactory::actionPropertiesElement( d->m_currentXmlData->m_document );
    01370     // Find or create an element for this action
    01371     QDomElement act_elem = KXMLGUIFactory::findActionByName( elem, item->internalName(), true /*create*/ );
    01372     Q_ASSERT( !act_elem.isNull() );
    01373     act_elem.setAttribute( "icon", icon );
    01374
    01375     // we're modified, so let this change
    01376     emit enableOk(true);
    01377   }
    01378
    01379   delete d->m_kdialogProcess;
    01380   d->m_kdialogProcess = 0;
    01381 }
    01382
    01383 void KEditToolbar::virtual_hook( int id, void* data )
    01384 { KDialogBase::virtual_hook( id, data ); }
    01385
    01386 void KEditToolbarWidget::virtual_hook( int id, void* data )
    01387 { KXMLGUIClient::virtual_hook( id, data ); }
    01388
    01389 #include "kedittoolbar.moc"

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:17 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003