kdeui Library API Documentation

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).
01060       moveActive(item, after);
01061     }
01062     else
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   // we're modified, so let this change
01180   emit enableOk(true);
01181 
01182   moveActive( item, item->itemAbove()->itemAbove() );
01183   delete item;
01184 }
01185 
01186 void KEditToolbarWidget::moveActive( ToolbarItem* item, QListViewItem* before )
01187 {
01188   QDomElement e = d->findElementForToolbarItem( item );
01189 
01190   if ( e.isNull() )
01191     return;
01192 
01193   // cool, i found me.  now clone myself
01194   ToolbarItem *clone = new ToolbarItem(m_activeList,
01195                                        before,
01196                                        item->internalTag(),
01197                                        item->internalName(),
01198                                        item->statusText());
01199 
01200   clone->setText(1, item->text(1));
01201 
01202   // only set new pixmap if exists
01203   if( item->pixmap(0) )
01204     clone->setPixmap(0, *item->pixmap(0));
01205 
01206   // select my clone
01207   m_activeList->setSelected(clone, true);
01208 
01209   // make clone visible
01210   m_activeList->ensureItemVisible(clone);
01211 
01212   // and do the real move in the DOM
01213   if ( !before )
01214     d->m_currentToolbarElem.insertBefore(e, d->m_currentToolbarElem.firstChild() );
01215   else
01216     d->m_currentToolbarElem.insertAfter(e, d->findElementForToolbarItem( (ToolbarItem*)before ));
01217 
01218   // and set this container as a noMerge
01219   static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
01220   d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
01221 
01222   // update the local doc
01223   updateLocal(d->m_currentToolbarElem);
01224 }
01225 
01226 void KEditToolbarWidget::slotDownButton()
01227 {
01228   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
01229 
01230   // make sure we're not the bottom item already
01231   if (!item->itemBelow())
01232     return;
01233 
01234   // we're modified, so let this change
01235   emit enableOk(true);
01236 
01237   moveActive( item, item->itemBelow() );
01238   delete item;
01239 }
01240 
01241 void KEditToolbarWidget::updateLocal(QDomElement& elem)
01242 {
01243   static const QString &attrName = KGlobal::staticQString( "name" );
01244 
01245   XmlDataList::Iterator xit = d->m_xmlFiles.begin();
01246   for ( ; xit != d->m_xmlFiles.end(); ++xit)
01247   {
01248     if ( (*xit).m_type == XmlData::Merged )
01249       continue;
01250 
01251     if ( (*xit).m_type == XmlData::Shell ||
01252          (*xit).m_type == XmlData::Part )
01253     {
01254       if ( d->m_currentXmlData->m_xmlFile == (*xit).m_xmlFile )
01255       {
01256         (*xit).m_isModified = true;
01257         return;
01258       }
01259 
01260       continue;
01261     }
01262 
01263     (*xit).m_isModified = true;
01264 
01265     ToolbarList::Iterator it = (*xit).m_barList.begin();
01266     for ( ; it != (*xit).m_barList.end(); ++it)
01267     {
01268       QString name( (*it).attribute( attrName ) );
01269       QString tag( (*it).tagName() );
01270       if ( (tag != elem.tagName()) || (name != elem.attribute(attrName)) )
01271         continue;
01272 
01273       QDomElement toolbar = (*xit).m_document.documentElement().toElement();
01274       toolbar.replaceChild(elem, (*it));
01275       return;
01276     }
01277 
01278     // just append it
01279     QDomElement toolbar = (*xit).m_document.documentElement().toElement();
01280     toolbar.appendChild(elem);
01281   }
01282 }
01283 
01284 void KEditToolbarWidget::slotChangeIcon()
01285 {
01286   // We can't use KIconChooser here, since it's in libkio
01287   // ##### KDE4: reconsider this, e.g. move KEditToolbar to libkio
01288   d->m_kdialogProcess = new KProcIO;
01289   QString kdialogExe = KStandardDirs::findExe(QString::fromLatin1("kdialog"));
01290   (*d->m_kdialogProcess) << kdialogExe;
01291   (*d->m_kdialogProcess) << "--embed";
01292   (*d->m_kdialogProcess) << QString::number( (ulong)topLevelWidget()->winId() );
01293   (*d->m_kdialogProcess) << "--geticon";
01294   (*d->m_kdialogProcess) << "Toolbar";
01295   (*d->m_kdialogProcess) << "Actions";
01296   if ( !d->m_kdialogProcess->start( KProcess::NotifyOnExit ) ) {
01297     kdError(240) << "Can't run " << kdialogExe << endl;
01298     delete d->m_kdialogProcess;
01299     d->m_kdialogProcess = 0;
01300     return;
01301   }
01302 
01303   m_activeList->setEnabled( false ); // don't change the current item
01304   m_toolbarCombo->setEnabled( false ); // don't change the current toolbar
01305 
01306   connect( d->m_kdialogProcess, SIGNAL( processExited( KProcess* ) ),
01307            this, SLOT( slotProcessExited( KProcess* ) ) );
01308 }
01309 
01310 void KEditToolbarWidget::slotProcessExited( KProcess* )
01311 {
01312   m_activeList->setEnabled( true );
01313   m_toolbarCombo->setEnabled( true );
01314 
01315   QString icon;
01316   if ( !d->m_kdialogProcess->normalExit() ||
01317        d->m_kdialogProcess->exitStatus() ||
01318        d->m_kdialogProcess->readln(icon, true) <= 0 ) {
01319     delete d->m_kdialogProcess;
01320     d->m_kdialogProcess = 0;
01321     return;
01322   }
01323 
01324   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
01325   if(item){
01326     item->setPixmap(0, BarIcon(icon, 16));
01327 
01328     Q_ASSERT( d->m_currentXmlData->m_type != XmlData::Merged );
01329 
01330     d->m_currentXmlData->m_isModified = true;
01331 
01332     // Get hold of ActionProperties tag
01333     QDomElement elem = KXMLGUIFactory::actionPropertiesElement( d->m_currentXmlData->m_document );
01334     // Find or create an element for this action
01335     QDomElement act_elem = KXMLGUIFactory::findActionByName( elem, item->internalName(), true /*create*/ );
01336     Q_ASSERT( !act_elem.isNull() );
01337     act_elem.setAttribute( "icon", icon );
01338 
01339     // we're modified, so let this change
01340     emit enableOk(true);
01341   }
01342   
01343   delete d->m_kdialogProcess;
01344   d->m_kdialogProcess = 0;
01345 }
01346 
01347 void KEditToolbar::virtual_hook( int id, void* data )
01348 { KDialogBase::virtual_hook( id, data ); }
01349 
01350 void KEditToolbarWidget::virtual_hook( int id, void* data )
01351 { KXMLGUIClient::virtual_hook( id, data ); }
01352 
01353 #include "kedittoolbar.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Aug 2 12:23:18 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003