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 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 #include "KoGroupButton.h"
21 
22 #include <QAction>
23 #include <QStyleOptionToolButton>
24 #include <QStylePainter>
25 
26 #include <KLocalizedString>
27 
28 class Q_DECL_HIDDEN KoGroupButton::Private
29 {
30 public:
Private(KoGroupButton * qq,const GroupPosition position)31     Private(KoGroupButton *qq, const GroupPosition position) : groupPosition(position)
32     {
33         // Make the policy closer to QPushButton's default but horizontal shouldn't be Fixed,
34         // otherwise spacing gets broken
35         qq->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
36     }
37     GroupPosition groupPosition;
38 };
39 
KoGroupButton(GroupPosition position,QWidget * parent)40 KoGroupButton::KoGroupButton(GroupPosition position, QWidget* parent)
41     : KisHighlightedToolButton(parent), d(new Private(this, position))
42 {
43 }
44 
KoGroupButton(QWidget * parent)45 KoGroupButton::KoGroupButton(QWidget* parent)
46     : KisHighlightedToolButton(parent), d(new Private(this, NoGroup))
47 {
48 }
49 
~KoGroupButton()50 KoGroupButton::~KoGroupButton()
51 {
52     delete d;
53 }
54 
setGroupPosition(KoGroupButton::GroupPosition groupPosition)55 void KoGroupButton::setGroupPosition(KoGroupButton::GroupPosition groupPosition)
56 {
57     d->groupPosition = groupPosition;
58 }
59 
groupPosition() const60 KoGroupButton::GroupPosition KoGroupButton::groupPosition() const
61 {
62     return d->groupPosition;
63 }
64 
paintEvent(QPaintEvent * event)65 void KoGroupButton::paintEvent(QPaintEvent* event)
66 {
67     if (groupPosition() == NoGroup) {
68         QToolButton::paintEvent(event);
69         return;
70     }
71     QStylePainter painter(this);
72     QStyleOptionToolButton opt;
73     initStyleOption(&opt);
74     QStyleOptionToolButton panelOpt = opt;
75 
76     // Panel
77     QRect& panelRect = panelOpt.rect;
78     switch (groupPosition()) {
79     case GroupLeft:
80         panelRect.setWidth(panelRect.width() * 2);
81         break;
82     case GroupCenter:
83         panelRect.setLeft(panelRect.left() - panelRect.width());
84         panelRect.setWidth(panelRect.width() * 3);
85         break;
86     case GroupRight:
87         panelRect.setLeft(panelRect.left() - panelRect.width());
88         break;
89     case NoGroup:
90         Q_ASSERT(0);
91     }
92     if (autoRaise()) {
93         if (!isChecked() && !isDown() && !(panelOpt.state & QStyle::State_MouseOver)) {
94             // Use 'pushed' appearance for all buttons, but those that are not really pushed
95             // are drawn with less contrast and are toned down.
96             panelOpt.state |= (QStyle::State_On | QStyle::State_Sunken);
97             QPalette panelPal(panelOpt.palette);
98             QColor c;
99             c = panelPal.color(QPalette::Button);
100             c.setAlpha(50);
101             panelPal.setColor(QPalette::Button, c);
102             c = panelPal.color(QPalette::Window);
103             c.setAlpha(50);
104             panelPal.setColor(QPalette::Window, c);
105             panelOpt.palette = panelPal;
106             painter.setOpacity(0.5);
107         }
108     } else {
109 
110         if (!isChecked() && !isDown() && !(panelOpt.state & QStyle::State_MouseOver)) {
111 
112         } else {
113             // only highlight the selected item
114             panelOpt.state |= (QStyle::State_On | QStyle::State_Sunken);
115             QPalette panelPal(panelOpt.palette);
116             QColor c;
117             c = panelPal.color(QPalette::Button);
118             c.setAlpha(50);
119             panelPal.setColor(QPalette::Button, c);
120             c = panelPal.color(QPalette::Window);
121             c.setAlpha(50);
122             panelPal.setColor(QPalette::Window, c);
123             panelOpt.palette = panelPal;
124             painter.setOpacity(0.5);
125         }
126     }
127 
128 
129     painter.drawPrimitive(QStyle::PE_PanelButtonTool, panelOpt);
130     painter.setOpacity(1.0);
131 
132     // Separator
133     //! @todo make specific fixes for styles such as Plastique, Cleanlooks if there's practical no alternative
134     const int y1 = opt.rect.top() + 1;
135     const int y2 = opt.rect.bottom() - 1;
136     painter.setOpacity(0.4);
137     if (d->groupPosition != GroupRight) {
138         const int x = opt.rect.right();
139         painter.setPen(QPen(opt.palette.color(QPalette::Dark), 0));
140         painter.drawLine(x, y1, x, y2);
141     }
142     painter.setOpacity(1.0);
143 
144     // Text
145     painter.drawControl(QStyle::CE_ToolButtonLabel, opt);
146 
147     // Filtering message on tooltip text for CJK to remove accelerators.
148     // Quoting ktoolbar.cpp:
149     // """
150     // CJK languages use more verbose accelerator marker: they add a Latin
151     // letter in parenthesis, and put accelerator on that. Hence, the default
152     // removal of ampersand only may not be enough there, instead the whole
153     // parenthesis construct should be removed. Provide these filtering i18n
154     // messages so that translators can use Transcript for custom removal.
155     // """
156     if (!actions().isEmpty()) {
157         QAction* action = actions().first();
158         setToolTip(i18nc("@info:tooltip of custom triple button", "%1", action->toolTip()));
159     }
160 }
161