libyui-mga-qt  1.1.0
YMGAQMenuBar.cc
1 /*
2  Copyright 2020 by Angelo Naselli <anaselli at linux dot it>
3 
4  This library is free software; you can redistribute it and/or modify
5  it under the terms of the GNU Lesser General Public License as
6  published by the Free Software Foundation; either version 2.1 of the
7  License, or (at your option) version 3.0 of the License. This library
8  is distributed in the hope that it will be useful, but WITHOUT ANY
9  WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
11  License for more details. You should have received a copy of the GNU
12  Lesser General Public License along with this library; if not, write
13  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
14  Floor, Boston, MA 02110-1301 USA
15 */
16 
17 
18 /*-/
19 
20  File: YMGAQMenuBar.cc
21 
22  Author: Angelo Naselli <anaselli@linux.it>
23 
24 /-*/
25 
26 #include <QMenu>
27 #include <QMenuBar>
28 #include <QHBoxLayout>
29 #include <QAction>
30 #include <QFileInfo>
31 #define YUILogComponent "mga-qt-ui"
32 #include <yui/YUILog.h>
33 
34 #include <yui/qt/utf8.h>
35 
36 #include <yui/qt/YQUI.h>
37 #include <yui/YEvent.h>
38 #include <yui/qt/YQSignalBlocker.h>
39 #include <yui/YUIException.h>
40 #include <yui/YMenuItem.h>
41 
42 #include "YMGAQMenuBar.h"
43 #include <yui/qt/YQApplication.h>
44 #include <yui/mga/YMGAMenuItem.h>
45 
46 typedef std::map<YItem*, QObject*> MenuEntryMap;
47 typedef std::pair<YItem*, QObject*> MenuEntryPair;
48 
50 {
51  QMenuBar *menubar;
52  MenuEntryMap menu_entry;
53 };
54 
55 
56 class QItemAction : public QAction
57 {
58 
59 private:
60  YMenuItem *_yitem;
61 public:
62  QItemAction(YMenuItem *item, QObject *parent = nullptr ) :
63  QAction(item->label().c_str(), parent), _yitem(item)
64  {
65 
66  }
67 
68  virtual ~QItemAction() {}
69 
70  void selectedItem()
71  {
72  YQUI::ui()->sendEvent( new YMenuEvent( _yitem ) );
73  }
74 };
75 
76 YMGAQMenuBar::YMGAQMenuBar( YWidget * parent )
77  : QWidget( (QWidget *) parent->widgetRep() )
78  , YMGAMenuBar( parent ), d(new Private)
79 {
80  YUI_CHECK_NEW ( d );
81 
82  setWidgetRep ( this );
83 
84  QHBoxLayout* layout = new QHBoxLayout ( this );
85  layout->setSpacing ( 0 );
86  setLayout ( layout );
87 
88  layout->setMargin ( YQWidgetMargin );
89 
90  d->menubar = new QMenuBar ( this );
91  YUI_CHECK_NEW ( d->menubar );
92  layout->addWidget ( d->menubar );
93 }
94 
95 
97 {
98  delete d;
99 }
100 
101 void YMGAQMenuBar::addAction(QMenu* menu, YItem* yitem)
102 {
103  YMenuItem * item = dynamic_cast<YMenuItem *> ( yitem );
104  YUI_CHECK_PTR ( item );
105 
106  YMenuSeparator *separator = dynamic_cast<YMenuSeparator *>(yitem);
107  if (separator)
108  menu->addSeparator();
109  else
110  {
111  // TODO icon from item
112  QItemAction *action = new QItemAction(item, this);
113  if (item->hasIconName())
114  {
115  QString qtIcon = fromUTF8( yitem->iconName() );
116  QString icon_name = QFileInfo( qtIcon ).baseName();
117 
118  if ( QIcon::hasThemeIcon( icon_name ) )
119  {
120  action->setIcon( QIcon::fromTheme ( icon_name ) );
121  }
122  else
123  {
124  QPixmap pixmap( qtIcon );
125 
126  if ( !pixmap.isNull() )
127  action->setIcon( QIcon( pixmap ) );
128  }
129  action->setIconVisibleInMenu(true);
130  }
131  connect(action, &QAction::triggered, action, &QItemAction::selectedItem);
132  menu->addAction(action);
133 
134  YMGAMenuItem *menuItem = dynamic_cast<YMGAMenuItem *>(yitem);
135  if (menuItem)
136  {
137  action->setEnabled(menuItem->enabled());
138  d->menu_entry.insert(MenuEntryPair(yitem, action));
139  action->setVisible(!menuItem->hidden());
140  }
141  }
142 
143 }
144 
145 void YMGAQMenuBar::addSubMenu(QMenu* menu, YItem* yitem)
146 {
147  YMenuItem * item = dynamic_cast<YMenuItem *> ( yitem );
148  YUI_CHECK_PTR ( item );
149 
150  // TODO icon from item
151  QMenu *m=menu->addMenu(item->label().c_str());
152  if (item->hasChildren())
153  {
154  YMGAMenuItem *menuItem = dynamic_cast<YMGAMenuItem *>(yitem);
155  if (menuItem)
156  {
157  m->setEnabled(menuItem->enabled());
158  d->menu_entry.insert(MenuEntryPair(yitem, m));
159  m->menuAction()->setVisible(!menuItem->hidden());
160  }
161  for (YItemIterator miter = item->childrenBegin(); miter != item->childrenEnd(); miter++)
162  {
163  YMenuItem *m_item= dynamic_cast<YMenuItem *>(*miter);
164  if (m_item->hasChildren())
165  {
166  addSubMenu(menu, m_item);
167  }
168  else
169  {
170  addAction(m, m_item);
171  }
172  }
173  }
174 }
175 
176 
177 void YMGAQMenuBar::addItem(YItem* yitem)
178 {
179  YMenuItem * item = dynamic_cast<YMenuItem *> ( yitem );
180  YUI_CHECK_PTR ( item );
181 
182  // TODO icon from item
183  QMenu *menu = d->menubar->addMenu(item->label().c_str());
184 
185  if (item->hasChildren())
186  {
187  for (YItemIterator miter = item->childrenBegin(); miter != item->childrenEnd(); miter++)
188  {
189  YMenuItem *m_item= dynamic_cast<YMenuItem *>(*miter);
190  if (m_item->hasChildren())
191  {
192  addSubMenu(menu, m_item);
193  }
194  else
195  {
196  addAction(menu, m_item);
197  }
198  }
199  }
200 
201  YMGAMenuItem *menuItem = dynamic_cast<YMGAMenuItem *>(yitem);
202  if (menuItem)
203  {
204  menu->setEnabled(menuItem->enabled());
205  d->menu_entry.insert(MenuEntryPair(yitem, menu));
206  menu->menuAction()->setVisible(!menuItem->hidden());
207  }
208  YMGAMenuBar::addItem(yitem);
209  menu->update();
210 }
211 
213 {
214  // Arbitrary value.
215  // Use a MinSize widget to set a size that is useful for the application.
216 
217  return 20 + d->menubar->sizeHint().width();
218 }
219 
220 
222 {
223  // Arbitrary value.
224  // Use a MinSize widget to set a size that is useful for the application.
225  return 20 + d->menubar->sizeHint().height();
226 }
227 
228 
229 
230 void YMGAQMenuBar::setSize( int newWidth, int newHeight )
231 {
232  resize( newWidth, newHeight );
233 }
234 
235 void YMGAQMenuBar::enableItem(YItem* menu_item, bool enable)
236 {
237  YMGAMenuBar::enableItem(menu_item, enable);
238 
239  auto search = d->menu_entry.find( menu_item );
240  if (search != d->menu_entry.end())
241  {
242  QMenu * menu_entry = dynamic_cast<QMenu*>(search->second);
243  if (menu_entry)
244  menu_entry->setEnabled(enable);
245  else
246  {
247  QAction * menu_action = dynamic_cast<QAction*>(search->second);
248  if (menu_action)
249  menu_action->setEnabled(enable);
250  }
251  }
252  else
253  {
254  yuiError() << menu_item->label() << " not found" << std::endl;
255  }
256 }
257 
258 void YMGAQMenuBar::hideItem(YItem* menu_item, bool invisible)
259 {
260  YMGAMenuBar::hideItem(menu_item, invisible);
261 
262  auto search = d->menu_entry.find( menu_item );
263  if (search != d->menu_entry.end())
264  {
265  QMenu * menu_entry = dynamic_cast<QMenu*>(search->second);
266  if (menu_entry)
267  {
268  menu_entry->menuAction()->setVisible(!invisible);
269 
270 // resize( d->menubar->sizeHint() + QSize(20,20));
271 // update();
272 
273  }
274  else
275  {
276  QAction * menu_action = dynamic_cast<QAction*>(search->second);
277  if (menu_action)
278  menu_action->setVisible(!invisible);
279  }
280  }
281  else
282  {
283  yuiError() << menu_item->label() << " not found" << std::endl;
284  }
285 }
286 
288 {
289  d->menubar->clear();
290 // for (MenuEntryMap::iterator it=d->menu_entry.begin(); it!=d->menu_entry.end(); ++it)
291 // {
292 // QMenu * menu_entry = dynamic_cast<QMenu*>(it->second);
293 // if (menu_entry)
294 // {
295 // d->menubar->removeAction(menu_entry->menuAction());
296 // }
297 // else
298 // {
299 // QAction * menu_action = dynamic_cast<QAction*>(it->second);
300 // if (menu_action)
301 // d->menubar->removeAction(menu_action);
302 // }
303 // }
304 
305  d->menu_entry.clear();
306 
307  YSelectionWidget::deleteAllItems();
308 }
309 
310 
YMGAQMenuBar::~YMGAQMenuBar
virtual ~YMGAQMenuBar()
Destructor.
Definition: YMGAQMenuBar.cc:96
YMGAQMenuBar::enableItem
virtual void enableItem(YItem *menu_item, bool enable=true)
Enable YMGAMenuItem (menu name or menu entry) to enable/disable it into menubar or menu.
Definition: YMGAQMenuBar.cc:235
YMGAQMenuBar::addSubMenu
virtual void addSubMenu(QMenu *menu, YItem *item)
Add a submenu.
Definition: YMGAQMenuBar.cc:145
YMGAQMenuBar::setSize
virtual void setSize(int newWidth, int newHeight)
Set the new size of the widget.
Definition: YMGAQMenuBar.cc:230
YMGAQMenuBar::preferredHeight
virtual int preferredHeight()
Preferred height of the widget.
Definition: YMGAQMenuBar.cc:221
YMGAQMenuBar::preferredWidth
virtual int preferredWidth()
Preferred width of the widget.
Definition: YMGAQMenuBar.cc:212
YMGAQMenuBar::deleteAllItems
virtual void deleteAllItems()
Delete all items.
Definition: YMGAQMenuBar.cc:287
YMGAQMenuBar::addItem
virtual void addItem(YItem *item)
Add an YMenuItem first item represents the menu name, other sub items menu entries.
Definition: YMGAQMenuBar.cc:177
QItemAction
Definition: YMGAQMenuBar.cc:56
YMGAQMenuBar::addAction
virtual void addAction(QMenu *menu, YItem *item)
Add an action (a menu entry without submenus)
Definition: YMGAQMenuBar.cc:101
YMGAQMenuBar::YMGAQMenuBar
YMGAQMenuBar(YWidget *parent)
Constructor.
Definition: YMGAQMenuBar.cc:76
YMGAQMenuBar::hideItem
virtual void hideItem(YItem *menu_item, bool invisible=true)
Hide YMGAMenuItem (menu name or menu entry) to hide/show it into menubar or menu.
Definition: YMGAQMenuBar.cc:258
YMGAQMenuBar::Private
Definition: YMGAQMenuBar.cc:49