GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Menu.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2011-2017 Michael Goffioul
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <QAction>
28 #include <QMainWindow>
29 #include <QMenu>
30 #include <QMenuBar>
31 
32 #include "Figure.h"
33 #include "Menu.h"
34 #include "QtHandlesUtils.h"
35 
36 namespace QtHandles
37 {
38 
39  static QKeySequence
41  {
43 
44  if (! s.empty ())
45  {
46  char c = s[0];
47  int keyMod = Qt::CTRL;
48 
49  if (c >= 'A' && c <= 'Z')
50  keyMod |= Qt::SHIFT;
51  if (c >= 'a' && c <= 'z')
52  c -= ('a' - 'A');
53  if (c >= 'A' && c <= 'Z')
54  return QKeySequence (keyMod | static_cast<int> (c));
55  }
56 
57  return QKeySequence ();
58  }
59 
60  Menu*
62  {
63  Object* parent_obj = Object::parentObject (go);
64 
65  if (parent_obj)
66  {
67  QObject* qObj = parent_obj->qObject ();
68 
69  if (qObj)
70  return new Menu (go, new QAction (qObj), parent_obj);
71  }
72 
73  return 0;
74  }
75 
76  Menu::Menu (const graphics_object& go, QAction* action, Object* xparent)
77  : Object (go, action), m_parent (0), m_separator (0)
78  {
79  uimenu::properties& up = properties<uimenu> ();
80 
81  action->setText (Utils::fromStdString (up.get_label ()));
82 
83  if (up.is_checked ())
84  {
85  action->setCheckable (true);
86  action->setChecked (up.is_checked ());
87  }
88 
89  action->setEnabled (up.is_enable ());
90  action->setShortcut (accelSequence (up));
91  action->setVisible (up.is_visible ());
92 
93  if (up.is_separator ())
94  {
95  m_separator = new QAction (action);
96  m_separator->setSeparator (true);
97  m_separator->setVisible (up.is_visible ());
98  }
99 
100  MenuContainer* menuContainer = dynamic_cast<MenuContainer*> (xparent);
101 
102  if (menuContainer)
103  m_parent = menuContainer->menu ();
104 
105  if (m_parent)
106  {
107  int pos = static_cast<int> (up.get_position ());
108 
109  if (pos <= 0)
110  {
111  if (m_separator)
112  m_parent->insertAction (0, m_separator);
113  m_parent->insertAction (0, action);
114 
115  int count = 0;
116 
117  foreach (QAction* a, m_parent->actions ())
118  if (! a->isSeparator () && a->objectName () != "builtinMenu")
119  count++;
120  up.get_property ("position").set
121  (octave_value (static_cast<double> (count)), true, false);
122  }
123  else
124  {
125 
126  int count = 0;
127  QAction* before = 0;
128 
129  foreach (QAction* a, m_parent->actions ())
130  if (! a->isSeparator () && a->objectName () != "builtinMenu")
131  {
132  count++;
133  if (pos <= count)
134  {
135  before = a;
136  break;
137  }
138  }
139 
140  if (m_separator)
141  m_parent->insertAction (before, m_separator);
142  m_parent->insertAction (before, action);
143 
144  if (before)
146  else
147  up.get_property ("position").set
148  (octave_value (static_cast<double> (count+1)), true, false);
149  }
150  }
151 
152  connect (action, SIGNAL (triggered (bool)), SLOT (actionTriggered (void)));
153  }
154 
155  Menu::~Menu (void)
156  { }
157 
158  void
159  Menu::update (int pId)
160  {
161  uimenu::properties& up = properties<uimenu> ();
162  QAction* action = qWidget<QAction> ();
163 
164  switch (pId)
165  {
167  action->setText (Utils::fromStdString (up.get_label ()));
168  break;
169 
171  if (up.is_checked ())
172  {
173  action->setCheckable (true);
174  action->setChecked (up.is_checked ());
175  }
176  else
177  {
178  action->setChecked (false);
179  action->setCheckable (false);
180  }
181  break;
182 
184  action->setEnabled (up.is_enable ());
185  break;
186 
188  if (! action->menu ())
189  action->setShortcut (accelSequence (up));
190  break;
191 
193  if (up.is_separator ())
194  {
195  if (! m_separator)
196  {
197  m_separator = new QAction (action);
198  m_separator->setSeparator (true);
199  m_separator->setVisible (up.is_visible ());
200  if (m_parent)
201  m_parent->insertAction (action, m_separator);
202  }
203  }
204  else
205  {
206  if (m_separator)
207  delete m_separator;
208  m_separator = 0;
209  }
210  break;
211 
213  action->setVisible (up.is_visible ());
214  if (m_separator)
215  m_separator->setVisible (up.is_visible ());
216  break;
217 
219  {
220  if (m_separator)
221  m_parent->removeAction (m_separator);
222 
223  m_parent->removeAction (action);
224 
225  int pos = static_cast<int> (up.get_position ());
226  QAction* before = 0;
227 
228  if (pos > 0)
229  {
230  int count = 0;
231 
232  foreach (QAction* a, m_parent->actions ())
233  if (! a->isSeparator () && a->objectName () != "builtinMenu")
234  {
235  count++;
236  if (pos <= count)
237  {
238  before = a;
239  break;
240  }
241  }
242  }
243 
244  if (m_separator)
245  m_parent->insertAction (before, m_separator);
246 
247  m_parent->insertAction (before, action);
248 
250  }
251  break;
252 
253  default:
254  Object::update (pId);
255  break;
256  }
257  }
258 
259  QWidget*
260  Menu::menu (void)
261  {
262  QAction* action = qWidget<QAction> ();
263  QMenu* _menu = action->menu ();
264 
265  if (! _menu)
266  {
267  _menu = new QMenu (action->parentWidget ());
268  action->setMenu (_menu);
269  action->setShortcut (QKeySequence ());
270  connect (_menu, SIGNAL (aboutToShow (void)),
271  this, SLOT (actionHovered (void)));
272  }
273 
274  return _menu;
275  }
276 
277  void
279  {
280  QAction* action = qWidget<QAction> ();
281 
282  if (action->isCheckable ())
283  action->setChecked (! action->isChecked ());
284  gh_manager::post_callback (m_handle, "callback");
285  }
286 
287  void
289  {
290  gh_manager::post_callback (m_handle, "callback");
291  }
292 
293  void
295  {
296  if (m_parent)
297  {
298  double count = 1.0;
299 
300  foreach (QAction* a, m_parent->actions ())
301  {
302  if (! a->isSeparator () && a->objectName () != "builtinMenu")
303  {
304  Object* aObj = Object::fromQObject (a);
305 
306  if (aObj)
307  {
308  graphics_object go = aObj->object ();
309 
310  // Probably overkill as a uimenu child can only be another
311  // uimenu object.
312  if (go.isa ("uimenu"))
313  {
314  uimenu::properties& up = Utils::properties<uimenu> (go);
315 
316  up.get_property ("position").set
317  (octave_value (count), true, false);
318  }
319  }
320 
321  count++;
322  }
323  }
324  }
325  }
326 
327 }
static void post_callback(const graphics_handle &h, const std::string &name, const octave_value &data=Matrix())
Definition: graphics.h:13910
bool is_visible(void) const
Definition: graphics.h:2704
bool isa(const std::string &go_name) const
Definition: graphics.h:3286
#define CTRL(x)
Definition: kpty.cpp:143
~Menu(void)
Definition: Menu.cc:155
QString fromStdString(const std::string &s)
void actionHovered(void)
Definition: Menu.cc:288
static Object * parentObject(const graphics_object &go)
Definition: Object.cc:165
QAction * m_separator
Definition: Menu.h:62
void update(int pId)
Definition: Menu.cc:159
s
Definition: file-io.cc:2682
QWidget * m_parent
Definition: Menu.h:61
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
bool is_separator(void) const
Definition: graphics.h:11503
static Menu * create(const graphics_object &go)
Definition: Menu.cc:61
QWidget * menu(void)
Definition: Menu.cc:260
property get_property(const caseless_str &pname)
Menu(const graphics_object &go, QAction *action, Object *parent)
Definition: Menu.cc:76
bool set(const octave_value &val, bool do_run=true, bool do_notify_toolkit=true)
Definition: graphics.h:1883
graphics_handle m_handle
Definition: Object.h:100
bool is_enable(void) const
Definition: graphics.h:11491
static Object * fromQObject(QObject *obj)
Definition: Object.cc:176
void updateSiblingPositions(void)
Definition: Menu.cc:294
std::string get_accelerator(void) const
Definition: graphics.h:11483
std::string get_label(void) const
Definition: graphics.h:11499
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
Definition: lu.cc:138
virtual QObject * qObject(void)
Definition: Object.h:71
graphics_object object(void) const
Definition: Object.cc:72
bool is_checked(void) const
Definition: graphics.h:11488
double get_position(void) const
Definition: graphics.h:11501
virtual void update(int pId)
Definition: Object.cc:132
void actionTriggered(void)
Definition: Menu.cc:278
static QKeySequence accelSequence(const uimenu::properties &up)
Definition: Menu.cc:40
virtual QWidget * menu(void)=0
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854