00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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);
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 }
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
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
00294
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
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
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
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
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() ))
00490 {
00491 initKPart(factory);
00492
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() ))
00503 {
00504 initKPart(factory);
00505
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
00520
00521
00522
if (global)
00523 setXMLFile(
locate(
"config",
"ui/ui_standards.rc"));
00524
QString localXML = d->loadXMLFile(file);
00525 setXML(localXML,
true);
00526
00527
00528
QDomElement elem;
00529
00530
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
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
00552
#endif
00553
00554
00555 setupLayout();
00556 }
00557
00558
void KEditToolbarWidget::initKPart(
KXMLGUIFactory* factory)
00559 {
00560
00561
QDomElement elem;
00562
00563
setFactory( factory );
00564
actionCollection()->
setWidget(
this );
00565
00566
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
00589 }
00590
00591
#ifndef NDEBUG
00592
00593
#endif
00594
00595
00596 setupLayout();
00597 }
00598
00599 bool KEditToolbarWidget::save()
00600 {
00601
00602 XmlDataList::Iterator it = d->m_xmlFiles.begin();
00603
for ( ; it != d->m_xmlFiles.end(); ++it)
00604 {
00605
00606
if ( !((*it).m_isModified) )
00607
continue;
00608
00609
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
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
00625
00626
00627
KXMLGUIClient *client = clients.
last();
00628
while ( client )
00629 {
00630
00631
factory()->
removeClient( client );
00632 client = clients.
prev();
00633 }
00634
00635
KXMLGUIClient *firstClient = clients.
first();
00636
00637
00638
00639
QPtrListIterator<KXMLGUIClient> cit( clients );
00640
for( ; cit.
current(); ++cit)
00641 {
00642
KXMLGUIClient* client = cit.
current();
00643
00644
QString file( client->
xmlFile() );
00645
if ( !file.
isEmpty() )
00646 {
00647
00648 client->
setXMLGUIBuildDocument(
QDomDocument() );
00649
00650
00651
if ( client == firstClient )
00652 client->
setXMLFile(
locate(
"config",
"ui/ui_standards.rc"));
00653
00654
00655 client->
setXMLFile( file, client == firstClient );
00656 }
00657 }
00658
00659
00660
00661
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
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
00681
00682
00683
00684
00685
00686
00687
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(
"");
00697
int column2 = m_inactiveList->addColumn(
"");
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
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(
"");
00715 m_activeList->addColumn(
"");
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
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
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
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
00784
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
00819 m_toolbarCombo->
clear();
00820
00821
int defaultToolbarId = -1;
00822
int count = 0;
00823
00824 XmlDataList::Iterator xit = d->m_xmlFiles.begin();
00825
for ( ; xit != d->m_xmlFiles.end(); ++xit)
00826 {
00827
00828
if ( (*xit).m_type == XmlData::Local )
00829
continue;
00830
00831
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
00850 m_toolbarCombo->
setCurrentItem(defaultToolbarId);
00851 slotToolbarSelected(m_toolbarCombo->
currentText());
00852 }
00853
00854
00855
void KEditToolbarWidget::loadActionList(
QDomElement& elem)
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
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
00875
KActionCollection*
actionCollection = d->m_currentXmlData->m_actionCollection;
00876
00877
00878
QMap<QString, bool> active_list;
00879
00880
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
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
00918
00919
00920
for (
unsigned int i = 0; i < actionCollection->
count(); i++)
00921 {
00922
KAction *
action = actionCollection->
action( i );
00923
00924
00925
if (it.
attribute( attrName ) ==
action->name())
00926 {
00927
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
00934 act->setPixmap(0,
action->iconSet(KIcon::Toolbar).pixmap());
00935
00936 active_list.
insert(
action->name(),
true);
00937
break;
00938 }
00939 }
00940 }
00941
00942
00943
for (
int i = actionCollection->
count() - 1; i > -1; --i)
00944 {
00945
KAction *
action = actionCollection->
action( i );
00946
00947
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
00957 act->setPixmap(0,
action->iconSet(KIcon::Toolbar).pixmap());
00958 }
00959
00960
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
00975 XmlDataList::Iterator xit = d->m_xmlFiles.begin();
00976
for ( ; xit != d->m_xmlFiles.end(); ++xit)
00977 {
00978
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
00984
if ( name == _text )
00985 {
00986
00987 d->m_currentXmlData = & (*xit);
00988 d->m_currentToolbarElem = (*it);
00989
00990
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);
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
01060 removeActive(item);
01061 }
01062
01063 insertActive(item, after,
true);
01064 }
else if (list == m_inactiveList) {
01065
01066 removeActive(item);
01067 }
01068
01069
delete item; item = 0;
01070
01071
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
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
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
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
01124
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
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
01140 d->m_currentToolbarElem.setAttribute( attrNoMerge,
"1");
01141
01142
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
01154 emit
enableOk(
true);
01155
01156
01157
QDomElement elem = d->findElementForToolbarItem( item );
01158
if ( !elem.isNull() )
01159 {
01160
01161 d->m_currentToolbarElem.removeChild(elem);
01162
01163
01164 d->m_currentToolbarElem.setAttribute( attrNoMerge,
"1");
01165
01166
01167 updateLocal(d->m_currentToolbarElem);
01168 }
01169 }
01170
01171
void KEditToolbarWidget::slotUpButton()
01172 {
01173 ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
01174
01175
01176
if (!item->itemAbove())
01177
return;
01178
01179
static const QString &attrNoMerge =
KGlobal::staticQString(
"noMerge" );
01180
01181
01182 emit
enableOk(
true);
01183
01184
01185
QDomElement elem = d->findElementForToolbarItem( item );
01186
if ( !elem.isNull() )
01187 {
01188
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
01197
if( item->pixmap(0) )
01198 clone->setPixmap(0, *item->pixmap(0));
01199
01200
01201 m_activeList->takeItem(item);
01202
delete item;
01203
01204
01205 m_activeList->setSelected(clone,
true);
01206
01207
01208 m_activeList->ensureItemVisible(clone);
01209
01210
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
01217 d->m_currentToolbarElem.setAttribute( attrNoMerge,
"1");
01218
01219
01220 updateLocal(d->m_currentToolbarElem);
01221 }
01222 }
01223
01224
void KEditToolbarWidget::slotDownButton()
01225 {
01226 ToolbarItem *item = (ToolbarItem*)m_activeList->currentItem();
01227
01228
01229
if (!item->itemBelow())
01230
return;
01231
01232
static const QString &attrNoMerge =
KGlobal::staticQString(
"noMerge" );
01233
01234
01235 emit
enableOk(
true);
01236
01237
01238
QDomElement elem = d->findElementForToolbarItem( item );
01239
if ( !elem.isNull() )
01240 {
01241
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
01250
if( item->pixmap(0) )
01251 clone->setPixmap(0, *item->pixmap(0));
01252
01253
01254 m_activeList->takeItem(item);
01255
delete item;
01256
01257
01258 m_activeList->setSelected(clone,
true);
01259
01260
01261 m_activeList->ensureItemVisible(clone);
01262
01263
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
01270 d->m_currentToolbarElem.setAttribute( attrNoMerge,
"1");
01271
01272
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
01315
QDomElement toolbar = (*xit).m_document.documentElement().toElement();
01316 toolbar.appendChild(elem);
01317 }
01318 }
01319
01320
void KEditToolbarWidget::slotChangeIcon()
01321 {
01322
01323
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 );
01340 m_toolbarCombo->setEnabled(
false );
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
01369
QDomElement elem = KXMLGUIFactory::actionPropertiesElement( d->m_currentXmlData->m_document );
01370
01371
QDomElement act_elem = KXMLGUIFactory::findActionByName( elem, item->internalName(),
true );
01372 Q_ASSERT( !act_elem.isNull() );
01373 act_elem.
setAttribute(
"icon", icon );
01374
01375
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"