• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeui
 

tdeui

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

tdeui

Skip menu "tdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeui

Skip menu "tdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeui by doxygen 1.7.1
This website is maintained by Timothy Pearson.