kdeui Library API Documentation

kedittoolbar.cpp

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