kedittoolbar.cpp Source File (kdeui Library)

| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kedittoolbar.cpp

    00001 /* This file is part of the KDE libraries
    00002    Copyright (C) 2000 Kurt Granroth <granroth@kde.org>
    00003
    00004    This library is free software; you can redistribute it and/or
    00005    modify it under the terms of the GNU Library General Public
    00006    License version 2 as published by the Free Software Foundation.
    00007
    00008    This library is distributed in the hope that it will be useful,
    00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
    00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00011    Library General Public License for more details.
    00012
    00013    You should have received a copy of the GNU Library General Public License
    00014    along with this library; see the file COPYING.LIB.  If not, write to
    00015    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00016    Boston, MA 02111-1307, USA.
    00017 */
    00018 #include <kedittoolbar.h>
    00019
    00020 #include <qdom.h>
    00021
    00022 #include <qlayout.h>
    00023 #include <kaction.h>
    00024
    00025 #include <qheader.h>
    00026 #include <qcombobox.h>
    00027 #include <qpushbutton.h>
    00028 #include <qlabel.h>
    00029 #include <qvaluelist.h>
    00030
    00031 #include <kstandarddirs.h>
    00032 #include <klocale.h>
    00033 #include <kicontheme.h>
    00034 #include <kiconloader.h>
    00035 #include <kinstance.h>
    00036 #include <kxmlguifactory.h>
    00037 #include <kseparator.h>
    00038 #include <kconfig.h>
    00039 #include <klistview.h>
    00040
    00041 #include <qtextstream.h>
    00042 #include <qfile.h>
    00043 #include <kdebug.h>
    00044 #include <kdebugclasses.h>
    00045
    00046 static void dump_xml(const QDomDocument& doc)
    00047 {
    00048     QString str;
    00049     QTextStream ts(&str, IO_WriteOnly);
    00050     ts << doc;
    00051     kdDebug() << str << endl;
    00052 }
    00053
    00054 typedef QValueList<QDomElement> ToolbarList;
    00055
    00056 class XmlData
    00057 {
    00058 public:
    00059   enum XmlType { Shell = 0, Part, Local, Merged };
    00060   XmlData()
    00061   {
    00062     m_isModified = false;
    00063   }
    00064
    00065   QString      m_xmlFile;
    00066   QDomDocument m_document;
    00067   XmlType      m_type;
    00068   bool         m_isModified;
    00069
    00070   ToolbarList  m_barList;
    00071 };
    00072
    00073 typedef QValueList<XmlData> XmlDataList;
    00074
    00075 class ToolbarItem : public QListViewItem
    00076 {
    00077 public:
    00078   ToolbarItem(KListView *parent, const QString& tag, const QString& name, const QString& statusText)
    00079     : QListViewItem(parent),
    00080       m_tag(tag),
    00081       m_name(name),
    00082       m_statusText(statusText)
    00083   {
    00084   }
    00085
    00086   ToolbarItem(KListView *parent, QListViewItem *item, const QString &tag, const QString& name, const QString& statusText)
    00087     : QListViewItem(parent, item),
    00088       m_tag(tag),
    00089       m_name(name),
    00090       m_statusText(statusText)
    00091   {
    00092   }
    00093
    00094   QString internalTag() const { return m_tag; }
    00095   QString internalName() const { return m_name; }
    00096   QString statusText() const { return m_statusText; }
    00097 private:
    00098   QString m_tag;
    00099   QString m_name;
    00100   QString m_statusText;
    00101 };
    00102
    00103 class KEditToolbarWidgetPrivate
    00104 {
    00105 public:
    00106   KEditToolbarWidgetPrivate(KInstance *instance, KActionCollection* collection)
    00107       : m_collection( collection )
    00108   {
    00109     m_instance = instance;
    00110     m_isPart   = false;
    00111     m_helpArea = 0L;
    00112   }
    00113   ~KEditToolbarWidgetPrivate()
    00114   {
    00115   }
    00116
    00117   QString xmlFile(const QString& xml_file)
    00118   {
    00119     return xml_file.isNull() ? QString(m_instance->instanceName()) + "ui.rc" :
    00120                                xml_file;
    00121   }
    00122
    00126   QString loadXMLFile(const QString& _xml_file)
    00127   {
    00128     QString raw_xml;
    00129     QString xml_file = xmlFile(_xml_file);
    00130     //kdDebug() << "loadXMLFile xml_file=" << xml_file << endl;
    00131
    00132     if ( xml_file[0] == '/' )
    00133       raw_xml = KXMLGUIFactory::readConfigFile(xml_file);
    00134     else
    00135       raw_xml = KXMLGUIFactory::readConfigFile(xml_file, m_instance);
    00136
    00137     return raw_xml;
    00138   }
    00139
    00143   ToolbarList findToolbars(QDomElement elem)
    00144   {
    00145     static const QString &tagToolbar = KGlobal::staticQString( "ToolBar" );
    00146     static const QString &attrNoEdit = KGlobal::staticQString( "noEdit" );
    00147     ToolbarList list;
    00148
    00149     for( ; !elem.isNull(); elem = elem.nextSibling().toElement() )
    00150     {
    00151       if (elem.tagName() == tagToolbar && elem.attribute( attrNoEdit ) != "true" )
    00152         list.append(elem);
    00153
    00154       QDomElement child = elem.firstChild().toElement();
    00155       list += findToolbars(child);
    00156     }
    00157
    00158     return list;
    00159   }
    00160
    00161   QValueList<KAction*> m_actionList;
    00162   KActionCollection* m_collection;
    00163   KInstance         *m_instance;
    00164
    00165   XmlData     m_currentXmlData;
    00166   QDomElement m_currentToolbarElem;
    00167
    00168   QString            m_xmlFile;
    00169   QString            m_globalFile;
    00170   QString            m_rcFile;
    00171   QDomDocument       m_localDoc;
    00172   bool               m_isPart;
    00173
    00174   ToolbarList        m_barList;
    00175
    00176   XmlDataList m_xmlFiles;
    00177
    00178   QLabel * m_helpArea;
    00179
    00180 };
    00181
    00182 class KEditToolbarPrivate {
    00183 public:
    00184     bool m_accept;
    00185 };
    00186
    00187 KEditToolbar::KEditToolbar(KActionCollection *collection, const QString& file,
    00188                            bool global, QWidget* parent, const char* name)
    00189   : KDialogBase(Swallow, i18n("Configure Toolbars"), Ok|Apply|Cancel, Ok, parent, name),
    00190     m_widget(new KEditToolbarWidget(collection, file, global, this))
    00191 {
    00192     init();
    00193 }
    00194
    00195 KEditToolbar::KEditToolbar(KXMLGUIFactory* factory, QWidget* parent, const char* name)
    00196     : KDialogBase(Swallow, i18n("Configure Toolbars"), Ok|Apply|Cancel, Ok, parent, name),
    00197       m_widget(new KEditToolbarWidget(factory, this))
    00198 {
    00199     init();
    00200 }
    00201
    00202 void KEditToolbar::init()
    00203 {
    00204     d = new KEditToolbarPrivate();
    00205     d->m_accept = false;
    00206
    00207     setMainWidget(m_widget);
    00208
    00209     connect(m_widget, SIGNAL(enableOk(bool)), SLOT(acceptOK(bool)));
    00210     connect(m_widget, SIGNAL(enableOk(bool)), SLOT(enableButtonApply(bool)));
    00211     enableButtonApply(false);
    00212
    00213     setMinimumSize(sizeHint());
    00214 }
    00215
    00216 KEditToolbar::~KEditToolbar()
    00217 {
    00218     delete d;
    00219 }
    00220
    00221 void KEditToolbar::acceptOK(bool b)
    00222 {
    00223     enableButtonOK(b);
    00224     d->m_accept = b;
    00225 }
    00226
    00227 void KEditToolbar::slotOk()
    00228 {
    00229   if (!d->m_accept) {
    00230       reject();
    00231       return;
    00232   }
    00233
    00234   if (!m_widget->save())
    00235   {
    00236     // some error box here is needed
    00237   }
    00238   else
    00239   {
    00240     emit newToolbarConfig();
    00241     accept();
    00242   }
    00243 }
    00244
    00245 void KEditToolbar::slotApply()
    00246 {
    00247     (void)m_widget->save();
    00248     enableButtonApply(false);
    00249     emit newToolbarConfig();
    00250 }
    00251
    00252 KEditToolbarWidget::KEditToolbarWidget(KActionCollection *collection,
    00253                                        const QString& file,
    00254                                        bool global, QWidget *parent)
    00255   : QWidget(parent),
    00256     d(new KEditToolbarWidgetPrivate(instance(), collection))
    00257 {
    00258   // let's not forget the stuff that's not xml specific
    00259   //d->m_collection = *collection;
    00260   d->m_actionList = collection->actions();
    00261
    00262   // handle the merging
    00263   if (global)
    00264     setXMLFile(locate("config", "ui/ui_standards.rc"));
    00265   QString localXML = d->loadXMLFile(file);
    00266   setXML(localXML, true);
    00267
    00268   // reusable vars
    00269   QDomElement elem;
    00270
    00271   // first, get all of the necessary info for our local xml
    00272   XmlData local;
    00273   local.m_xmlFile = d->xmlFile(file);
    00274   local.m_type    = XmlData::Local;
    00275   local.m_document.setContent(localXML);
    00276   elem = local.m_document.documentElement().toElement();
    00277   KXMLGUIFactory::removeDOMComments( elem );
    00278   local.m_barList = d->findToolbars(elem);
    00279   d->m_xmlFiles.append(local);
    00280
    00281   // then, the merged one
    00282   XmlData merge;
    00283   merge.m_xmlFile  = QString::null;
    00284   merge.m_type     = XmlData::Merged;
    00285   merge.m_document = domDocument();
    00286   elem = merge.m_document.documentElement().toElement();
    00287   merge.m_barList  = d->findToolbars(elem);
    00288   d->m_xmlFiles.append(merge);
    00289
    00290   // okay, that done, we concern ourselves with the GUI aspects
    00291   setupLayout();
    00292
    00293   // now load in our toolbar combo box
    00294   loadToolbarCombo();
    00295   adjustSize();
    00296
    00297   //kdDebug() << "kedittoolbarwidget " << sizeHint() << endl;
    00298   setMinimumSize(sizeHint());
    00299 }
    00300
    00301 KEditToolbarWidget::KEditToolbarWidget( KXMLGUIFactory* factory,
    00302                                         QWidget *parent)
    00303   : QWidget(parent),
    00304     d(new KEditToolbarWidgetPrivate(instance(), KXMLGUIClient::actionCollection() /*create new one*/))
    00305 {
    00306   // reusable vars
    00307   QDomElement elem;
    00308
    00309   setFactory( factory );
    00310   actionCollection()->setWidget( this );
    00311
    00312   // add all of the client data
    00313   QPtrList<KXMLGUIClient> clients(factory->clients());
    00314   QPtrListIterator<KXMLGUIClient> it( clients );
    00315   for( ; it.current(); ++it)
    00316   {
    00317     KXMLGUIClient *client = it.current();
    00318
    00319     if (client->xmlFile().isNull())
    00320       continue;
    00321
    00322     XmlData data;
    00323     data.m_xmlFile = client->localXMLFile();
    00324     if ( it.atFirst() )
    00325       data.m_type = XmlData::Shell;
    00326     else
    00327       data.m_type = XmlData::Part;
    00328     data.m_document.setContent( KXMLGUIFactory::readConfigFile( client->xmlFile(), client->instance() ) );
    00329     elem = data.m_document.documentElement().toElement();
    00330     KXMLGUIFactory::removeDOMComments( elem );
    00331     data.m_barList = d->findToolbars(elem);
    00332     d->m_xmlFiles.append(data);
    00333
    00334     d->m_actionList += client->actionCollection()->actions();
    00335   }
    00336
    00337   // okay, that done, we concern ourselves with the GUI aspects
    00338   setupLayout();
    00339   setMinimumSize(sizeHint());
    00340
    00341   // now load in our toolbar combo box
    00342   loadToolbarCombo();
    00343 }
    00344
    00345 KEditToolbarWidget::~KEditToolbarWidget()
    00346 {
    00347     delete d;
    00348 }
    00349
    00350 bool KEditToolbarWidget::save()
    00351 {
    00352   //kdDebug() << "KEditToolbarWidget::save" << endl;
    00353   XmlDataList::Iterator it = d->m_xmlFiles.begin();
    00354   for ( ; it != d->m_xmlFiles.end(); ++it)
    00355   {
    00356     // let's not save non-modified files
    00357     if ( (*it).m_isModified == false )
    00358       continue;
    00359
    00360     // let's also skip (non-existent) merged files
    00361     if ( (*it).m_type == XmlData::Merged )
    00362       continue;
    00363
    00364     dump_xml((*it).m_document.toDocument());
    00365
    00366     // if we got this far, we might as well just save it
    00367     KXMLGUIFactory::saveConfigFile((*it).m_document, (*it).m_xmlFile);
    00368   }
    00369
    00370   if ( !factory() )
    00371     return true;
    00372
    00373   QPtrList<KXMLGUIClient> clients(factory()->clients());
    00374
    00375   // remove the elements starting from the last going to the first
    00376   KXMLGUIClient *client = clients.last();
    00377   while ( client )
    00378   {
    00379     //kdDebug() << "factory->removeClient " << client << endl;
    00380     factory()->removeClient( client );
    00381     client = clients.prev();
    00382   }
    00383
    00384   client = clients.first();
    00385   KXMLGUIClient *firstClient = client;
    00386
    00387   // now, rebuild the gui from the first to the last
    00388   //kdDebug() << "rebuildling the gui" << endl;
    00389   for (; client; client = clients.next() )
    00390   {
    00391     QString file( client->xmlFile() ); // before setting ui_standards!
    00392     if ( !file.isEmpty() )
    00393     {
    00394         // passing an empty stream forces the clients to reread the XML
    00395         client->setXMLGUIBuildDocument( QDomDocument() );
    00396
    00397         // for the shell, merge in ui_standards.rc
    00398         if ( client == firstClient ) // same assumption as in the ctor: first==shell
    00399             client->setXMLFile(locate("config", "ui/ui_standards.rc"));
    00400
    00401         // and this forces it to use the *new* XML file
    00402         client->setXMLFile( file, client == firstClient /* merge if shell */ );
    00403     }
    00404
    00405     //kdDebug() << "factory->addClient " << client << endl;
    00406     // finally, do all the real work
    00407     factory()->addClient( client );
    00408   }
    00409
    00410   return true;
    00411 }
    00412
    00413 void KEditToolbarWidget::setupLayout()
    00414 {
    00415   // the toolbar name combo
    00416   QLabel *toolbar_label = new QLabel(i18n("&Toolbar:"), this);
    00417   m_toolbarCombo = new QComboBox(this);
    00418   m_toolbarCombo->setEnabled(false);
    00419   toolbar_label->setBuddy(m_toolbarCombo);
    00420   connect(m_toolbarCombo, SIGNAL(activated(const QString&)),
    00421           this,           SLOT(slotToolbarSelected(const QString&)));
    00422
    00423 //  QPushButton *new_toolbar = new QPushButton(i18n("&New"), this);
    00424 //  new_toolbar->setPixmap(BarIcon("filenew", KIcon::SizeSmall));
    00425 //  new_toolbar->setEnabled(false); // disabled until implemented
    00426 //  QPushButton *del_toolbar = new QPushButton(i18n("&Delete"), this);
    00427 //  del_toolbar->setPixmap(BarIcon("editdelete", KIcon::SizeSmall));
    00428 //  del_toolbar->setEnabled(false); // disabled until implemented
    00429
    00430   // our list of inactive actions
    00431   QLabel *inactive_label = new QLabel(i18n("A&vailable actions:"), this);
    00432   m_inactiveList = new KListView(this);
    00433   m_inactiveList->setAllColumnsShowFocus(true);
    00434   m_inactiveList->setMinimumSize(180, 250);
    00435   m_inactiveList->header()->hide();
    00436   m_inactiveList->addColumn("");
    00437   int column2 = m_inactiveList->addColumn("");
    00438   m_inactiveList->setSorting( column2 );
    00439   inactive_label->setBuddy(m_inactiveList);
    00440   connect(m_inactiveList, SIGNAL(selectionChanged(QListViewItem *)),
    00441           this,           SLOT(slotInactiveSelected(QListViewItem *)));
    00442
    00443   // our list of active actions
    00444   QLabel *active_label = new QLabel(i18n("Curr&ent actions:"), this);
    00445   m_activeList = new KListView(this);
    00446   m_activeList->setAllColumnsShowFocus(true);
    00447   m_activeList->setMinimumWidth(m_inactiveList->minimumWidth());
    00448   m_activeList->header()->hide();
    00449   m_activeList->addColumn("");
    00450   m_activeList->addColumn("");
    00451   m_activeList->setSorting (-1);
    00452   active_label->setBuddy(m_activeList);
    00453
    00454   connect(m_activeList, SIGNAL(selectionChanged(QListViewItem *)),
    00455           this,         SLOT(slotActiveSelected(QListViewItem *)));
    00456
    00457   QIconSet iconSet;
    00458   QPixmap pixMap;
    00459
    00460   m_upAction     = new QPushButton(QString::null, this);
    00461   iconSet = SmallIconSet( "up" );
    00462   m_upAction->setIconSet( iconSet );
    00463   pixMap = iconSet.pixmap( QIconSet::Small, QIconSet::Normal );
    00464   m_upAction->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
    00465   m_upAction->setEnabled(false);
    00466   connect(m_upAction, SIGNAL(clicked()), SLOT(slotUpButton()));
    00467
    00468   m_insertAction = new QPushButton(QString::null, this);
    00469   iconSet = SmallIconSet( "forward" );
    00470   m_insertAction->setIconSet( iconSet );
    00471   m_insertAction->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
    00472   m_insertAction->setEnabled(false);
    00473   connect(m_insertAction, SIGNAL(clicked()), SLOT(slotInsertButton()));
    00474
    00475   m_removeAction = new QPushButton(QString::null, this);
    00476   iconSet = SmallIconSet( "back" );
    00477   m_removeAction->setIconSet( iconSet );
    00478   m_removeAction->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
    00479   m_removeAction->setEnabled(false);
    00480   connect(m_removeAction, SIGNAL(clicked()), SLOT(slotRemoveButton()));
    00481
    00482   m_downAction   = new QPushButton(QString::null, this);
    00483   iconSet = SmallIconSet( "down" );
    00484   m_downAction->setIconSet( iconSet );
    00485   m_downAction->setFixedSize( pixMap.width()+8, pixMap.height()+8 );
    00486   m_downAction->setEnabled(false);
    00487   connect(m_downAction, SIGNAL(clicked()), SLOT(slotDownButton()));
    00488
    00489   d->m_helpArea = new QLabel(this);
    00490   d->m_helpArea->setAlignment( Qt::WordBreak );
    00491
    00492   // now start with our layouts
    00493   QVBoxLayout *top_layout = new QVBoxLayout(this, 0, KDialog::spacingHint());
    00494
    00495   QVBoxLayout *name_layout = new QVBoxLayout(KDialog::spacingHint());
    00496   QHBoxLayout *list_layout = new QHBoxLayout(KDialog::spacingHint());
    00497
    00498   QVBoxLayout *inactive_layout = new QVBoxLayout(KDialog::spacingHint());
    00499   QVBoxLayout *active_layout = new QVBoxLayout(KDialog::spacingHint());
    00500
    00501   QGridLayout *button_layout = new QGridLayout(5, 3, 0);
    00502
    00503   name_layout->addWidget(toolbar_label);
    00504   name_layout->addWidget(m_toolbarCombo);
    00505 //  name_layout->addWidget(new_toolbar);
    00506 //  name_layout->addWidget(del_toolbar);
    00507
    00508   button_layout->addWidget(m_upAction, 1, 1);
    00509   button_layout->addWidget(m_removeAction, 2, 0);
    00510   button_layout->addWidget(m_insertAction, 2, 2);
    00511   button_layout->addWidget(m_downAction, 3, 1);
    00512
    00513   inactive_layout->addWidget(inactive_label);
    00514   inactive_layout->addWidget(m_inactiveList, 1);
    00515
    00516   active_layout->addWidget(active_label);
    00517   active_layout->addWidget(m_activeList, 1);
    00518
    00519   list_layout->addLayout(inactive_layout);
    00520   list_layout->addLayout(button_layout);
    00521   list_layout->addLayout(active_layout);
    00522
    00523   top_layout->addLayout(name_layout);
    00524   top_layout->addWidget(new KSeparator(this));
    00525   top_layout->addLayout(list_layout,10);
    00526   top_layout->addWidget(d->m_helpArea);
    00527   top_layout->addWidget(new KSeparator(this));
    00528 }
    00529
    00530 void KEditToolbarWidget::loadToolbarCombo()
    00531 {
    00532   static const QString &attrName = KGlobal::staticQString( "name" );
    00533   static const QString &tagText = KGlobal::staticQString( "text" );
    00534   static const QString &tagText2 = KGlobal::staticQString( "Text" );
    00535
    00536   // just in case, we clear our combo
    00537   m_toolbarCombo->clear();
    00538
    00539   // load in all of the toolbar names into this combo box
    00540   XmlDataList::Iterator xit = d->m_xmlFiles.begin();
    00541   for ( ; xit != d->m_xmlFiles.end(); ++xit)
    00542   {
    00543     // skip the local one in favor of the merged
    00544     if ( (*xit).m_type == XmlData::Local )
    00545       continue;
    00546
    00547     // each xml file may have any number of toolbars
    00548     ToolbarList::Iterator it = (*xit).m_barList.begin();
    00549     for ( ; it != (*xit).m_barList.end(); ++it)
    00550     {
    00551       QString name;
    00552       QCString txt( (*it).namedItem( tagText ).toElement().text().utf8() );
    00553       if ( txt.isEmpty() )
    00554           txt = (*it).namedItem( tagText2 ).toElement().text().utf8();
    00555       if ( txt.isEmpty() )
    00556           name = (*it).attribute( attrName );
    00557       else
    00558           name = i18n( txt );
    00559
    00560       // the name of the toolbar might depend on whether or not
    00561       // it is in kparts
    00562       if ( ( (*xit).m_type == XmlData::Shell ) ||
    00563            ( (*xit).m_type == XmlData::Part ) )
    00564       {
    00565         QString doc_name((*xit).m_document.documentElement().attribute( attrName ));
    00566         name += " <" + doc_name + ">";
    00567       }
    00568
    00569       m_toolbarCombo->setEnabled( true );
    00570       m_toolbarCombo->insertItem( name );
    00571     }
    00572   }
    00573
    00574   // we want to the first item selected and its actions loaded
    00575   slotToolbarSelected( m_toolbarCombo->currentText() );
    00576 }
    00577
    00578 void KEditToolbarWidget::loadActionList(QDomElement& elem)
    00579 {
    00580   static const QString &tagSeparator = KGlobal::staticQString( "Separator" );
    00581   static const QString &tagMerge     = KGlobal::staticQString( "Merge" );
    00582   static const QString &tagActionList= KGlobal::staticQString( "ActionList" );
    00583   static const QString &attrName     = KGlobal::staticQString( "name" );
    00584
    00585   int     sep_num = 0;
    00586   QString sep_name("separator_%1");
    00587
    00588   // clear our lists
    00589   m_inactiveList->clear();
    00590   m_activeList->clear();
    00591   m_insertAction->setEnabled(false);
    00592   m_removeAction->setEnabled(false);
    00593   m_upAction->setEnabled(false);
    00594   m_downAction->setEnabled(false);
    00595
    00596   // store the names of our active actions
    00597   QMap<QString, bool> active_list;
    00598
    00599   // see if our current action is in this toolbar
    00600   QDomElement it = elem.lastChild().toElement();
    00601   for( ; !it.isNull(); it = it.previousSibling().toElement() )
    00602   {
    00603     if (it.tagName() == tagSeparator)
    00604     {
    00605       ToolbarItem *act = new ToolbarItem(m_activeList, tagSeparator, sep_name.arg(sep_num++), QString::null);
    00606       act->setText(1, "-----");
    00607       it.setAttribute( attrName, act->internalName() );
    00608       continue;
    00609     }
    00610
    00611     if (it.tagName() == tagMerge)
    00612     {
    00613       // Merge can be named or not - use the name if there is one
    00614       QString name = it.attribute( attrName );
    00615       ToolbarItem *act = new ToolbarItem(m_activeList, tagMerge, name, i18n("This element will be replaced with all the elements of an embedded component."));
    00616       if ( name.isEmpty() )
    00617           act->setText(1, i18n("<Merge>"));
    00618       else
    00619           act->setText(1, i18n("<Merge %1>").arg(name));
    00620       continue;
    00621     }
    00622
    00623     if (it.tagName() == tagActionList)
    00624     {
    00625       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.") );
    00626       act->setText(1, i18n("ActionList: %1").arg(it.attribute(attrName)));
    00627       continue;
    00628     }
    00629
    00630     // iterate through all of our actions
    00631     for (unsigned int i = 0;  i < d->m_actionList.count(); i++)
    00632     {
    00633       KAction *action = d->m_actionList[i];
    00634
    00635       // do we have a match?
    00636       if (it.attribute( attrName ) == action->name())
    00637       {
    00638         // we have a match!
    00639         ToolbarItem *act = new ToolbarItem(m_activeList, it.tagName(), action->name(), action->statusText());
    00640         act->setText(1, action->plainText());
    00641         if (action->hasIcon())
    00642           act->setPixmap(0, BarIcon(action->icon(), 16));
    00643
    00644         active_list.insert(action->name(), true);
    00645         break;
    00646       }
    00647     }
    00648   }
    00649
    00650   // go through the rest of the collection
    00651   for (int i = d->m_actionList.count() - 1; i > -1; --i)
    00652   {
    00653     KAction *action = d->m_actionList[i];
    00654
    00655     // skip our active ones
    00656     if (active_list.contains(action->name()))
    00657       continue;
    00658
    00659     // insert this into the inactive list
    00660     // for now, only deal with buttons with icons.. later, we'll need
    00661     // to look into actions a LOT more carefully
    00662     // Hmm, we also accept non-basic-KActions that have no icon
    00663     // (e.g. konqueror's location bar)
    00664     if ( action->icon().isEmpty() && action->isA("KAction") )
    00665       continue;
    00666
    00667     ToolbarItem *act = new ToolbarItem(m_inactiveList, tagActionList, action->name(), action->statusText());
    00668     act->setText(1, action->plainText());
    00669     if (!action->icon().isEmpty())
    00670         act->setPixmap(0, BarIcon(action->icon(), 16));
    00671   }
    00672
    00673   // finally, add a default separator to the inactive list
    00674   ToolbarItem *act = new ToolbarItem(m_inactiveList, tagSeparator, sep_name.arg(sep_num++), QString::null);
    00675   act->setText(1, "-----");
    00676 }
    00677
    00678 KActionCollection *KEditToolbarWidget::actionCollection() const
    00679 {
    00680   return d->m_collection;
    00681 }
    00682
    00683 void KEditToolbarWidget::slotToolbarSelected(const QString& _text)
    00684 {
    00685   static const QString &attrName = KGlobal::staticQString( "name" );
    00686   static const QString &tagText = KGlobal::staticQString( "text" );
    00687   static const QString &tagText2 = KGlobal::staticQString( "Text" );
    00688
    00689   // iterate through everything
    00690   XmlDataList::Iterator xit = d->m_xmlFiles.begin();
    00691   for ( ; xit != d->m_xmlFiles.end(); ++xit)
    00692   {
    00693     // each xml file may have any number of toolbars
    00694     ToolbarList::Iterator it = (*xit).m_barList.begin();
    00695     for ( ; it != (*xit).m_barList.end(); ++it)
    00696     {
    00697       QString name;
    00698       QCString txt( (*it).namedItem( tagText ).toElement().text().utf8() );
    00699       if ( txt.isEmpty() )
    00700           txt = (*it).namedItem( tagText2 ).toElement().text().utf8();
    00701       if ( txt.isEmpty() )
    00702           name = (*it).attribute( attrName );
    00703       else
    00704           name = i18n( txt );
    00705
    00706       // the name of the toolbar might depend on whether or not
    00707       // it is in kparts
    00708       if ( ( (*xit).m_type == XmlData::Shell ) ||
    00709            ( (*xit).m_type == XmlData::Part ) )
    00710       {
    00711         QString doc_name((*xit).m_document.documentElement().attribute( attrName ));
    00712         name += " <" + doc_name + ">";
    00713       }
    00714
    00715       // is this our toolbar?
    00716       if ( name == _text )
    00717       {
    00718         // save our current settings
    00719         d->m_currentXmlData     = (*xit);
    00720         d->m_currentToolbarElem = (*it);
    00721
    00722         // load in our values
    00723         loadActionList(d->m_currentToolbarElem);
    00724
    00725         if ((*xit).m_type == XmlData::Part || (*xit).m_type == XmlData::Shell)
    00726           setXML(KXMLGUIFactory::documentToXML((*xit).m_document.toDocument()));
    00727         return;
    00728       }
    00729     }
    00730   }
    00731 }
    00732
    00733 void KEditToolbarWidget::slotInactiveSelected(QListViewItem *item)
    00734 {
    00735   if (item)
    00736   {
    00737     m_insertAction->setEnabled(true);
    00738     QString statusText = static_cast<ToolbarItem *>(item)->statusText();
    00739     d->m_helpArea->setText( statusText );
    00740   }
    00741   else
    00742   {
    00743     m_insertAction->setEnabled(false);
    00744     d->m_helpArea->setText( QString::null );
    00745   }
    00746 }
    00747
    00748 void KEditToolbarWidget::slotActiveSelected(QListViewItem *item)
    00749 {
    00750   if (item)
    00751   {
    00752     m_removeAction->setEnabled(true);
    00753
    00754     if (item->itemAbove())
    00755       m_upAction->setEnabled(true);
    00756     else
    00757       m_upAction->setEnabled(false);
    00758
    00759     if (item->itemBelow())
    00760       m_downAction->setEnabled(true);
    00761     else
    00762       m_downAction->setEnabled(false);
    00763     QString statusText = static_cast<ToolbarItem *>(item)->statusText();
    00764     d->m_helpArea->setText( statusText );
    00765   }
    00766   else
    00767   {
    00768     m_removeAction->setEnabled(false);
    00769     m_upAction->setEnabled(false);
    00770     m_downAction->setEnabled(false);
    00771     d->m_helpArea->setText( QString::null );
    00772   }
    00773 }
    00774
    00775 void KEditToolbarWidget::slotInsertButton()
    00776 {
    00777   static const QString &tagAction    = KGlobal::staticQString( "Action" );
    00778   static const QString &tagSeparator = KGlobal::staticQString( "Separator" );
    00779   static const QString &attrName     = KGlobal::staticQString( "name" );
    00780
    00781   // we're modified, so let this change
    00782   emit enableOk(true);
    00783
    00784   ToolbarItem *item = (ToolbarItem*)m_inactiveList->currentItem();
    00785
    00786   QDomElement new_item;
    00787   // let's handle the separator specially
    00788   if (item->text(1) == "-----")
    00789     new_item = domDocument().createElement(tagSeparator);
    00790   else
    00791     new_item = domDocument().createElement(tagAction);
    00792   new_item.setAttribute(attrName, item->internalName());
    00793
    00794   if (m_activeList->currentItem())
    00795   {
    00796     // we have a selected item in the active list.. so let's try
    00797     // our best to add our new item right after the selected one
    00798     ToolbarItem *act_item = (ToolbarItem*)m_activeList->currentItem();
    00799     QDomElement elem = d->m_currentToolbarElem.firstChild().toElement();
    00800     for( ; !elem.isNull(); elem = elem.nextSibling().toElement())
    00801     {
    00802       if ((elem.attribute(attrName) == act_item->internalName()) &&
    00803           (elem.tagName() == act_item->internalTag()))
    00804       {
    00805         d->m_currentToolbarElem.insertAfter(new_item, elem);
    00806         break;
    00807       }
    00808     }
    00809   }
    00810   else
    00811   {
    00812     // just stick it at the end of this
    00813     d->m_currentToolbarElem.appendChild(new_item);
    00814   }
    00815
    00816   // and set this container as a noMerge
    00817   d->m_currentToolbarElem.setAttribute(QString::fromLatin1("noMerge"), "1");
    00818
    00819   // update the local doc
    00820   updateLocal(d->m_currentToolbarElem);
    00821
    00822   slotToolbarSelected( m_toolbarCombo->currentText() );
    00823 }
    00824
    00825 void KEditToolbarWidget::slotRemoveButton()
    00826 {
    00827   static const QString &attrName    = KGlobal::staticQString( "name" );
    00828   static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
    00829
    00830   // we're modified, so let this change
    00831   emit enableOk(true);
    00832
    00833   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
    00834
    00835   // now iterate through to find the child to nuke
    00836   QDomElement elem = d->m_currentToolbarElem.firstChild().toElement();
    00837   for( ; !elem.isNull(); elem = elem.nextSibling().toElement())
    00838   {
    00839     if ((elem.attribute(attrName) == item->internalName()) &&
    00840         (elem.tagName() == item->internalTag()))
    00841     {
    00842       // nuke myself!
    00843       d->m_currentToolbarElem.removeChild(elem);
    00844
    00845       // and set this container as a noMerge
    00846       d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
    00847
    00848       // update the local doc
    00849       updateLocal(d->m_currentToolbarElem);
    00850
    00851       break;
    00852     }
    00853   }
    00854
    00855   slotToolbarSelected( m_toolbarCombo->currentText() );
    00856 }
    00857
    00858 void KEditToolbarWidget::slotUpButton()
    00859 {
    00860   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
    00861
    00862   // make sure we're not the top item already
    00863   if (!item->itemAbove())
    00864     return;
    00865
    00866   static const QString &attrName    = KGlobal::staticQString( "name" );
    00867   static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
    00868
    00869   // we're modified, so let this change
    00870   emit enableOk(true);
    00871
    00872   // now iterate through to find where we are
    00873   QDomElement elem = d->m_currentToolbarElem.firstChild().toElement();
    00874   for( ; !elem.isNull(); elem = elem.nextSibling().toElement())
    00875   {
    00876     if ((elem.attribute(attrName) == item->internalName()) &&
    00877         (elem.tagName() == item->internalTag()))
    00878     {
    00879       // cool, i found me.  now clone myself
    00880       ToolbarItem *clone = new ToolbarItem(m_activeList,
    00881                                            item->itemAbove()->itemAbove(),
    00882                                            item->internalTag(),
    00883                                            item->internalName(),
    00884                                            item->statusText());
    00885       clone->setText(1, item->text(1));
    00886
    00887       // only set new pixmap if exists
    00888       if( item->pixmap(0) )
    00889         clone->setPixmap(0, *item->pixmap(0));
    00890
    00891       // remove the old me
    00892       m_activeList->takeItem(item);
    00893       delete item;
    00894
    00895       // select my clone
    00896       m_activeList->setSelected(clone, true);
    00897
    00898       // make clone visible
    00899       m_activeList->ensureItemVisible(clone);
    00900
    00901       // and do the real move in the DOM
    00902       d->m_currentToolbarElem.insertBefore(elem, elem.previousSibling());
    00903
    00904       // and set this container as a noMerge
    00905       d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
    00906
    00907       // update the local doc
    00908       updateLocal(d->m_currentToolbarElem);
    00909
    00910       break;
    00911     }
    00912   }
    00913 }
    00914
    00915 void KEditToolbarWidget::slotDownButton()
    00916 {
    00917   ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
    00918
    00919   // make sure we're not the bottom item already
    00920   if (!item->itemBelow())
    00921     return;
    00922
    00923   static const QString &attrName    = KGlobal::staticQString( "name" );
    00924   static const QString &attrNoMerge = KGlobal::staticQString( "noMerge" );
    00925
    00926   // we're modified, so let this change
    00927   emit enableOk(true);
    00928
    00929   // now iterate through to find where we are
    00930   QDomElement elem = d->m_currentToolbarElem.firstChild().toElement();
    00931   for( ; !elem.isNull(); elem = elem.nextSibling().toElement())
    00932   {
    00933     if ((elem.attribute(attrName) == item->internalName()) &&
    00934         (elem.tagName() == item->internalTag()))
    00935     {
    00936       // cool, i found me.  now clone myself
    00937       ToolbarItem *clone = new ToolbarItem(m_activeList,
    00938                                            item->itemBelow(),
    00939                                            item->internalTag(),
    00940                                            item->internalName(),
    00941                                            item->statusText());
    00942       clone->setText(1, item->text(1));
    00943
    00944       // only set new pixmap if exists
    00945       if( item->pixmap(0) )
    00946         clone->setPixmap(0, *item->pixmap(0));
    00947
    00948       // remove the old me
    00949       m_activeList->takeItem(item);
    00950       delete item;
    00951
    00952       // select my clone
    00953       m_activeList->setSelected(clone, true);
    00954
    00955       // make clone visible
    00956       m_activeList->ensureItemVisible(clone);
    00957
    00958       // and do the real move in the DOM
    00959       d->m_currentToolbarElem.insertAfter(elem, elem.nextSibling());
    00960
    00961       // and set this container as a noMerge
    00962       d->m_currentToolbarElem.setAttribute( attrNoMerge, "1");
    00963
    00964       // update the local doc
    00965       updateLocal(d->m_currentToolbarElem);
    00966
    00967       break;
    00968     }
    00969   }
    00970 }
    00971
    00972 void KEditToolbarWidget::updateLocal(QDomElement& elem)
    00973 {
    00974   static const QString &attrName = KGlobal::staticQString( "name" );
    00975
    00976   XmlDataList::Iterator xit = d->m_xmlFiles.begin();
    00977   for ( ; xit != d->m_xmlFiles.end(); ++xit)
    00978   {
    00979     if ( (*xit).m_type == XmlData::Merged )
    00980       continue;
    00981
    00982     if ( (*xit).m_type == XmlData::Shell ||
    00983          (*xit).m_type == XmlData::Part )
    00984     {
    00985       if ( d->m_currentXmlData.m_xmlFile == (*xit).m_xmlFile )
    00986       {
    00987         (*xit).m_isModified = true;
    00988         return;
    00989       }
    00990
    00991       continue;
    00992     }
    00993
    00994     (*xit).m_isModified = true;
    00995
    00996     ToolbarList::Iterator it = (*xit).m_barList.begin();
    00997     for ( ; it != (*xit).m_barList.end(); ++it)
    00998     {
    00999       QString name( (*it).attribute( attrName ) );;
    01000       QString tag( (*it).tagName() );
    01001       if ( (tag != elem.tagName()) || (name != elem.attribute(attrName)) )
    01002         continue;
    01003
    01004       QDomElement toolbar = (*xit).m_document.documentElement().toElement();
    01005       toolbar.replaceChild(elem, (*it));
    01006       return;
    01007     }
    01008
    01009     // just append it
    01010     QDomElement toolbar = (*xit).m_document.documentElement().toElement();
    01011     toolbar.appendChild(elem);
    01012   }
    01013 }
    01014
    01015 void KEditToolbar::virtual_hook( int id, void* data )
    01016 { KDialogBase::virtual_hook( id, data ); }
    01017
    01018 void KEditToolbarWidget::virtual_hook( int id, void* data )
    01019 { KXMLGUIClient::virtual_hook( id, data ); }
    01020
    01021 #include "kedittoolbar.moc"

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:56:48 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001