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