GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Menu.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2011-2018 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
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License 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 <https://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  {
42  std::string s (up.get_accelerator ());
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 nullptr;
74  }
75 
76  Menu::Menu (const graphics_object& go, QAction *action, Object *xparent)
77  : Object (go, action), m_parent (nullptr), m_separator (nullptr)
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 (nullptr, m_separator);
113  m_parent->insertAction (nullptr, action);
114 
115  int count = 0;
116 
117  foreach (QAction *a, m_parent->actions ())
118  if (! a->isSeparator ())
119  count++;
120 
121  up.get_property ("position").set
122  (octave_value (static_cast<double> (count)), true, false);
123  }
124  else
125  {
126 
127  int count = 0;
128  QAction *before = nullptr;
129 
130  foreach (QAction *a, m_parent->actions ())
131  {
132  if (! a->isSeparator ())
133  {
134  count++;
135  if (pos <= count)
136  {
137  before = a;
138  break;
139  }
140  }
141  }
142 
143  if (m_separator)
144  m_parent->insertAction (before, m_separator);
145  m_parent->insertAction (before, action);
146 
147  if (before)
149  else
150  up.get_property ("position").set
151  (octave_value (static_cast<double> (count+1)), true, false);
152  }
153  }
154 
155  connect (action, SIGNAL (triggered (bool)), SLOT (actionTriggered (void)));
156  }
157 
158  Menu::~Menu (void)
159  { }
160 
161  void
162  Menu::update (int pId)
163  {
164  uimenu::properties& up = properties<uimenu> ();
165  QAction *action = qWidget<QAction> ();
166 
167  switch (pId)
168  {
169  case uimenu::properties::ID_LABEL:
170  action->setText (Utils::fromStdString (up.get_label ()));
171  break;
172 
173  case uimenu::properties::ID_CHECKED:
174  if (up.is_checked ())
175  {
176  action->setCheckable (true);
177  action->setChecked (up.is_checked ());
178  }
179  else
180  {
181  action->setChecked (false);
182  action->setCheckable (false);
183  }
184  break;
185 
186  case uimenu::properties::ID_ENABLE:
187  action->setEnabled (up.is_enable ());
188  break;
189 
190  case uimenu::properties::ID_ACCELERATOR:
191  if (! action->menu ())
192  action->setShortcut (accelSequence (up));
193  break;
194 
195  case uimenu::properties::ID_SEPARATOR:
196  if (up.is_separator ())
197  {
198  if (! m_separator)
199  {
200  m_separator = new QAction (action);
201  m_separator->setSeparator (true);
202  m_separator->setVisible (up.is_visible ());
203  if (m_parent)
204  m_parent->insertAction (action, m_separator);
205  }
206  }
207  else
208  {
209  if (m_separator)
210  delete m_separator;
211  m_separator = nullptr;
212  }
213  break;
214 
215  case uimenu::properties::ID_VISIBLE:
216  action->setVisible (up.is_visible ());
217  if (m_separator)
218  m_separator->setVisible (up.is_visible ());
219  break;
220 
221  case uimenu::properties::ID_POSITION:
222  {
223  if (m_separator)
224  m_parent->removeAction (m_separator);
225 
226  m_parent->removeAction (action);
227 
228  int pos = static_cast<int> (up.get_position ());
229  QAction *before = nullptr;
230 
231  if (pos > 0)
232  {
233  int count = 0;
234 
235  foreach (QAction *a, m_parent->actions ())
236  {
237  if (! a->isSeparator ())
238  {
239  count++;
240  if (pos <= count)
241  {
242  before = a;
243  break;
244  }
245  }
246  }
247  }
248 
249  if (m_separator)
250  m_parent->insertAction (before, m_separator);
251 
252  m_parent->insertAction (before, action);
253 
255  }
256  break;
257 
258  default:
259  Object::update (pId);
260  break;
261  }
262  }
263 
264  QWidget*
265  Menu::menu (void)
266  {
267  QAction *action = qWidget<QAction> ();
268  QMenu *_menu = action->menu ();
269 
270  if (! _menu)
271  {
272  _menu = new QMenu (action->parentWidget ());
273  action->setMenu (_menu);
274  action->setShortcut (QKeySequence ());
275  connect (_menu, SIGNAL (aboutToShow (void)),
276  this, SLOT (actionHovered (void)));
277  }
278 
279  return _menu;
280  }
281 
282  void
284  {
285  QAction *action = qWidget<QAction> ();
286 
287  if (action->isCheckable ())
288  action->setChecked (! action->isChecked ());
289  gh_manager::post_callback (m_handle, "callback");
290  }
291 
292  void
294  {
295  gh_manager::post_callback (m_handle, "callback");
296  }
297 
298  void
300  {
301  if (m_parent)
302  {
303  double count = 1.0;
304 
305  foreach (QAction *a, m_parent->actions ())
306  {
307  if (! a->isSeparator ())
308  {
309  Object *aObj = Object::fromQObject (a);
310 
311  if (aObj)
312  {
313  graphics_object go = aObj->object ();
314 
315  // Probably overkill as a uimenu child can only be another
316  // uimenu object.
317  if (go.isa ("uimenu"))
318  {
319  uimenu::properties& up = Utils::properties<uimenu> (go);
320 
321  up.get_property ("position").set
322  (octave_value (count), true, false);
323  }
324  }
325 
326  count++;
327  }
328  }
329  }
330  }
331 
332 }
static void post_callback(const graphics_handle &h, const std::string &name, const octave_value &data=Matrix())
Definition: graphics.in.h:6214
#define CTRL(x)
Definition: kpty.cpp:143
~Menu(void)
Definition: Menu.cc:158
QString fromStdString(const std::string &s)
void actionHovered(void)
Definition: Menu.cc:293
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:162
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
s
Definition: file-io.cc:2729
bool isa(const std::string &go_name) const
Definition: graphics.in.h:2786
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:400
static Menu * create(const graphics_object &go)
Definition: Menu.cc:61
QWidget * menu(void)
Definition: Menu.cc:265
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.in.h:1995
graphics_handle m_handle
Definition: Object.h:115
static Object * fromQObject(QObject *obj)
Definition: Object.cc:176
void updateSiblingPositions(void)
Definition: Menu.cc:299
virtual QObject * qObject(void)
Definition: Object.h:71
graphics_object object(void) const
Definition: Object.cc:72
virtual void update(int pId)
Definition: Object.cc:132
void actionTriggered(void)
Definition: Menu.cc:283
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:888
virtual property get_property(const caseless_str &pname)