fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / kdeui / xmlgui / kmenumenuhandler_p.cpp
blob1f95d3e8a40d2067ce0885409d7d3af82a681342
1 /* This file is part of the KDE project
2 Copyright (C) 2006 Olivier Goffart <ogoffart@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "kmenumenuhandler_p.h"
22 #include "kxmlguibuilder.h"
23 #include "kxmlguiclient.h"
24 #include "kxmlguifactory.h"
25 #include "kmenu.h"
26 #include "kaction.h"
27 #include "kactioncollection.h"
28 #include <kdialog.h>
29 #include <kshortcutwidget.h>
30 #include <klocale.h>
31 #include <kdebug.h>
34 #include <QWidget>
35 #include <QDomDocument>
36 #include <QDomNode>
37 #include <kapplication.h>
38 #include <kmainwindow.h>
39 #include <ktoolbar.h>
40 #include <kselectaction.h>
43 namespace KDEPrivate {
45 KMenuMenuHandler::KMenuMenuHandler( KXMLGUIBuilder *builder )
46 : QObject() , m_builder(builder)
48 m_toolbarAction = new KSelectAction(i18n("Add to Toolbar"), this);
49 connect(m_toolbarAction , SIGNAL(triggered(int)) , this , SLOT(slotAddToToolBar(int)));
54 void KMenuMenuHandler::insertKMenu( KMenu *popup )
56 popup->contextMenu()->addAction( i18n("Configure Shortcut...") , this , SLOT( slotSetShortcut() ));
58 KMainWindow *window=qobject_cast<KMainWindow*>(m_builder->widget());
59 if(window)
61 popup->contextMenu()->addAction( m_toolbarAction );
62 connect(popup, SIGNAL(aboutToShowContextMenu(KMenu*,QAction*,QMenu*)) , this, SLOT(buildToolbarAction()));
68 void KMenuMenuHandler::buildToolbarAction()
70 KMainWindow *window=qobject_cast<KMainWindow*>(m_builder->widget());
71 if(!window)
72 return;
73 QStringList toolbarlist;
74 foreach(KToolBar *b , window->toolBars())
76 toolbarlist << (b->windowTitle().isEmpty() ? b->objectName() : b->windowTitle());
78 m_toolbarAction->setItems(toolbarlist);
81 static KActionCollection* findParentCollection(KXMLGUIFactory* factory, QAction* action)
83 foreach(KXMLGUIClient *client, factory->clients()) {
84 KActionCollection* collection = client->actionCollection();
85 // if the call to actions() is too slow, add KActionCollection::contains(QAction*).
86 if (collection->actions().contains(action)) {
87 return collection;
90 return 0;
93 void KMenuMenuHandler::slotSetShortcut()
95 KMenu * menu=KMenu::contextMenuFocus();
96 if(!menu)
97 return;
98 KAction *action= qobject_cast<KAction*>(menu->contextMenuFocusAction());
99 if(!action)
100 return;
102 KDialog dialog(m_builder->widget());
103 KShortcutWidget swidget(&dialog);
104 swidget.setShortcut(action->shortcut());
105 dialog.setMainWidget(&swidget);
106 KActionCollection* parentCollection = 0;
107 if(dynamic_cast<KXMLGUIClient*>(m_builder))
109 QList<KActionCollection*> checkCollections;
110 KXMLGUIFactory *factory=dynamic_cast<KXMLGUIClient*>(m_builder)->factory();
111 parentCollection = findParentCollection(factory, action);
112 foreach(KXMLGUIClient *client, factory->clients()) {
113 checkCollections += client->actionCollection();
115 swidget.setCheckActionCollections(checkCollections);
118 if(dialog.exec())
120 action->setShortcut(swidget.shortcut(), KAction::ActiveShortcut);
121 swidget.applyStealShortcut();
122 if(parentCollection)
123 parentCollection->writeSettings();
128 void KMenuMenuHandler::slotAddToToolBar(int tb)
130 KMainWindow *window=qobject_cast<KMainWindow*>(m_builder->widget());
131 if(!window)
132 return;
134 KMenu * menu=KMenu::contextMenuFocus();
135 if(!menu)
136 return;
137 QAction *action= qobject_cast<QAction*>(menu->contextMenuFocusAction());
138 if(!action)
139 return;
141 KXMLGUIFactory *factory = dynamic_cast<KXMLGUIClient*>(m_builder)->factory();
142 QString actionName = action->objectName(); // set by KActionCollection::addAction
143 KActionCollection *collection = 0;
144 if (factory) {
145 collection = findParentCollection(factory, action);
147 if(!collection) {
148 kWarning(296) << "Cannot find the action collection for action " << actionName;
149 return;
152 KToolBar *toolbar=window->toolBars()[tb];
153 toolbar->addAction(action);
155 const KXMLGUIClient* client = collection->parentGUIClient ();
156 QString xmlFile = client->localXMLFile();
157 QDomDocument document;
158 document.setContent( KXMLGUIFactory::readConfigFile( client->xmlFile(), client->componentData() ) );
159 QDomElement elem = document.documentElement().toElement();
161 static const QString &tagToolBar = KGlobal::staticQString( "ToolBar" );
162 static const QString &attrNoEdit = KGlobal::staticQString( "noEdit" );
163 static const QString &attrName = KGlobal::staticQString( "name" );
165 QDomElement toolbarElem;
166 QDomNode n=elem.firstChild();
167 for( ; !n.isNull(); n = n.nextSibling() )
169 QDomElement elem = n.toElement();
170 if (!elem.isNull() && elem.tagName() == tagToolBar && elem.attribute( attrName ) == toolbar->objectName() )
172 if(elem.attribute( attrNoEdit ) == "true")
174 kWarning(296) << "The toolbar is not editable";
175 return;
177 toolbarElem = elem;
178 break;
181 if(toolbarElem.isNull())
183 toolbarElem=document.createElement( tagToolBar );
184 toolbarElem.setAttribute( attrName, toolbar->objectName() );
185 elem.appendChild( toolbarElem );
188 KXMLGUIFactory::findActionByName(toolbarElem, actionName, true);
189 KXMLGUIFactory::saveConfigFile(document, xmlFile);
195 } //END namespace KDEPrivate
197 #include "kmenumenuhandler_p.moc"