1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /***************************************************************************
8 begin : Jan 2005
9 copyright : (C) 2005 by Craig Bradney
10 email : cbradney@zip.com.au
11 ***************************************************************************/
12
13 /***************************************************************************
14 * *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 ***************************************************************************/
21
22 #include <QDebug>
23 #include <QObject>
24 #include <QMetaObject>
25 #include <QMenu>
26 #include <QList>
27 #include "scmenu.h"
28 #include "scraction.h"
29 #include "util_debug.h"
30 #include "iconmanager.h"
31
32
ScrPopupMenu(QWidget * parent,const QString & pMenuName,const QString & pMenuText,const QString & parentName,bool pCheckable)33 ScrPopupMenu::ScrPopupMenu ( QWidget * parent, const QString& pMenuName, const QString& pMenuText, const QString& parentName, bool pCheckable ) : QObject(parent)
34 {
35 parentMenuName=parentName;
36 parentMenuID=-1;
37 menuText=pMenuText;
38 menuName=pMenuName;
39 menuBarID=-1;
40 menuItemList.clear();
41 localPopupMenu=new QMenu(parent);//, name);
42 // localPopupMenu->setCheckable(pCheckable);
43 enabled=true;
44 checkable = pCheckable;
45 }
46
~ScrPopupMenu()47 ScrPopupMenu::~ScrPopupMenu()
48 {
49 delete localPopupMenu;
50 }
51
getMenuText()52 QString ScrPopupMenu::getMenuText()
53 {
54 return menuText;
55 }
56
setText(const QString & pMenuText)57 void ScrPopupMenu::setText(const QString& pMenuText)
58 {
59 menuText=pMenuText;
60 localPopupMenu->menuAction()->setText(menuText);
61 }
62
getMenuIcon()63 QIcon ScrPopupMenu::getMenuIcon()
64 {
65 return menuIcon;
66 }
67
setMenuIcon(const QIcon & pMenuIcon)68 void ScrPopupMenu::setMenuIcon(const QIcon& pMenuIcon)
69 {
70 menuIcon=pMenuIcon;
71 }
72
getMenuName()73 QString ScrPopupMenu::getMenuName()
74 {
75 return menuName;
76 }
77
getParentMenuName()78 QString ScrPopupMenu::getParentMenuName()
79 {
80 return parentMenuName;
81 }
82
83 // void ScrPopupMenu::setMenuBarID(int id)
84 // {
85 // menuBarID=id;
86 // }
87 //
88 // int ScrPopupMenu::getMenuBarID()
89 // {
90 // return menuBarID;
91 // }
92
getLocalPopupMenu()93 QMenu *ScrPopupMenu::getLocalPopupMenu()
94 {
95 return localPopupMenu;
96 }
97
hasSubMenu(ScrPopupMenu * subMenu)98 bool ScrPopupMenu::hasSubMenu(ScrPopupMenu* subMenu)
99 {
100 return menuItemList.contains(QPointer<QObject>(subMenu));
101 }
102
103 // void ScrPopupMenu::setParentMenuID(int id)
104 // {
105 // parentMenuID=id;
106 // }
107 //
108 //
109 // const int ScrPopupMenu::getParentMenuID()
110 // {
111 // return parentMenuID;
112 // }
113
insertSubMenu(ScrPopupMenu * newSubMenu)114 bool ScrPopupMenu::insertSubMenu(ScrPopupMenu* newSubMenu)
115 {
116 if (newSubMenu)
117 {
118 menuItemList.append(newSubMenu);
119 // localPopupMenu->insertItem(newSubMenu->getMenuIcon(), newSubMenu->getMenuText(), newSubMenu->getLocalPopupMenu());
120 QAction *m=localPopupMenu->addMenu(newSubMenu->getLocalPopupMenu());
121 if (m)
122 m->setText(newSubMenu->getMenuText());
123 return true;
124 }
125 return false;
126 }
127
removeSubMenu(ScrPopupMenu * subMenu)128 bool ScrPopupMenu::removeSubMenu(ScrPopupMenu* subMenu)
129 {
130 if (menuItemList.removeAll(subMenu))
131 {
132 repopulateLocalMenu();
133 return true;
134 }
135 return false;
136 }
137
insertMenuItem(ScrAction * newMenuAction)138 bool ScrPopupMenu::insertMenuItem(ScrAction *newMenuAction)
139 {
140 if (newMenuAction)
141 {
142
143 #ifdef Q_OS_MAC
144 bool menuListHasNoIcons = true;
145 // look for ScrAction or ScrPopupMenu from the end of the list
146 // QList< QPointer<QObject> >::Iterator it = menuItemList.end();
147 int s=menuItemList.size()-1;
148 for (int i=s; i>=0; --i) {
149 QObject* menuItem = menuItemList[i];
150 QString menuItemListClassName = menuItemList[i]->metaObject()->className();
151 if (menuItemListClassName == "ScrAction")
152 {
153 ScrAction * act = qobject_cast<ScrAction *>(menuItem);
154 if (act!=nullptr)
155 menuListHasNoIcons = act->icon().isNull();
156 break;
157 }
158 if (menuItemListClassName == "ScrPopupMenu")
159 {
160 ScrPopupMenu * men = qobject_cast<ScrPopupMenu *>(menuItem);
161 if (men!=nullptr)
162 menuListHasNoIcons = men->getMenuIcon().isNull();
163 break;
164 }
165 }
166 if (newMenuAction->icon().isNull() && ! menuListHasNoIcons)
167 newMenuAction->setIcon(IconManager::instance().loadIcon("noicon.png"));
168 #endif
169
170 menuItemList.append(newMenuAction);
171 localPopupMenu->addAction(newMenuAction);
172 return true;
173 }
174 return false;
175 }
176
177 /* Qt4
178 bool ScrPopupMenu::insertMenuItem(QWidget *widget)
179 {
180 if (widget)
181 {
182 ScrAction *widgetAction = new ScrAction( nullptr, "widget_action" );
183 menuItemList.append(widgetAction);
184 localPopupMenu->insertItem(widget);
185 return true;
186 }
187 else
188 return false;
189 }
190 */
191
insertMenuItemAfter(ScrAction * newMenuAction,ScrAction * afterMenuAction)192 bool ScrPopupMenu::insertMenuItemAfter(ScrAction *newMenuAction, ScrAction *afterMenuAction)
193 {
194 //Allow duplicate menu items ???
195 //if (menuItemList.findRef(newMenuAction)!=-1)
196 // return false;
197
198 #ifdef Q_OS_MAC
199 if (newMenuAction && afterMenuAction)
200 if (newMenuAction->icon().isNull() && ! (afterMenuAction->icon().isNull()))
201 newMenuAction->setIcon(IconManager::instance().loadIcon("noicon.png"));
202 #endif
203
204 int pos=menuItemList.indexOf(QPointer<QObject>(afterMenuAction));
205 menuItemList.insert(++pos, QPointer<QObject>(newMenuAction));
206 /*
207 if (index==-1)
208 return false;
209 int newIndex=++index;
210 bool insSuccess=menuItemList.insert(newIndex, newMenuAction);
211
212 if (!insSuccess)
213 return false;
214 */
215 return repopulateLocalMenu();
216 }
217
removeMenuItem(ScrAction * menuAction)218 bool ScrPopupMenu::removeMenuItem(ScrAction *menuAction)
219 {
220 if (menuItemList.removeAll(menuAction))
221 {
222 repopulateLocalMenu();
223 return true;
224 }
225 return false;
226 }
227 /*
228 bool ScrPopupMenu::insertMenuItemAfter(ScrAction *newMenuAction, const QString afterMenuName)
229 {
230 bool retVal=true;
231 bool found=false;
232 QPtrListIterator<QObject> menuItemListIt(menuItemList);
233 QObject *object;
234 while ( (object = menuItemListIt.current()) != 0 )
235 {
236 QString menuItemListClassName=object->className();
237 int index=-1;
238 //index=menuItemListIt.at();
239 if (index=-1)
240 {
241 retVal=false;
242 break;
243 }
244 if (menuItemListClassName=="ScrAction")
245 {
246 qDebug("ScrAction found");
247 if(QString(object->name())==QString("separator_action"))
248 bool blah=true;//localPopupMenu->insertSeparator();
249 else
250 {
251 //Grab the action from the list, break and call the other after insert function
252
253 int newIndex=++index;
254 bool insSuccess=menuItemList.insert(newIndex, newMenuAction);
255 if (!insSuccess)
256 return false;
257
258 }
259 }
260 }
261 if (!found)
262 return false;
263 if (retVal==false)
264 return false;
265
266 return repopulateLocalMenu();
267 }
268 */
269
270 //CB TODO Does NOT handle rebuilding with widgets
repopulateLocalMenu()271 bool ScrPopupMenu::repopulateLocalMenu()
272 {
273 localPopupMenu->clear();
274 QList< QPointer<QObject> >::Iterator menuItemListIt = menuItemList.begin();
275 while (menuItemListIt!=menuItemList.end())
276 {
277 QObject *listObj=(*menuItemListIt);
278 if (listObj==nullptr)
279 {
280 QList< QPointer<QObject> >::Iterator menuItemListItToDelete = menuItemListIt;
281 ++menuItemListIt;
282 menuItemList.removeAll(*menuItemListItToDelete);
283 continue;
284 }
285
286 QString menuItemListClassName=listObj->metaObject()->className();
287 if (menuItemListClassName=="ScrAction")
288 {
289 ScrAction * act = qobject_cast<ScrAction *>(listObj);
290 if (act!=nullptr)
291 localPopupMenu->addAction(act);
292 }
293 else
294 {
295 if (menuItemListClassName=="ScrPopupMenu")
296 {
297 ScrPopupMenu * men = qobject_cast<ScrPopupMenu *>(listObj);
298 if (men!=nullptr)
299 {
300 //qDebug()<<men->localPopupMenu->title()<<men->localPopupMenu->;
301 // localPopupMenu->insertItem(men->getMenuIcon(), men->getMenuText(), men->getLocalPopupMenu());
302 QAction *m=localPopupMenu->addMenu(men->getLocalPopupMenu());
303 if (m)
304 m->setText(men->getMenuText());
305 }
306 }
307 else
308 sDebug(QString("Alien found: %1").arg((*menuItemListIt)->metaObject()->className()));
309 }
310 ++menuItemListIt;
311 }
312 return true;
313 }
314
generateEntryList(QStringList * actNames)315 bool ScrPopupMenu::generateEntryList(QStringList *actNames)
316 {
317 QList< QPointer<QObject> >::Iterator menuItemListIt = menuItemList.begin();
318 while (menuItemListIt!=menuItemList.end())
319 {
320 QObject *listObj=(*menuItemListIt);
321 if (listObj==nullptr)
322 {
323 QList< QPointer<QObject> >::Iterator menuItemListItToDelete = menuItemListIt;
324 ++menuItemListIt;
325 menuItemList.removeAll(*menuItemListItToDelete);
326 continue;
327 }
328
329 QString menuItemListClassName=listObj->metaObject()->className();
330 if (menuItemListClassName=="ScrAction")
331 {
332 auto *sca=qobject_cast<ScrAction *>(listObj);
333 if (sca!=nullptr)
334 actNames->append(sca->objectName());
335 }
336 else
337 if (menuItemListClassName=="ScrPopupMenu")
338 {
339 auto *scp=qobject_cast<ScrPopupMenu *>(listObj);
340 if (scp!=nullptr)
341 scp->generateEntryList(actNames);
342 }
343 ++menuItemListIt;
344 }
345 return true;
346
347 }
348
clear()349 bool ScrPopupMenu::clear()
350 {
351 menuItemList.clear(); //CB TODO leaking separators here ?
352 localPopupMenu->clear();
353 return true;
354 }
355
insertMenuSeparator()356 bool ScrPopupMenu::insertMenuSeparator()
357 {
358 ScrAction *sepAction = new ScrAction( nullptr );
359 sepAction->setSeparator(true);
360 menuItemList.append(sepAction);
361 localPopupMenu->addSeparator();
362 return true;
363 }
364
setEnabled(bool menuEnabled)365 void ScrPopupMenu::setEnabled(bool menuEnabled)
366 {
367 enabled=menuEnabled;
368 localPopupMenu->setEnabled(enabled);
369 }
370
setParentMenuName(const QString & newParentMenuName)371 void ScrPopupMenu::setParentMenuName(const QString& newParentMenuName)
372 {
373 if (!parentMenuName.isEmpty())
374 parentMenuName=newParentMenuName;
375 }
376