source: trunk/tools/designer/src/components/propertyeditor/paletteeditor.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 20.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the Qt Designer of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "paletteeditor.h"
43
44#include <iconloader_p.h>
45#include <qtcolorbutton.h>
46
47#include <QtDesigner/QDesignerFormEditorInterface>
48#include <QtDesigner/QDesignerFormWindowManagerInterface>
49#include <QtDesigner/QDesignerIconCacheInterface>
50
51#include <QtCore/QMetaProperty>
52#include <QtGui/QPainter>
53#include <QtGui/QToolButton>
54#include <QtGui/QLabel>
55#include <QtGui/QHeaderView>
56
57QT_BEGIN_NAMESPACE
58
59namespace qdesigner_internal {
60
61enum { BrushRole = 33 };
62
63PaletteEditor::PaletteEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
64 QDialog(parent),
65 m_currentColorGroup(QPalette::Active),
66 m_paletteModel(new PaletteModel(this)),
67 m_modelUpdated(false),
68 m_paletteUpdated(false),
69 m_compute(true),
70 m_core(core)
71{
72 ui.setupUi(this);
73 ui.paletteView->setModel(m_paletteModel);
74 updatePreviewPalette();
75 updateStyledButton();
76 ui.paletteView->setModel(m_paletteModel);
77 ColorDelegate *delegate = new ColorDelegate(core, this);
78 ui.paletteView->setItemDelegate(delegate);
79 ui.paletteView->setEditTriggers(QAbstractItemView::AllEditTriggers);
80 connect(m_paletteModel, SIGNAL(paletteChanged(QPalette)),
81 this, SLOT(paletteChanged(QPalette)));
82 ui.paletteView->setSelectionBehavior(QAbstractItemView::SelectRows);
83#ifndef QT_NO_DRAGANDDROP
84 ui.paletteView->setDragEnabled(true);
85 ui.paletteView->setDropIndicatorShown(true);
86#endif
87 ui.paletteView->setRootIsDecorated(false);
88 ui.paletteView->setColumnHidden(2, true);
89 ui.paletteView->setColumnHidden(3, true);
90}
91
92PaletteEditor::~PaletteEditor()
93{
94}
95
96QPalette PaletteEditor::palette() const
97{
98 return m_editPalette;
99}
100
101void PaletteEditor::setPalette(const QPalette &palette)
102{
103 m_editPalette = palette;
104 const uint mask = palette.resolve();
105 for (int i = 0; i < (int)QPalette::NColorRoles; i++) {
106 if (!(mask & (1 << i))) {
107 m_editPalette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(i),
108 m_parentPalette.brush(QPalette::Active, static_cast<QPalette::ColorRole>(i)));
109 m_editPalette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i),
110 m_parentPalette.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i)));
111 m_editPalette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i),
112 m_parentPalette.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i)));
113 }
114 }
115 m_editPalette.resolve(mask);
116 updatePreviewPalette();
117 updateStyledButton();
118 m_paletteUpdated = true;
119 if (!m_modelUpdated)
120 m_paletteModel->setPalette(m_editPalette, m_parentPalette);
121 m_paletteUpdated = false;
122}
123
124void PaletteEditor::setPalette(const QPalette &palette, const QPalette &parentPalette)
125{
126 m_parentPalette = parentPalette;
127 setPalette(palette);
128}
129
130void PaletteEditor::on_buildButton_colorChanged(const QColor &)
131{
132 buildPalette();
133}
134
135void PaletteEditor::on_activeRadio_clicked()
136{
137 m_currentColorGroup = QPalette::Active;
138 updatePreviewPalette();
139}
140
141void PaletteEditor::on_inactiveRadio_clicked()
142{
143 m_currentColorGroup = QPalette::Inactive;
144 updatePreviewPalette();
145}
146
147void PaletteEditor::on_disabledRadio_clicked()
148{
149 m_currentColorGroup = QPalette::Disabled;
150 updatePreviewPalette();
151}
152
153void PaletteEditor::on_computeRadio_clicked()
154{
155 if (m_compute)
156 return;
157 ui.paletteView->setColumnHidden(2, true);
158 ui.paletteView->setColumnHidden(3, true);
159 m_compute = true;
160 m_paletteModel->setCompute(true);
161}
162
163void PaletteEditor::on_detailsRadio_clicked()
164{
165 if (!m_compute)
166 return;
167 const int w = ui.paletteView->columnWidth(1);
168 ui.paletteView->setColumnHidden(2, false);
169 ui.paletteView->setColumnHidden(3, false);
170 QHeaderView *header = ui.paletteView->header();
171 header->resizeSection(1, w / 3);
172 header->resizeSection(2, w / 3);
173 header->resizeSection(3, w / 3);
174 m_compute = false;
175 m_paletteModel->setCompute(false);
176}
177
178void PaletteEditor::paletteChanged(const QPalette &palette)
179{
180 m_modelUpdated = true;
181 if (!m_paletteUpdated)
182 setPalette(palette);
183 m_modelUpdated = false;
184}
185
186void PaletteEditor::buildPalette()
187{
188 const QColor btn = ui.buildButton->color();
189 const QPalette temp = QPalette(btn);
190 setPalette(temp);
191}
192
193void PaletteEditor::updatePreviewPalette()
194{
195 const QPalette::ColorGroup g = currentColorGroup();
196 // build the preview palette
197 const QPalette currentPalette = palette();
198 QPalette previewPalette;
199 for (int i = QPalette::WindowText; i < QPalette::NColorRoles; i++) {
200 const QPalette::ColorRole r = static_cast<QPalette::ColorRole>(i);
201 const QBrush br = currentPalette.brush(g, r);
202 previewPalette.setBrush(QPalette::Active, r, br);
203 previewPalette.setBrush(QPalette::Inactive, r, br);
204 previewPalette.setBrush(QPalette::Disabled, r, br);
205 }
206 ui.previewFrame->setPreviewPalette(previewPalette);
207
208 const bool enabled = g != QPalette::Disabled;
209 ui.previewFrame->setEnabled(enabled);
210 ui.previewFrame->setSubWindowActive(g != QPalette::Inactive);
211}
212
213void PaletteEditor::updateStyledButton()
214{
215 ui.buildButton->setColor(palette().color(QPalette::Active, QPalette::Button));
216}
217
218QPalette PaletteEditor::getPalette(QDesignerFormEditorInterface *core, QWidget* parent, const QPalette &init,
219 const QPalette &parentPal, int *ok)
220{
221 PaletteEditor dlg(core, parent);
222 QPalette parentPalette(parentPal);
223 uint mask = init.resolve();
224 for (int i = 0; i < (int)QPalette::NColorRoles; i++) {
225 if (!(mask & (1 << i))) {
226 parentPalette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(i),
227 init.brush(QPalette::Active, static_cast<QPalette::ColorRole>(i)));
228 parentPalette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i),
229 init.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(i)));
230 parentPalette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i),
231 init.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(i)));
232 }
233 }
234 dlg.setPalette(init, parentPalette);
235
236 const int result = dlg.exec();
237 if (ok) *ok = result;
238
239 return result == QDialog::Accepted ? dlg.palette() : init;
240}
241
242//////////////////////
243
244PaletteModel::PaletteModel(QObject *parent) :
245 QAbstractTableModel(parent),
246 m_compute(true)
247{
248 const QMetaObject *meta = metaObject();
249 const int index = meta->indexOfProperty("colorRole");
250 const QMetaProperty p = meta->property(index);
251 const QMetaEnum e = p.enumerator();
252 for (int r = QPalette::WindowText; r < QPalette::NColorRoles; r++) {
253 m_roleNames[static_cast<QPalette::ColorRole>(r)] = QLatin1String(e.key(r));
254 }
255}
256
257int PaletteModel::rowCount(const QModelIndex &) const
258{
259 return m_roleNames.count();
260}
261
262int PaletteModel::columnCount(const QModelIndex &) const
263{
264 return 4;
265}
266
267QVariant PaletteModel::data(const QModelIndex &index, int role) const
268{
269 if (!index.isValid())
270 return QVariant();
271 if (index.row() < 0 || index.row() >= QPalette::NColorRoles)
272 return QVariant();
273 if (index.column() < 0 || index.column() >= 4)
274 return QVariant();
275
276 if (index.column() == 0) {
277 if (role == Qt::DisplayRole)
278 return m_roleNames[static_cast<QPalette::ColorRole>(index.row())];
279 if (role == Qt::EditRole) {
280 const uint mask = m_palette.resolve();
281 if (mask & (1 << index.row()))
282 return true;
283 return false;
284 }
285 return QVariant();
286 }
287 if (role == BrushRole)
288 return m_palette.brush(columnToGroup(index.column()),
289 static_cast<QPalette::ColorRole>(index.row()));
290 return QVariant();
291}
292
293bool PaletteModel::setData(const QModelIndex &index, const QVariant &value, int role)
294{
295 if (!index.isValid())
296 return false;
297
298 if (index.column() != 0 && role == BrushRole) {
299 const QBrush br = qVariantValue<QBrush>(value);
300 const QPalette::ColorRole r = static_cast<QPalette::ColorRole>(index.row());
301 const QPalette::ColorGroup g = columnToGroup(index.column());
302 m_palette.setBrush(g, r, br);
303
304 QModelIndex idxBegin = PaletteModel::index(r, 0);
305 QModelIndex idxEnd = PaletteModel::index(r, 3);
306 if (m_compute) {
307 m_palette.setBrush(QPalette::Inactive, r, br);
308 switch (r) {
309 case QPalette::WindowText:
310 case QPalette::Text:
311 case QPalette::ButtonText:
312 case QPalette::Base:
313 break;
314 case QPalette::Dark:
315 m_palette.setBrush(QPalette::Disabled, QPalette::WindowText, br);
316 m_palette.setBrush(QPalette::Disabled, QPalette::Dark, br);
317 m_palette.setBrush(QPalette::Disabled, QPalette::Text, br);
318 m_palette.setBrush(QPalette::Disabled, QPalette::ButtonText, br);
319 idxBegin = PaletteModel::index(0, 0);
320 idxEnd = PaletteModel::index(m_roleNames.count() - 1, 3);
321 break;
322 case QPalette::Window:
323 m_palette.setBrush(QPalette::Disabled, QPalette::Base, br);
324 m_palette.setBrush(QPalette::Disabled, QPalette::Window, br);
325 idxBegin = PaletteModel::index(QPalette::Base, 0);
326 break;
327 case QPalette::Highlight:
328 //m_palette.setBrush(QPalette::Disabled, QPalette::Highlight, c.dark(120));
329 break;
330 default:
331 m_palette.setBrush(QPalette::Disabled, r, br);
332 break;
333 }
334 }
335 emit paletteChanged(m_palette);
336 emit dataChanged(idxBegin, idxEnd);
337 return true;
338 }
339 if (index.column() == 0 && role == Qt::EditRole) {
340 uint mask = m_palette.resolve();
341 const bool isMask = qVariantValue<bool>(value);
342 const int r = index.row();
343 if (isMask)
344 mask |= (1 << r);
345 else {
346 m_palette.setBrush(QPalette::Active, static_cast<QPalette::ColorRole>(r),
347 m_parentPalette.brush(QPalette::Active, static_cast<QPalette::ColorRole>(r)));
348 m_palette.setBrush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r),
349 m_parentPalette.brush(QPalette::Inactive, static_cast<QPalette::ColorRole>(r)));
350 m_palette.setBrush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r),
351 m_parentPalette.brush(QPalette::Disabled, static_cast<QPalette::ColorRole>(r)));
352
353 mask &= ~(1 << index.row());
354 }
355 m_palette.resolve(mask);
356 emit paletteChanged(m_palette);
357 const QModelIndex idxEnd = PaletteModel::index(r, 3);
358 emit dataChanged(index, idxEnd);
359 return true;
360 }
361 return false;
362}
363
364Qt::ItemFlags PaletteModel::flags(const QModelIndex &index) const
365{
366 if (!index.isValid())
367 return Qt::ItemIsEnabled;
368 return Qt::ItemIsEditable | Qt::ItemIsEnabled;
369}
370
371QVariant PaletteModel::headerData(int section, Qt::Orientation orientation,
372 int role) const
373{
374 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
375 if (section == 0)
376 return tr("Color Role");
377 if (section == groupToColumn(QPalette::Active))
378 return tr("Active");
379 if (section == groupToColumn(QPalette::Inactive))
380 return tr("Inactive");
381 if (section == groupToColumn(QPalette::Disabled))
382 return tr("Disabled");
383 }
384 return QVariant();
385}
386
387QPalette PaletteModel::getPalette() const
388{
389 return m_palette;
390}
391
392void PaletteModel::setPalette(const QPalette &palette, const QPalette &parentPalette)
393{
394 m_parentPalette = parentPalette;
395 m_palette = palette;
396 const QModelIndex idxBegin = index(0, 0);
397 const QModelIndex idxEnd = index(m_roleNames.count() - 1, 3);
398 emit dataChanged(idxBegin, idxEnd);
399}
400
401QPalette::ColorGroup PaletteModel::columnToGroup(int index) const
402{
403 if (index == 1)
404 return QPalette::Active;
405 if (index == 2)
406 return QPalette::Inactive;
407 return QPalette::Disabled;
408}
409
410int PaletteModel::groupToColumn(QPalette::ColorGroup group) const
411{
412 if (group == QPalette::Active)
413 return 1;
414 if (group == QPalette::Inactive)
415 return 2;
416 return 3;
417}
418
419//////////////////////////
420
421BrushEditor::BrushEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
422 QWidget(parent),
423 m_button(new QtColorButton(this)),
424 m_changed(false),
425 m_core(core)
426{
427 QLayout *layout = new QHBoxLayout(this);
428 layout->setMargin(0);
429 layout->addWidget(m_button);
430 connect(m_button, SIGNAL(colorChanged(QColor)), this, SLOT(brushChanged()));
431 setFocusProxy(m_button);
432}
433
434void BrushEditor::setBrush(const QBrush &brush)
435{
436 m_button->setColor(brush.color());
437 m_changed = false;
438}
439
440QBrush BrushEditor::brush() const
441{
442 return QBrush(m_button->color());
443}
444
445void BrushEditor::brushChanged()
446{
447 m_changed = true;
448 emit changed(this);
449}
450
451bool BrushEditor::changed() const
452{
453 return m_changed;
454}
455
456//////////////////////////
457
458RoleEditor::RoleEditor(QWidget *parent) :
459 QWidget(parent),
460 m_label(new QLabel(this)),
461 m_edited(false)
462{
463 QHBoxLayout *layout = new QHBoxLayout(this);
464 layout->setMargin(0);
465 layout->setSpacing(0);
466
467 layout->addWidget(m_label);
468 m_label->setAutoFillBackground(true);
469 m_label->setIndent(3); // ### hardcode it should have the same value of textMargin in QItemDelegate
470 setFocusProxy(m_label);
471
472 QToolButton *button = new QToolButton(this);
473 button->setToolButtonStyle(Qt::ToolButtonIconOnly);
474 button->setIcon(createIconSet(QLatin1String("resetproperty.png")));
475 button->setIconSize(QSize(8,8));
476 button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding));
477 layout->addWidget(button);
478 connect(button, SIGNAL(clicked()), this, SLOT(emitResetProperty()));
479}
480
481void RoleEditor::setLabel(const QString &label)
482{
483 m_label->setText(label);
484}
485
486void RoleEditor::setEdited(bool on)
487{
488 QFont font;
489 if (on == true) {
490 font.setBold(on);
491 }
492 m_label->setFont(font);
493 m_edited = on;
494}
495
496bool RoleEditor::edited() const
497{
498 return m_edited;
499}
500
501void RoleEditor::emitResetProperty()
502{
503 setEdited(false);
504 emit changed(this);
505}
506
507//////////////////////////
508ColorDelegate::ColorDelegate(QDesignerFormEditorInterface *core, QObject *parent) :
509 QItemDelegate(parent),
510 m_core(core)
511{
512}
513
514QWidget *ColorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &,
515 const QModelIndex &index) const
516{
517 QWidget *ed = 0;
518 if (index.column() == 0) {
519 RoleEditor *editor = new RoleEditor(parent);
520 connect(editor, SIGNAL(changed(QWidget*)), this, SIGNAL(commitData(QWidget*)));
521 //editor->setFocusPolicy(Qt::NoFocus);
522 //editor->installEventFilter(const_cast<ColorDelegate *>(this));
523 ed = editor;
524 } else {
525 BrushEditor *editor = new BrushEditor(m_core, parent);
526 connect(editor, SIGNAL(changed(QWidget*)), this, SIGNAL(commitData(QWidget*)));
527 editor->setFocusPolicy(Qt::NoFocus);
528 editor->installEventFilter(const_cast<ColorDelegate *>(this));
529 ed = editor;
530 }
531 return ed;
532}
533
534void ColorDelegate::setEditorData(QWidget *ed, const QModelIndex &index) const
535{
536 if (index.column() == 0) {
537 const bool mask = qVariantValue<bool>(index.model()->data(index, Qt::EditRole));
538 RoleEditor *editor = static_cast<RoleEditor *>(ed);
539 editor->setEdited(mask);
540 const QString colorName = qVariantValue<QString>(index.model()->data(index, Qt::DisplayRole));
541 editor->setLabel(colorName);
542 } else {
543 const QBrush br = qVariantValue<QBrush>(index.model()->data(index, BrushRole));
544 BrushEditor *editor = static_cast<BrushEditor *>(ed);
545 editor->setBrush(br);
546 }
547}
548
549void ColorDelegate::setModelData(QWidget *ed, QAbstractItemModel *model,
550 const QModelIndex &index) const
551{
552 if (index.column() == 0) {
553 RoleEditor *editor = static_cast<RoleEditor *>(ed);
554 const bool mask = editor->edited();
555 model->setData(index, mask, Qt::EditRole);
556 } else {
557 BrushEditor *editor = static_cast<BrushEditor *>(ed);
558 if (editor->changed()) {
559 QBrush br = editor->brush();
560 model->setData(index, br, BrushRole);
561 }
562 }
563}
564
565void ColorDelegate::updateEditorGeometry(QWidget *ed,
566 const QStyleOptionViewItem &option, const QModelIndex &index) const
567{
568 QItemDelegate::updateEditorGeometry(ed, option, index);
569 ed->setGeometry(ed->geometry().adjusted(0, 0, -1, -1));
570}
571
572void ColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt,
573 const QModelIndex &index) const
574{
575 QStyleOptionViewItem option = opt;
576 const bool mask = qVariantValue<bool>(index.model()->data(index, Qt::EditRole));
577 if (index.column() == 0 && mask) {
578 option.font.setBold(true);
579 }
580 QBrush br = qVariantValue<QBrush>(index.model()->data(index, BrushRole));
581 if (br.style() == Qt::LinearGradientPattern ||
582 br.style() == Qt::RadialGradientPattern ||
583 br.style() == Qt::ConicalGradientPattern) {
584 painter->save();
585 painter->translate(option.rect.x(), option.rect.y());
586 painter->scale(option.rect.width(), option.rect.height());
587 QGradient gr = *(br.gradient());
588 gr.setCoordinateMode(QGradient::LogicalMode);
589 br = QBrush(gr);
590 painter->fillRect(0, 0, 1, 1, br);
591 painter->restore();
592 } else {
593 painter->save();
594 painter->setBrushOrigin(option.rect.x(), option.rect.y());
595 painter->fillRect(option.rect, br);
596 painter->restore();
597 }
598 QItemDelegate::paint(painter, option, index);
599
600
601 const QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &option));
602 const QPen oldPen = painter->pen();
603 painter->setPen(QPen(color));
604
605 painter->drawLine(option.rect.right(), option.rect.y(),
606 option.rect.right(), option.rect.bottom());
607 painter->drawLine(option.rect.x(), option.rect.bottom(),
608 option.rect.right(), option.rect.bottom());
609 painter->setPen(oldPen);
610}
611
612QSize ColorDelegate::sizeHint(const QStyleOptionViewItem &opt, const QModelIndex &index) const
613{
614 return QItemDelegate::sizeHint(opt, index) + QSize(4, 4);
615}
616}
617
618QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.