1 /* This file is part of the KDE libraries
2 Copyright (C) 2007 Aurélien Gâteau <agateau@kde.org>
3 Copyright (C) 2012 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com>
4 Copyright (C) 2012-2016 Jarosław Staniek <staniek@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
20
21 #include "KexiGroupButton.h"
22
23 // Qt
24 #include <QAction>
25 #include <QStyleOptionToolButton>
26 #include <QStylePainter>
27 #include <QToolButton>
28
29 // KF5
30 #include <KLocalizedString>
31
32 class Q_DECL_HIDDEN KexiGroupButton::Private
33 {
34 public:
Private(KexiGroupButton * qq,const GroupPosition position)35 Private(KexiGroupButton *qq, const GroupPosition position) : groupPosition(position)
36 {
37 // Make the policy closer to QPushButton's default but horizontal shouldn't be Fixed,
38 // otherwise spacing gets broken
39 qq->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
40 }
41 GroupPosition groupPosition;
42 };
43
KexiGroupButton(GroupPosition position,QWidget * parent)44 KexiGroupButton::KexiGroupButton(GroupPosition position, QWidget* parent)
45 : QToolButton(parent), d(new Private(this, position))
46 {
47 }
48
KexiGroupButton(QWidget * parent)49 KexiGroupButton::KexiGroupButton(QWidget* parent)
50 : QToolButton(parent), d(new Private(this, NoGroup))
51 {
52 }
53
~KexiGroupButton()54 KexiGroupButton::~KexiGroupButton()
55 {
56 delete d;
57 }
58
setGroupPosition(KexiGroupButton::GroupPosition groupPosition)59 void KexiGroupButton::setGroupPosition(KexiGroupButton::GroupPosition groupPosition)
60 {
61 d->groupPosition = groupPosition;
62 }
63
groupPosition() const64 KexiGroupButton::GroupPosition KexiGroupButton::groupPosition() const
65 {
66 return d->groupPosition;
67 }
68
paintEvent(QPaintEvent * event)69 void KexiGroupButton::paintEvent(QPaintEvent* event)
70 {
71 if (groupPosition() == NoGroup) {
72 QToolButton::paintEvent(event);
73 return;
74 }
75 QStylePainter painter(this);
76 QStyleOptionToolButton opt;
77 initStyleOption(&opt);
78 QStyleOptionToolButton panelOpt = opt;
79 panelOpt.state |= QStyle::State_MouseOver; // force border
80
81 // Panel
82 QRect& panelRect = panelOpt.rect;
83 switch (groupPosition()) {
84 case GroupLeft:
85 panelRect.setWidth(panelRect.width() * 2);
86 break;
87 case GroupCenter:
88 panelRect.setLeft(panelRect.left() - panelRect.width());
89 panelRect.setWidth(panelRect.width() * 3);
90 break;
91 case GroupRight:
92 panelRect.setLeft(panelRect.left() - panelRect.width());
93 break;
94 case NoGroup:
95 Q_ASSERT(0);
96 }
97 if (autoRaise()) {
98 if (!isChecked() && !isDown() && !(panelOpt.state & QStyle::State_MouseOver)) {
99 // Use 'pushed' appearance for all buttons, but those that are not really pushed
100 // are drawn with less contrast and are toned down.
101 panelOpt.state |= (QStyle::State_On | QStyle::State_Sunken);
102 QPalette panelPal(panelOpt.palette);
103 QColor c;
104 c = panelPal.color(QPalette::Button);
105 c.setAlpha(50);
106 panelPal.setColor(QPalette::Button, c);
107 c = panelPal.color(QPalette::Window);
108 c.setAlpha(50);
109 panelPal.setColor(QPalette::Window, c);
110 panelOpt.palette = panelPal;
111 painter.setOpacity(0.5);
112 }
113 }
114 painter.drawPrimitive(QStyle::PE_PanelButtonTool, panelOpt);
115 painter.setOpacity(1.0);
116
117 // Separator
118 //! @todo make specific fixes for styles such as Plastique, Cleanlooks if there's practical no alernative
119 const int y1 = opt.rect.top() + 1;
120 const int y2 = opt.rect.bottom() - 1;
121 painter.setOpacity(0.4);
122 if (d->groupPosition != GroupRight) {
123 const int x = opt.rect.right();
124 painter.setPen(opt.palette.color(QPalette::Dark));
125 painter.drawLine(x, y1, x, y2);
126 }
127 painter.setOpacity(1.0);
128
129 // Text
130 painter.drawControl(QStyle::CE_ToolButtonLabel, opt);
131
132 // Filtering message on tooltip text for CJK to remove accelerators.
133 // Quoting ktoolbar.cpp:
134 // """
135 // CJK languages use more verbose accelerator marker: they add a Latin
136 // letter in parenthesis, and put accelerator on that. Hence, the default
137 // removal of ampersand only may not be enough there, instead the whole
138 // parenthesis construct should be removed. Provide these filtering i18n
139 // messages so that translators can use Transcript for custom removal.
140 // """
141 if (!actions().isEmpty()) {
142 QAction* action = actions().first();
143 setToolTip(i18nc("@info:tooltip of custom triple button", "%1", action->toolTip()));
144 }
145 }
146
mousePressEvent(QMouseEvent * e)147 void KexiGroupButton::mousePressEvent(QMouseEvent *e)
148 {
149 if (!isChecked()) { // only allow clicking to check; unchecking happens automatically
150 QToolButton::mousePressEvent(e);
151 }
152 }
153