qtpropertybrowserutils.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Solutions component.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 ** * Redistributions of source code must retain the above copyright
15 ** notice, this list of conditions and the following disclaimer.
16 ** * Redistributions in binary form must reproduce the above copyright
17 ** notice, this list of conditions and the following disclaimer in
18 ** the documentation and/or other materials provided with the
19 ** distribution.
20 ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 ** of its contributors may be used to endorse or promote products derived
22 ** from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 
43 #include <QApplication>
44 #include <QPainter>
45 #include <QHBoxLayout>
46 #include <QMouseEvent>
47 #include <QCheckBox>
48 #include <QLineEdit>
49 #include <QMenu>
50 #include <QStyleOption>
51 
52 QT_BEGIN_NAMESPACE
53 
55 {
56  appendCursor(Qt::ArrowCursor, QCoreApplication::translate("QtCursorDatabase", "Arrow"),
57  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-arrow.png")));
58  appendCursor(Qt::UpArrowCursor, QCoreApplication::translate("QtCursorDatabase", "Up Arrow"),
59  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-uparrow.png")));
60  appendCursor(Qt::CrossCursor, QCoreApplication::translate("QtCursorDatabase", "Cross"),
61  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-cross.png")));
62  appendCursor(Qt::WaitCursor, QCoreApplication::translate("QtCursorDatabase", "Wait"),
63  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-wait.png")));
64  appendCursor(Qt::IBeamCursor, QCoreApplication::translate("QtCursorDatabase", "IBeam"),
65  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-ibeam.png")));
66  appendCursor(Qt::SizeVerCursor, QCoreApplication::translate("QtCursorDatabase", "Size Vertical"),
67  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizev.png")));
68  appendCursor(Qt::SizeHorCursor, QCoreApplication::translate("QtCursorDatabase", "Size Horizontal"),
69  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeh.png")));
70  appendCursor(Qt::SizeFDiagCursor, QCoreApplication::translate("QtCursorDatabase", "Size Backslash"),
71  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizef.png")));
72  appendCursor(Qt::SizeBDiagCursor, QCoreApplication::translate("QtCursorDatabase", "Size Slash"),
73  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeb.png")));
74  appendCursor(Qt::SizeAllCursor, QCoreApplication::translate("QtCursorDatabase", "Size All"),
75  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeall.png")));
76  appendCursor(Qt::BlankCursor, QCoreApplication::translate("QtCursorDatabase", "Blank"),
77  QIcon());
78  appendCursor(Qt::SplitVCursor, QCoreApplication::translate("QtCursorDatabase", "Split Vertical"),
79  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-vsplit.png")));
80  appendCursor(Qt::SplitHCursor, QCoreApplication::translate("QtCursorDatabase", "Split Horizontal"),
81  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-hsplit.png")));
82  appendCursor(Qt::PointingHandCursor, QCoreApplication::translate("QtCursorDatabase", "Pointing Hand"),
83  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-hand.png")));
84  appendCursor(Qt::ForbiddenCursor, QCoreApplication::translate("QtCursorDatabase", "Forbidden"),
85  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-forbidden.png")));
86  appendCursor(Qt::OpenHandCursor, QCoreApplication::translate("QtCursorDatabase", "Open Hand"),
87  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-openhand.png")));
88  appendCursor(Qt::ClosedHandCursor, QCoreApplication::translate("QtCursorDatabase", "Closed Hand"),
89  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-closedhand.png")));
90  appendCursor(Qt::WhatsThisCursor, QCoreApplication::translate("QtCursorDatabase", "What's This"),
91  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-whatsthis.png")));
92  appendCursor(Qt::BusyCursor, QCoreApplication::translate("QtCursorDatabase", "Busy"),
93  QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-busy.png")));
94 }
95 
97 {
98  m_cursorNames.clear();
99  m_cursorIcons.clear();
100  m_valueToCursorShape.clear();
101  m_cursorShapeToValue.clear();
102 }
103 
104 void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString& name, const QIcon& icon)
105 {
106  if (m_cursorShapeToValue.contains(shape))
107  {
108  return;
109  }
110 
111  const int value = m_cursorNames.count();
112  m_cursorNames.append(name);
113  m_cursorIcons.insert(value, icon);
114  m_valueToCursorShape.insert(value, shape);
115  m_cursorShapeToValue.insert(shape, value);
116 }
117 
119 {
120  return m_cursorNames;
121 }
122 
123 QMap<int, QIcon> QtCursorDatabase::cursorShapeIcons() const
124 {
125  return m_cursorIcons;
126 }
127 
128 QString QtCursorDatabase::cursorToShapeName(const QCursor& cursor) const
129 {
130  int val = cursorToValue(cursor);
131 
132  if (val >= 0)
133  {
134  return m_cursorNames.at(val);
135  }
136 
137  return QString();
138 }
139 
140 QIcon QtCursorDatabase::cursorToShapeIcon(const QCursor& cursor) const
141 {
142  int val = cursorToValue(cursor);
143  return m_cursorIcons.value(val);
144 }
145 
146 int QtCursorDatabase::cursorToValue(const QCursor& cursor) const
147 {
148 #ifndef QT_NO_CURSOR
149  Qt::CursorShape shape = cursor.shape();
150 
151  if (m_cursorShapeToValue.contains(shape))
152  {
153  return m_cursorShapeToValue[shape];
154  }
155 
156 #endif
157  return -1;
158 }
159 
160 #ifndef QT_NO_CURSOR
162 {
163  if (m_valueToCursorShape.contains(value))
164  {
165  return QCursor(m_valueToCursorShape[value]);
166  }
167 
168  return QCursor();
169 }
170 #endif
171 
173 {
174  QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
175  img.fill(0);
176 
177  QPainter painter(&img);
178  painter.setCompositionMode(QPainter::CompositionMode_Source);
179  painter.fillRect(0, 0, img.width(), img.height(), b);
180  QColor color = b.color();
181 
182  if (color.alpha() != 255) // indicate alpha by an inset
183  {
184  QBrush opaqueBrush = b;
185  color.setAlpha(255);
186  opaqueBrush.setColor(color);
187  painter.fillRect(img.width() / 4, img.height() / 4,
188  img.width() / 2, img.height() / 2, opaqueBrush);
189  }
190 
191  painter.end();
192  return QPixmap::fromImage(img);
193 }
194 
196 {
197  return QIcon(brushValuePixmap(b));
198 }
199 
201 {
202  return QCoreApplication::translate("QtPropertyBrowserUtils", "[%1, %2, %3] (%4)")
203  .arg(c.red()).arg(c.green()).arg(c.blue()).arg(c.alpha());
204 }
205 
206 QPixmap QtPropertyBrowserUtils::fontValuePixmap(const QFont& font)
207 {
208  QFont f = font;
209  QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
210  img.fill(0);
211  QPainter p(&img);
212  p.setRenderHint(QPainter::TextAntialiasing, true);
213  p.setRenderHint(QPainter::Antialiasing, true);
214  f.setPointSize(13);
215  p.setFont(f);
216  QTextOption t;
217  t.setAlignment(Qt::AlignCenter);
218  p.drawText(QRect(0, 0, 16, 16), QString(QLatin1Char('A')), t);
219  return QPixmap::fromImage(img);
220 }
221 
223 {
224  return QIcon(fontValuePixmap(f));
225 }
226 
228 {
229  return QCoreApplication::translate("QtPropertyBrowserUtils", "[%1, %2]")
230  .arg(f.family()).arg(f.pointSize());
231 }
232 
233 
234 QtBoolEdit::QtBoolEdit(QWidget* parent) :
235  QWidget(parent),
236  m_checkBox(new QCheckBox(this)),
237  m_textVisible(true)
238 {
239  QHBoxLayout* lt = new QHBoxLayout;
240 
241  if (QApplication::layoutDirection() == Qt::LeftToRight)
242  {
243  lt->setContentsMargins(4, 0, 0, 0);
244  }
245  else
246  {
247  lt->setContentsMargins(0, 0, 4, 0);
248  }
249 
250  lt->addWidget(m_checkBox);
251  setLayout(lt);
252  connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
253  setFocusProxy(m_checkBox);
254  m_checkBox->setText(tr("True"));
255 }
256 
257 void QtBoolEdit::setTextVisible(bool textVisible)
258 {
259  if (m_textVisible == textVisible)
260  {
261  return;
262  }
263 
264  m_textVisible = textVisible;
265 
266  if (m_textVisible)
267  {
268  m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
269  }
270  else
271  {
272  m_checkBox->setText(QString());
273  }
274 }
275 
276 Qt::CheckState QtBoolEdit::checkState() const
277 {
278  return m_checkBox->checkState();
279 }
280 
281 void QtBoolEdit::setCheckState(Qt::CheckState state)
282 {
283  m_checkBox->setCheckState(state);
284 }
285 
287 {
288  return m_checkBox->isChecked();
289 }
290 
292 {
293  m_checkBox->setChecked(c);
294 
295  if (!m_textVisible)
296  {
297  return;
298  }
299 
300  m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
301 }
302 
304 {
305  return m_checkBox->blockSignals(block);
306 }
307 
308 void QtBoolEdit::mousePressEvent(QMouseEvent* event)
309 {
310  if (event->buttons() == Qt::LeftButton)
311  {
312  m_checkBox->click();
313  event->accept();
314  }
315  else
316  {
317  QWidget::mousePressEvent(event);
318  }
319 }
320 
321 void QtBoolEdit::paintEvent(QPaintEvent*)
322 {
323  QStyleOption opt;
324  opt.init(this);
325  QPainter p(this);
326  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
327 }
328 
329 
330 
332  : QWidget(parent), m_num(0), m_lineEdit(new QLineEdit(this))
333 {
334  QHBoxLayout* layout = new QHBoxLayout(this);
335  layout->addWidget(m_lineEdit);
336  layout->setMargin(0);
337  m_lineEdit->installEventFilter(this);
338  m_lineEdit->setReadOnly(true);
339  m_lineEdit->setFocusProxy(this);
340  setFocusPolicy(m_lineEdit->focusPolicy());
341  setAttribute(Qt::WA_InputMethodEnabled);
342 }
343 
344 bool QtKeySequenceEdit::eventFilter(QObject* o, QEvent* e)
345 {
346  if (o == m_lineEdit && e->type() == QEvent::ContextMenu)
347  {
348  QContextMenuEvent* c = static_cast<QContextMenuEvent*>(e);
349  QMenu* menu = m_lineEdit->createStandardContextMenu();
350  const QList<QAction*> actions = menu->actions();
351  QListIterator<QAction*> itAction(actions);
352 
353  while (itAction.hasNext())
354  {
355  QAction* action = itAction.next();
356  action->setShortcut(QKeySequence());
357  QString actionString = action->text();
358  const int pos = actionString.lastIndexOf(QLatin1Char('\t'));
359 
360  if (pos > 0)
361  {
362  actionString.remove(pos, actionString.length() - pos);
363  }
364 
365  action->setText(actionString);
366  }
367 
368  QAction* actionBefore = 0;
369 
370  if (actions.count() > 0)
371  {
372  actionBefore = actions[0];
373  }
374 
375  QAction* clearAction = new QAction(tr("Clear Shortcut"), menu);
376  menu->insertAction(actionBefore, clearAction);
377  menu->insertSeparator(actionBefore);
378  clearAction->setEnabled(!m_keySequence.isEmpty());
379  connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearShortcut()));
380  menu->exec(c->globalPos());
381  delete menu;
382  e->accept();
383  return true;
384  }
385 
386  return QWidget::eventFilter(o, e);
387 }
388 
389 void QtKeySequenceEdit::slotClearShortcut()
390 {
391  if (m_keySequence.isEmpty())
392  {
393  return;
394  }
395 
396  setKeySequence(QKeySequence());
397  emit keySequenceChanged(m_keySequence);
398 }
399 
400 void QtKeySequenceEdit::handleKeyEvent(QKeyEvent* e)
401 {
402  int nextKey = e->key();
403 
404  if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift ||
405  nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt ||
406  nextKey == Qt::Key_Super_L || nextKey == Qt::Key_AltGr)
407  {
408  return;
409  }
410 
411  nextKey |= translateModifiers(e->modifiers(), e->text());
412  int k0 = m_keySequence[0];
413  int k1 = m_keySequence[1];
414  int k2 = m_keySequence[2];
415  int k3 = m_keySequence[3];
416 
417  switch (m_num)
418  {
419  case 0:
420  k0 = nextKey;
421  k1 = 0;
422  k2 = 0;
423  k3 = 0;
424  break;
425 
426  case 1:
427  k1 = nextKey;
428  k2 = 0;
429  k3 = 0;
430  break;
431 
432  case 2:
433  k2 = nextKey;
434  k3 = 0;
435  break;
436 
437  case 3:
438  k3 = nextKey;
439  break;
440 
441  default:
442  break;
443  }
444 
445  ++m_num;
446 
447  if (m_num > 3)
448  {
449  m_num = 0;
450  }
451 
452  m_keySequence = QKeySequence(k0, k1, k2, k3);
453  m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
454  e->accept();
455  emit keySequenceChanged(m_keySequence);
456 }
457 
458 void QtKeySequenceEdit::setKeySequence(const QKeySequence& sequence)
459 {
460  if (sequence == m_keySequence)
461  {
462  return;
463  }
464 
465  m_num = 0;
466  m_keySequence = sequence;
467  m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
468 }
469 
470 QKeySequence QtKeySequenceEdit::keySequence() const
471 {
472  return m_keySequence;
473 }
474 
475 int QtKeySequenceEdit::translateModifiers(Qt::KeyboardModifiers state, const QString& text) const
476 {
477  int result = 0;
478 
479  if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint() || text.at(0).isLetter() || text.at(0).isSpace()))
480  {
481  result |= Qt::SHIFT;
482  }
483 
484  if (state & Qt::ControlModifier)
485  {
486  result |= Qt::CTRL;
487  }
488 
489  if (state & Qt::MetaModifier)
490  {
491  result |= Qt::META;
492  }
493 
494  if (state & Qt::AltModifier)
495  {
496  result |= Qt::ALT;
497  }
498 
499  return result;
500 }
501 
503 {
504  m_lineEdit->event(e);
505  m_lineEdit->selectAll();
506  QWidget::focusInEvent(e);
507 }
508 
510 {
511  m_num = 0;
512  m_lineEdit->event(e);
513  QWidget::focusOutEvent(e);
514 }
515 
517 {
518  handleKeyEvent(e);
519  e->accept();
520 }
521 
523 {
524  m_lineEdit->event(e);
525 }
526 
528 {
529  QStyleOption opt;
530  opt.init(this);
531  QPainter p(this);
532  style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
533 }
534 
536 {
537  if (e->type() == QEvent::Shortcut ||
538  e->type() == QEvent::ShortcutOverride ||
539  e->type() == QEvent::KeyRelease)
540  {
541  e->accept();
542  return true;
543  }
544 
545  return QWidget::event(e);
546 }
547 
548 QT_END_NAMESPACE
qtpropertybrowserutils_p.h
QtKeySequenceEdit::keySequence
QKeySequence keySequence() const
Definition: qtpropertybrowserutils.cpp:470
QtPropertyBrowserUtils::brushValuePixmap
static QPixmap brushValuePixmap(const QBrush &b)
Definition: qtpropertybrowserutils.cpp:172
QtKeySequenceEdit::event
bool event(QEvent *e) override
Definition: qtpropertybrowserutils.cpp:535
QtCursorDatabase::valueToCursor
QCursor valueToCursor(int value) const
Definition: qtpropertybrowserutils.cpp:161
QtPropertyBrowserUtils::colorValueText
static QString colorValueText(const QColor &c)
Definition: qtpropertybrowserutils.cpp:200
QtBoolEdit::QtBoolEdit
QtBoolEdit(QWidget *parent=0)
Definition: qtpropertybrowserutils.cpp:234
QtBoolEdit::blockCheckBoxSignals
bool blockCheckBoxSignals(bool block)
Definition: qtpropertybrowserutils.cpp:303
QtCursorDatabase::QtCursorDatabase
QtCursorDatabase()
Definition: qtpropertybrowserutils.cpp:54
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
QtKeySequenceEdit::keyPressEvent
void keyPressEvent(QKeyEvent *e) override
Definition: qtpropertybrowserutils.cpp:516
QtCursorDatabase::cursorShapeNames
QStringList cursorShapeNames() const
Definition: qtpropertybrowserutils.cpp:118
QtKeySequenceEdit::setKeySequence
void setKeySequence(const QKeySequence &sequence)
Definition: qtpropertybrowserutils.cpp:458
QtPropertyBrowserUtils::fontValuePixmap
static QPixmap fontValuePixmap(const QFont &f)
Definition: qtpropertybrowserutils.cpp:206
QtKeySequenceEdit::eventFilter
bool eventFilter(QObject *o, QEvent *e) override
Definition: qtpropertybrowserutils.cpp:344
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
QtKeySequenceEdit::QtKeySequenceEdit
QtKeySequenceEdit(QWidget *parent=0)
Definition: qtpropertybrowserutils.cpp:331
QtBoolEdit::setChecked
void setChecked(bool c)
Definition: qtpropertybrowserutils.cpp:291
QtKeySequenceEdit::focusInEvent
void focusInEvent(QFocusEvent *e) override
Definition: qtpropertybrowserutils.cpp:502
QtBoolEdit::paintEvent
void paintEvent(QPaintEvent *) override
Definition: qtpropertybrowserutils.cpp:321
QtCursorDatabase::cursorToValue
int cursorToValue(const QCursor &cursor) const
Definition: qtpropertybrowserutils.cpp:146
QtBoolEdit::setTextVisible
void setTextVisible(bool textVisible)
Definition: qtpropertybrowserutils.cpp:257
QtPropertyBrowserUtils::brushValueIcon
static QIcon brushValueIcon(const QBrush &b)
Definition: qtpropertybrowserutils.cpp:195
QtCursorDatabase::cursorToShapeName
QString cursorToShapeName(const QCursor &cursor) const
Definition: qtpropertybrowserutils.cpp:128
QtPropertyBrowserUtils::fontValueText
static QString fontValueText(const QFont &f)
Definition: qtpropertybrowserutils.cpp:227
QtBoolEdit::checkState
Qt::CheckState checkState() const
Definition: qtpropertybrowserutils.cpp:276
QtBoolEdit::isChecked
bool isChecked() const
Definition: qtpropertybrowserutils.cpp:286
QtBoolEdit::textVisible
bool textVisible() const
Definition: qtpropertybrowserutils_p.h:105
QtCursorDatabase::clear
void clear()
Definition: qtpropertybrowserutils.cpp:96
QtPropertyBrowserUtils::fontValueIcon
static QIcon fontValueIcon(const QFont &f)
Definition: qtpropertybrowserutils.cpp:222
QtBoolEdit::toggled
void toggled(bool)
QtBoolEdit::mousePressEvent
void mousePressEvent(QMouseEvent *event) override
Definition: qtpropertybrowserutils.cpp:308
QtCursorDatabase::cursorShapeIcons
QMap< int, QIcon > cursorShapeIcons() const
Definition: qtpropertybrowserutils.cpp:123
QtKeySequenceEdit::paintEvent
void paintEvent(QPaintEvent *) override
Definition: qtpropertybrowserutils.cpp:527
QtKeySequenceEdit::focusOutEvent
void focusOutEvent(QFocusEvent *e) override
Definition: qtpropertybrowserutils.cpp:509
QtCursorDatabase::cursorToShapeIcon
QIcon cursorToShapeIcon(const QCursor &cursor) const
Definition: qtpropertybrowserutils.cpp:140
QtKeySequenceEdit::keyReleaseEvent
void keyReleaseEvent(QKeyEvent *e) override
Definition: qtpropertybrowserutils.cpp:522
QtBoolEdit::setCheckState
void setCheckState(Qt::CheckState state)
Definition: qtpropertybrowserutils.cpp:281
QtKeySequenceEdit::keySequenceChanged
void keySequenceChanged(const QKeySequence &sequence)