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