kdeui Library API Documentation

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