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
42#include <QApplication>
43#include <QCheckBox>
44#include <QHBoxLayout>
45#include <QLineEdit>
46#include <QMenu>
47#include <QMouseEvent>
48#include <QPainter>
49#include <QStyleOption>
50
52
53QT_BEGIN_NAMESPACE
54
56{
57 appendCursor(
58 Qt::ArrowCursor,
59 QCoreApplication::translate("QtCursorDatabase", "Arrow"),
60 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-arrow.png")));
61 appendCursor(
62 Qt::UpArrowCursor,
63 QCoreApplication::translate("QtCursorDatabase", "Up Arrow"),
64 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-uparrow.png")));
65 appendCursor(
66 Qt::CrossCursor,
67 QCoreApplication::translate("QtCursorDatabase", "Cross"),
68 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-cross.png")));
69 appendCursor(Qt::WaitCursor,
70 QCoreApplication::translate("QtCursorDatabase", "Wait"),
71 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-wait.png")));
72 appendCursor(
73 Qt::IBeamCursor,
74 QCoreApplication::translate("QtCursorDatabase", "IBeam"),
75 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-ibeam.png")));
76 appendCursor(
77 Qt::SizeVerCursor,
78 QCoreApplication::translate("QtCursorDatabase", "Size Vertical"),
79 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizev.png")));
80 appendCursor(
81 Qt::SizeHorCursor,
82 QCoreApplication::translate("QtCursorDatabase", "Size Horizontal"),
83 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeh.png")));
84 appendCursor(
85 Qt::SizeFDiagCursor,
86 QCoreApplication::translate("QtCursorDatabase", "Size Backslash"),
87 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizef.png")));
88 appendCursor(
89 Qt::SizeBDiagCursor,
90 QCoreApplication::translate("QtCursorDatabase", "Size Slash"),
91 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeb.png")));
92 appendCursor(
93 Qt::SizeAllCursor,
94 QCoreApplication::translate("QtCursorDatabase", "Size All"),
95 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-sizeall.png")));
96 appendCursor(
97 Qt::BlankCursor, QCoreApplication::translate("QtCursorDatabase", "Blank"), QIcon());
98 appendCursor(
99 Qt::SplitVCursor,
100 QCoreApplication::translate("QtCursorDatabase", "Split Vertical"),
101 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-vsplit.png")));
102 appendCursor(
103 Qt::SplitHCursor,
104 QCoreApplication::translate("QtCursorDatabase", "Split Horizontal"),
105 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-hsplit.png")));
106 appendCursor(Qt::PointingHandCursor,
107 QCoreApplication::translate("QtCursorDatabase", "Pointing Hand"),
108 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-hand.png")));
109 appendCursor(
110 Qt::ForbiddenCursor,
111 QCoreApplication::translate("QtCursorDatabase", "Forbidden"),
112 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-forbidden.png")));
113 appendCursor(
114 Qt::OpenHandCursor,
115 QCoreApplication::translate("QtCursorDatabase", "Open Hand"),
116 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-openhand.png")));
117 appendCursor(
118 Qt::ClosedHandCursor,
119 QCoreApplication::translate("QtCursorDatabase", "Closed Hand"),
120 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-closedhand.png")));
121 appendCursor(
122 Qt::WhatsThisCursor,
123 QCoreApplication::translate("QtCursorDatabase", "What's This"),
124 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-whatsthis.png")));
125 appendCursor(Qt::BusyCursor,
126 QCoreApplication::translate("QtCursorDatabase", "Busy"),
127 QIcon(QLatin1String(":/qt-project.org/qtpropertybrowser/images/cursor-busy.png")));
128}
129
130void
132{
133 m_cursorNames.clear();
134 m_cursorIcons.clear();
135 m_valueToCursorShape.clear();
136 m_cursorShapeToValue.clear();
137}
138
139void
140QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString& name, const QIcon& icon)
141{
142 if (m_cursorShapeToValue.contains(shape))
143 {
144 return;
145 }
146
147 const int value = m_cursorNames.count();
148 m_cursorNames.append(name);
149 m_cursorIcons.insert(value, icon);
150 m_valueToCursorShape.insert(value, shape);
151 m_cursorShapeToValue.insert(shape, value);
152}
153
154QStringList
156{
157 return m_cursorNames;
158}
159
160QMap<int, QIcon>
162{
163 return m_cursorIcons;
164}
165
166QString
167QtCursorDatabase::cursorToShapeName(const QCursor& cursor) const
168{
169 int val = cursorToValue(cursor);
170
171 if (val >= 0)
172 {
173 return m_cursorNames.at(val);
174 }
175
176 return QString();
177}
178
179QIcon
180QtCursorDatabase::cursorToShapeIcon(const QCursor& cursor) const
181{
182 int val = cursorToValue(cursor);
183 return m_cursorIcons.value(val);
184}
185
186int
187QtCursorDatabase::cursorToValue(const QCursor& cursor) const
188{
189#ifndef QT_NO_CURSOR
190 Qt::CursorShape shape = cursor.shape();
191
192 if (m_cursorShapeToValue.contains(shape))
193 {
194 return m_cursorShapeToValue[shape];
195 }
196
197#endif
198 return -1;
199}
200
201#ifndef QT_NO_CURSOR
202QCursor
204{
205 if (m_valueToCursorShape.contains(value))
206 {
207 return QCursor(m_valueToCursorShape[value]);
208 }
209
210 return QCursor();
211}
212#endif
213
214QPixmap
216{
217 QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
218 img.fill(0);
219
220 QPainter painter(&img);
221 painter.setCompositionMode(QPainter::CompositionMode_Source);
222 painter.fillRect(0, 0, img.width(), img.height(), b);
223 QColor color = b.color();
224
225 if (color.alpha() != 255) // indicate alpha by an inset
226 {
227 QBrush opaqueBrush = b;
228 color.setAlpha(255);
229 opaqueBrush.setColor(color);
230 painter.fillRect(
231 img.width() / 4, img.height() / 4, img.width() / 2, img.height() / 2, opaqueBrush);
232 }
233
234 painter.end();
235 return QPixmap::fromImage(img);
236}
237
238QIcon
240{
241 return QIcon(brushValuePixmap(b));
242}
243
244QString
246{
247 return QCoreApplication::translate("QtPropertyBrowserUtils", "[%1, %2, %3] (%4)")
248 .arg(c.red())
249 .arg(c.green())
250 .arg(c.blue())
251 .arg(c.alpha());
252}
253
254QPixmap
256{
257 QFont f = font;
258 QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
259 img.fill(0);
260 QPainter p(&img);
261 p.setRenderHint(QPainter::TextAntialiasing, true);
262 p.setRenderHint(QPainter::Antialiasing, true);
263 f.setPointSize(13);
264 p.setFont(f);
265 QTextOption t;
266 t.setAlignment(Qt::AlignCenter);
267 p.drawText(QRect(0, 0, 16, 16), QString(QLatin1Char('A')), t);
268 return QPixmap::fromImage(img);
269}
270
271QIcon
273{
274 return QIcon(fontValuePixmap(f));
275}
276
277QString
279{
280 return QCoreApplication::translate("QtPropertyBrowserUtils", "[%1, %2]")
281 .arg(f.family())
282 .arg(f.pointSize());
283}
284
285QtBoolEdit::QtBoolEdit(QWidget* parent) :
286 QWidget(parent), m_checkBox(new QCheckBox(this)), m_textVisible(true)
287{
288 QHBoxLayout* lt = new QHBoxLayout;
289
290 if (QApplication::layoutDirection() == Qt::LeftToRight)
291 {
292 lt->setContentsMargins(4, 0, 0, 0);
293 }
294 else
295 {
296 lt->setContentsMargins(0, 0, 4, 0);
297 }
298
299 lt->addWidget(m_checkBox);
300 setLayout(lt);
301 connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
302 setFocusProxy(m_checkBox);
303 m_checkBox->setText(tr("True"));
304}
305
306void
308{
309 if (m_textVisible == textVisible)
310 {
311 return;
312 }
313
314 m_textVisible = textVisible;
315
316 if (m_textVisible)
317 {
318 m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
319 }
320 else
321 {
322 m_checkBox->setText(QString());
323 }
324}
325
326Qt::CheckState
328{
329 return m_checkBox->checkState();
330}
331
332void
333QtBoolEdit::setCheckState(Qt::CheckState state)
334{
335 m_checkBox->setCheckState(state);
336}
337
338bool
340{
341 return m_checkBox->isChecked();
342}
343
344void
346{
347 m_checkBox->setChecked(c);
348
349 if (!m_textVisible)
350 {
351 return;
352 }
353
354 m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
355}
356
357bool
359{
360 return m_checkBox->blockSignals(block);
361}
362
363void
365{
366 if (event->buttons() == Qt::LeftButton)
367 {
368 m_checkBox->click();
369 event->accept();
370 }
371 else
372 {
373 QWidget::mousePressEvent(event);
374 }
375}
376
377void
379{
380 QStyleOption opt;
381 opt.init(this);
382 QPainter p(this);
383 style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
384}
385
387 QWidget(parent), m_num(0), m_lineEdit(new QLineEdit(this))
388{
389 QHBoxLayout* layout = new QHBoxLayout(this);
390 layout->addWidget(m_lineEdit);
391 layout->setMargin(0);
392 m_lineEdit->installEventFilter(this);
393 m_lineEdit->setReadOnly(true);
394 m_lineEdit->setFocusProxy(this);
395 setFocusPolicy(m_lineEdit->focusPolicy());
396 setAttribute(Qt::WA_InputMethodEnabled);
397}
398
399bool
400QtKeySequenceEdit::eventFilter(QObject* o, QEvent* e)
401{
402 if (o == m_lineEdit && e->type() == QEvent::ContextMenu)
403 {
404 QContextMenuEvent* c = static_cast<QContextMenuEvent*>(e);
405 QMenu* menu = m_lineEdit->createStandardContextMenu();
406 const QList<QAction*> actions = menu->actions();
407 QListIterator<QAction*> itAction(actions);
408
409 while (itAction.hasNext())
410 {
411 QAction* action = itAction.next();
412 action->setShortcut(QKeySequence());
413 QString actionString = action->text();
414 const int pos = actionString.lastIndexOf(QLatin1Char('\t'));
415
416 if (pos > 0)
417 {
418 actionString.remove(pos, actionString.length() - pos);
419 }
420
421 action->setText(actionString);
422 }
423
424 QAction* actionBefore = 0;
425
426 if (actions.count() > 0)
427 {
428 actionBefore = actions[0];
429 }
430
431 QAction* clearAction = new QAction(tr("Clear Shortcut"), menu);
432 menu->insertAction(actionBefore, clearAction);
433 menu->insertSeparator(actionBefore);
434 clearAction->setEnabled(!m_keySequence.isEmpty());
435 connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearShortcut()));
436 menu->exec(c->globalPos());
437 delete menu;
438 e->accept();
439 return true;
440 }
441
442 return QWidget::eventFilter(o, e);
443}
444
445void
446QtKeySequenceEdit::slotClearShortcut()
447{
448 if (m_keySequence.isEmpty())
449 {
450 return;
451 }
452
453 setKeySequence(QKeySequence());
454 emit keySequenceChanged(m_keySequence);
455}
456
457void
458QtKeySequenceEdit::handleKeyEvent(QKeyEvent* e)
459{
460 int nextKey = e->key();
461
462 if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift || nextKey == Qt::Key_Meta ||
463 nextKey == Qt::Key_Alt || nextKey == Qt::Key_Super_L || nextKey == Qt::Key_AltGr)
464 {
465 return;
466 }
467
468 nextKey |= translateModifiers(e->modifiers(), e->text());
469 int k0 = m_keySequence[0];
470 int k1 = m_keySequence[1];
471 int k2 = m_keySequence[2];
472 int k3 = m_keySequence[3];
473
474 switch (m_num)
475 {
476 case 0:
477 k0 = nextKey;
478 k1 = 0;
479 k2 = 0;
480 k3 = 0;
481 break;
482
483 case 1:
484 k1 = nextKey;
485 k2 = 0;
486 k3 = 0;
487 break;
488
489 case 2:
490 k2 = nextKey;
491 k3 = 0;
492 break;
493
494 case 3:
495 k3 = nextKey;
496 break;
497
498 default:
499 break;
500 }
501
502 ++m_num;
503
504 if (m_num > 3)
505 {
506 m_num = 0;
507 }
508
509 m_keySequence = QKeySequence(k0, k1, k2, k3);
510 m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
511 e->accept();
512 emit keySequenceChanged(m_keySequence);
513}
514
515void
516QtKeySequenceEdit::setKeySequence(const QKeySequence& sequence)
517{
518 if (sequence == m_keySequence)
519 {
520 return;
521 }
522
523 m_num = 0;
524 m_keySequence = sequence;
525 m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
526}
527
528QKeySequence
530{
531 return m_keySequence;
532}
533
534int
535QtKeySequenceEdit::translateModifiers(Qt::KeyboardModifiers state, const QString& text) const
536{
537 int result = 0;
538
539 if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint() ||
540 text.at(0).isLetter() || text.at(0).isSpace()))
541 {
542 result |= Qt::SHIFT;
543 }
544
545 if (state & Qt::ControlModifier)
546 {
547 result |= Qt::CTRL;
548 }
549
550 if (state & Qt::MetaModifier)
551 {
552 result |= Qt::META;
553 }
554
555 if (state & Qt::AltModifier)
556 {
557 result |= Qt::ALT;
558 }
559
560 return result;
561}
562
563void
565{
566 m_lineEdit->event(e);
567 m_lineEdit->selectAll();
568 QWidget::focusInEvent(e);
569}
570
571void
573{
574 m_num = 0;
575 m_lineEdit->event(e);
576 QWidget::focusOutEvent(e);
577}
578
579void
581{
582 handleKeyEvent(e);
583 e->accept();
584}
585
586void
588{
589 m_lineEdit->event(e);
590}
591
592void
594{
595 QStyleOption opt;
596 opt.init(this);
597 QPainter p(this);
598 style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
599}
600
601bool
603{
604 if (e->type() == QEvent::Shortcut || e->type() == QEvent::ShortcutOverride ||
605 e->type() == QEvent::KeyRelease)
606 {
607 e->accept();
608 return true;
609 }
610
611 return QWidget::event(e);
612}
613
614QT_END_NAMESPACE
constexpr T c
void setTextVisible(bool textVisible)
void paintEvent(QPaintEvent *) override
void toggled(bool)
void setCheckState(Qt::CheckState state)
bool blockCheckBoxSignals(bool block)
void mousePressEvent(QMouseEvent *event) override
Qt::CheckState checkState() const
QtBoolEdit(QWidget *parent=0)
QCursor valueToCursor(int value) const
QStringList cursorShapeNames() const
QMap< int, QIcon > cursorShapeIcons() const
QIcon cursorToShapeIcon(const QCursor &cursor) const
QString cursorToShapeName(const QCursor &cursor) const
int cursorToValue(const QCursor &cursor) const
void paintEvent(QPaintEvent *) override
void focusInEvent(QFocusEvent *e) override
bool eventFilter(QObject *o, QEvent *e) override
void setKeySequence(const QKeySequence &sequence)
void keyReleaseEvent(QKeyEvent *e) override
void keyPressEvent(QKeyEvent *e) override
void focusOutEvent(QFocusEvent *e) override
bool event(QEvent *e) override
QKeySequence keySequence() const
QtKeySequenceEdit(QWidget *parent=0)
void keySequenceChanged(const QKeySequence &sequence)
static QString fontValueText(const QFont &f)
static QPixmap brushValuePixmap(const QBrush &b)
static QIcon fontValueIcon(const QFont &f)
static QIcon brushValueIcon(const QBrush &b)
static QString colorValueText(const QColor &c)
static QPixmap fontValuePixmap(const QFont &f)
std::shared_ptr< Value > value()
Definition cxxopts.hpp:855