GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
QtHandlesUtils.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 <QApplication>
28 #include <QKeyEvent>
29 #include <QMouseEvent>
30 
31 #include <list>
32 
33 #include "ov.h"
34 #include "graphics.h"
35 
36 #include "Backend.h"
37 #include "Container.h"
38 #include "KeyMap.h"
39 #include "Object.h"
40 #include "QtHandlesUtils.h"
41 
42 #include "oct-string.h"
43 
44 namespace QtHandles
45 {
46 
47  namespace Utils
48  {
49 
50  QString
52  {
53  return QString::fromLocal8Bit (s.c_str ());
54  }
55 
57  toStdString (const QString& s)
58  {
59  return std::string (s.toLocal8Bit ().data ());
60  }
61 
62  QStringList
64  {
65  QStringList l;
66  octave_idx_type n = v.numel ();
67 
68  for (octave_idx_type i = 0; i < n; i++)
69  l << fromStdString (v[i]);
70 
71  return l;
72  }
73 
75  toStringVector (const QStringList& l)
76  {
77  string_vector v (l.length ());
78  int i = 0;
79 
80  foreach (const QString& s, l)
81  v[i++] = toStdString (s);
82 
83  return v;
84  }
85 
86  Cell toCellString (const QStringList& l)
87  {
88  QStringList tmp = l;
89 
90  // don't get any empty lines from end of the list
91  while ((tmp.length () > 0) && tmp.last ().isEmpty ())
92  {
93  tmp.removeLast ();
94  }
95  // no strings converts to a 1x1 cell with empty string
96  if (tmp.isEmpty ())
97  tmp += "";
98 
99  Cell v (toStringVector (tmp));
100  return v;
101  }
102 
103  template <typename T>
104  QFont
105  computeFont (const typename T::properties& props, int height)
106  {
107  QFont f (fromStdString (props.get_fontname ()));
108 
109  static std::map<std::string, QFont::Weight> weightMap;
110  static std::map<std::string, QFont::Style> angleMap;
111  static bool mapsInitialized = false;
112 
113  if (! mapsInitialized)
114  {
115  weightMap["normal"] = QFont::Normal;
116  weightMap["light"] = QFont::Light;
117  weightMap["demi"] = QFont::DemiBold;
118  weightMap["bold"] = QFont::Bold;
119 
120  angleMap["normal"] = QFont::StyleNormal;
121  angleMap["italic"] = QFont::StyleItalic;
122  angleMap["oblique"] = QFont::StyleOblique;
123 
124  mapsInitialized = true;
125  }
126 
127  f.setPointSizeF (props.get___fontsize_points__ (height));
128  f.setWeight (weightMap[props.get_fontweight ()]);
129  f.setStyle (angleMap[props.get_fontangle ()]);
130 
131  return f;
132  }
133 
134  template QFont computeFont<uicontrol> (const uicontrol::properties& props,
135  int height);
136 
137  template QFont computeFont<uipanel> (const uipanel::properties& props,
138  int height);
139 
141  props,
142  int height);
143  QColor
144  fromRgb (const Matrix& rgb)
145  {
146  QColor c;
147 
148  if (rgb.numel () == 3)
149  c.setRgbF (rgb(0), rgb(1), rgb(2));
150 
151  return c;
152  }
153 
154  Matrix
155  toRgb (const QColor& c)
156  {
157  Matrix rgb (1, 3);
158  double *rgbData = rgb.fortran_vec ();
159 
160  // qreal is a typedef for double except for ARM CPU architectures
161  // where it is a typedef for float (Bug #44970).
162  qreal tmp[3];
163  c.getRgbF (tmp, tmp+1, tmp+2);
164  rgbData[0] = tmp[0]; rgbData[1] = tmp[1]; rgbData[2] = tmp[2];
165 
166  return rgb;
167  }
168 
170  figureSelectionType (QMouseEvent *event, bool isDoubleClick)
171  {
172  if (isDoubleClick)
173  return "open";
174  else
175  {
176  Qt::MouseButtons buttons = event->buttons ();
177  Qt::KeyboardModifiers mods = event->modifiers ();
178 
179  if (mods == Qt::NoModifier)
180  {
181  if (buttons == Qt::LeftButton)
182  return "normal";
183  else if (buttons == Qt::RightButton)
184  return "alt";
185 #if defined (Q_WS_WIN)
186  else if (buttons == (Qt::LeftButton | Qt::RightButton))
187  return "extend";
188 #elif defined (Q_WS_X11)
189  else if (buttons == Qt::MidButton)
190  return "extend";
191 #endif
192  }
193  else if (buttons == Qt::LeftButton)
194  {
195  if (mods == Qt::ShiftModifier)
196  return "extend";
197  else if (mods == Qt::ControlModifier)
198  return "alt";
199  }
200  }
201 
202  return "normal";
203  }
204 
205  /*
206  Two figureCurrentPoint() routines are required:
207  1) Used for QMouseEvents where cursor position data is in callback from Qt.
208  2) Used for QKeyEvents where cursor position must be determined.
209  */
210  Matrix
211  figureCurrentPoint (const graphics_object& fig, QMouseEvent *event)
212  {
213  Object *tkFig = Backend::toolkitObject (fig);
214 
215  if (tkFig)
216  {
217  Container *c = tkFig->innerContainer ();
218 
219  if (c)
220  {
221  QPoint qp = c->mapFromGlobal (event->globalPos ());
222 
223  return tkFig->properties<figure> ().map_from_boundingbox (qp.x (),
224  qp.y ());
225  }
226  }
227 
228  return Matrix (1, 2, 0.0);
229  }
230 
231  Matrix
233  {
234  Object *tkFig = Backend::toolkitObject (fig);
235 
236  if (tkFig)
237  {
238  Container *c = tkFig->innerContainer ();
239 
240  if (c)
241  {
242  // FIXME: QCursor::pos() may give inaccurate results with
243  // asynchronous window systems like X11 over ssh.
244  QPoint qp = c->mapFromGlobal (QCursor::pos ());
245 
246  return tkFig->properties<figure> ().map_from_boundingbox (qp.x (),
247  qp.y ());
248  }
249  }
250 
251  return Matrix (1, 2, 0.0);
252  }
253 
254  Qt::Alignment
255  fromHVAlign (const std::string& halign, const std::string& valign)
256  {
257  Qt::Alignment flags;
258 
259  if (octave::string::strcmpi (halign, "left"))
260  flags |= Qt::AlignLeft;
261  else if (octave::string::strcmpi (halign, "center"))
262  flags |= Qt::AlignHCenter;
263  else if (octave::string::strcmpi (halign, "right"))
264  flags |= Qt::AlignRight;
265  else
266  flags |= Qt::AlignLeft;
267 
268  if (octave::string::strcmpi (valign, "middle"))
269  flags |= Qt::AlignVCenter;
270  else if (octave::string::strcmpi (valign, "top"))
271  flags |= Qt::AlignTop;
272  else if (octave::string::strcmpi (valign, "bottom"))
273  flags |= Qt::AlignBottom;
274  else
275  flags |= Qt::AlignVCenter;
276 
277  return flags;
278  }
279 
280  QImage
281  makeImageFromCData (const octave_value& v, int width, int height)
282  {
283  dim_vector dv (v.dims ());
284 
285  if (dv.ndims () == 3 && dv(2) == 3)
286  {
287  int w = qMin (dv(1), static_cast<octave_idx_type> (width));
288  int h = qMin (dv(0), static_cast<octave_idx_type> (height));
289 
290  int x_off = (w < width ? (width - w) / 2 : 0);
291  int y_off = (h < height ? (height - h) / 2 : 0);
292 
293  QImage img (width, height, QImage::Format_ARGB32);
294  img.fill (qRgba (0, 0, 0, 0));
295 
296  if (v.is_uint8_type ())
297  {
299 
300  for (int i = 0; i < w; i++)
301  for (int j = 0; j < h; j++)
302  {
303  int r = d(j, i, 0);
304  int g = d(j, i, 1);
305  int b = d(j, i, 2);
306  int a = 255;
307 
308  img.setPixel (x_off + i, y_off + j, qRgba (r, g, b, a));
309  }
310  }
311  else if (v.is_single_type ())
312  {
314 
315  for (int i = 0; i < w; i++)
316  for (int j = 0; j < h; j++)
317  {
318  float r = f(j, i, 0);
319  float g = f(j, i, 1);
320  float b = f(j, i, 2);
321  int a = (octave::math::isnan (r) || octave::math::isnan (g)
322  || octave::math::isnan (b) ? 0 : 255);
323 
324  img.setPixel (x_off + i, y_off + j,
325  qRgba (octave::math::round (r * 255),
326  octave::math::round (g * 255),
327  octave::math::round (b * 255),
328  a));
329  }
330  }
331  else if (v.isreal ())
332  {
333  NDArray d = v.array_value ();
334 
335  for (int i = 0; i < w; i++)
336  for (int j = 0; j < h; j++)
337  {
338  double r = d(j, i, 0);
339  double g = d(j, i, 1);
340  double b = d(j, i, 2);
341  int a = (octave::math::isnan (r) || octave::math::isnan (g)
342  || octave::math::isnan (b) ? 0 : 255);
343 
344  img.setPixel (x_off + i, y_off + j,
345  qRgba (octave::math::round (r * 255),
346  octave::math::round (g * 255),
347  octave::math::round (b * 255),
348  a));
349  }
350  }
351 
352  return img;
353  }
354 
355  return QImage ();
356  }
357 
359  makeKeyEventStruct (QKeyEvent *event)
360  {
362 
363  retval.setfield ("Key", KeyMap::qKeyToKeyString (event->key ()));
364  retval.setfield ("Character", toStdString (event->text ()));
365 
366  std::list<std::string> modList;
367  Qt::KeyboardModifiers mods = event->modifiers ();
368 
369  if (mods & Qt::ShiftModifier)
370  modList.push_back ("shift");
371  if (mods & Qt::ControlModifier)
372 #if defined (Q_OS_MAC)
373  modList.push_back ("command");
374 #else
375  modList.push_back ("control");
376 #endif
377  if (mods & Qt::AltModifier)
378  modList.push_back ("alt");
379 #if defined (Q_OS_MAC)
380  if (mods & Qt::MetaModifier)
381  modList.push_back ("control");
382 #endif
383 
384  retval.setfield ("Modifier", Cell (modList));
385 
386  return retval;
387  }
388 
389  }
390 
391 }
static int qp(const Matrix &H, const ColumnVector &q, const Matrix &Aeq, const ColumnVector &beq, const Matrix &Ain, const ColumnVector &bin, int maxit, ColumnVector &x, ColumnVector &lambda, int &iter)
Definition: __qp__.cc:89
Definition: Cell.h:37
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
Qt::Alignment fromHVAlign(const std::string &halign, const std::string &valign)
const T * fortran_vec(void) const
Definition: Array.h:584
bool isnan(bool)
Definition: lo-mappers.h:187
QString fromStdString(const std::string &s)
QStringList fromStringVector(const string_vector &v)
virtual Container * innerContainer(void)=0
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
FloatNDArray float_array_value(bool frc_str_conv=false) const
Definition: ov.h:843
Matrix figureCurrentPoint(const graphics_object &fig, QMouseEvent *event)
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
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
template QFont computeFont< uicontrol >(const uicontrol::properties &props, int height)
QColor fromRgb(const Matrix &rgb)
std::string qKeyToKeyString(int key)
Definition: KeyMap.cc:39
double h
Definition: graphics.cc:11808
template QFont computeFont< uibuttongroup >(const uibuttongroup::properties &props, int height)
octave_scalar_map makeKeyEventStruct(QKeyEvent *event)
Matrix toRgb(const QColor &c)
std::complex< double > w(std::complex< double > z, double relerr=0)
bool is_single_type(void) const
Definition: ov.h:651
dim_vector dims(void) const
Definition: ov.h:469
double tmp
Definition: data.cc:6252
octave_value retval
Definition: data.cc:6246
QFont computeFont(const typename T::properties &props, int height)
template QFont computeFont< uipanel >(const uipanel::properties &props, int height)
QImage makeImageFromCData(const octave_value &v, int width, int height)
Definition: dMatrix.h:36
bool isreal(void) const
Definition: ov.h:703
static Object * toolkitObject(const graphics_object &go)
Definition: Backend.cc:212
bool strcmpi(const T &str_a, const T &str_b)
True if strings are the same, ignoring case.
Definition: oct-string.cc:129
std::string figureSelectionType(QMouseEvent *event, bool isDoubleClick)
b
Definition: cellfun.cc:400
Cell toCellString(const QStringList &l)
double round(double x)
Definition: lo-mappers.h:145
for i
Definition: data.cc:5264
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:295
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
std::string toStdString(const QString &s)
bool is_uint8_type(void) const
Definition: ov.h:675
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
dim_vector dv
Definition: sub2ind.cc:263
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:840
base_properties & properties(void)
Definition: Object.h:49
uint8NDArray uint8_array_value(void) const
Definition: ov.h:943
string_vector toStringVector(const QStringList &l)
T::properties & properties(graphics_object obj)