File indexing completed on 2024-05-12 16:39:37

0001 /* This file is part of the KDE libraries
0002    Copyright (C) 2007 Aurélien Gâteau <agateau@kde.org>
0003    Copyright (C) 2012 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com>
0004    Copyright (C) 2012-2016 Jarosław Staniek <staniek@kde.org>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License version 2 as published by the Free Software Foundation.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include "KexiGroupButton.h"
0022 
0023 // Qt
0024 #include <QAction>
0025 #include <QStyleOptionToolButton>
0026 #include <QStylePainter>
0027 #include <QToolButton>
0028 
0029 // KF5
0030 #include <KLocalizedString>
0031 
0032 class Q_DECL_HIDDEN KexiGroupButton::Private
0033 {
0034 public:
0035     Private(KexiGroupButton *qq, const GroupPosition position) : groupPosition(position)
0036     {
0037         // Make the policy closer to QPushButton's default but horizontal shouldn't be Fixed,
0038         // otherwise spacing gets broken
0039         qq->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
0040     }
0041     GroupPosition groupPosition;
0042 };
0043 
0044 KexiGroupButton::KexiGroupButton(GroupPosition position, QWidget* parent)
0045  : QToolButton(parent), d(new Private(this, position))
0046 {
0047 }
0048 
0049 KexiGroupButton::KexiGroupButton(QWidget* parent)
0050  : QToolButton(parent), d(new Private(this, NoGroup))
0051 {
0052 }
0053 
0054 KexiGroupButton::~KexiGroupButton()
0055 {
0056     delete d;
0057 }
0058 
0059 void KexiGroupButton::setGroupPosition(KexiGroupButton::GroupPosition groupPosition)
0060 {
0061     d->groupPosition = groupPosition;
0062 }
0063 
0064 KexiGroupButton::GroupPosition KexiGroupButton::groupPosition() const
0065 {
0066     return d->groupPosition;
0067 }
0068 
0069 void KexiGroupButton::paintEvent(QPaintEvent* event)
0070 {
0071     if (groupPosition() == NoGroup) {
0072         QToolButton::paintEvent(event);
0073         return;
0074     }
0075     QStylePainter painter(this);
0076     QStyleOptionToolButton opt;
0077     initStyleOption(&opt);
0078     QStyleOptionToolButton panelOpt = opt;
0079     panelOpt.state |= QStyle::State_MouseOver; // force border
0080 
0081     // Panel
0082     QRect& panelRect = panelOpt.rect;
0083     switch (groupPosition()) {
0084     case GroupLeft:
0085         panelRect.setWidth(panelRect.width() * 2);
0086         break;
0087     case GroupCenter:
0088         panelRect.setLeft(panelRect.left() - panelRect.width());
0089         panelRect.setWidth(panelRect.width() * 3);
0090         break;
0091     case GroupRight:
0092         panelRect.setLeft(panelRect.left() - panelRect.width());
0093         break;
0094     case NoGroup:
0095         Q_ASSERT(0);
0096     }
0097     if (autoRaise()) {
0098         if (!isChecked() && !isDown() && !(panelOpt.state & QStyle::State_MouseOver)) {
0099             // Use 'pushed' appearance for all buttons, but those that are not really pushed
0100             // are drawn with less contrast and are toned down.
0101             panelOpt.state |= (QStyle::State_On | QStyle::State_Sunken);
0102             QPalette panelPal(panelOpt.palette);
0103             QColor c;
0104             c = panelPal.color(QPalette::Button);
0105             c.setAlpha(50);
0106             panelPal.setColor(QPalette::Button, c);
0107             c = panelPal.color(QPalette::Window);
0108             c.setAlpha(50);
0109             panelPal.setColor(QPalette::Window, c);
0110             panelOpt.palette = panelPal;
0111             painter.setOpacity(0.5);
0112         }
0113     }
0114     painter.drawPrimitive(QStyle::PE_PanelButtonTool, panelOpt);
0115     painter.setOpacity(1.0);
0116 
0117     // Separator
0118     //! @todo make specific fixes for styles such as Plastique, Cleanlooks if there's practical no alernative
0119     const int y1 = opt.rect.top() + 1;
0120     const int y2 = opt.rect.bottom() - 1;
0121     painter.setOpacity(0.4);
0122     if (d->groupPosition != GroupRight) {
0123         const int x = opt.rect.right();
0124         painter.setPen(opt.palette.color(QPalette::Dark));
0125         painter.drawLine(x, y1, x, y2);
0126     }
0127     painter.setOpacity(1.0);
0128 
0129     // Text
0130     painter.drawControl(QStyle::CE_ToolButtonLabel, opt);
0131 
0132     // Filtering message on tooltip text for CJK to remove accelerators.
0133     // Quoting ktoolbar.cpp:
0134     // """
0135     // CJK languages use more verbose accelerator marker: they add a Latin
0136     // letter in parenthesis, and put accelerator on that. Hence, the default
0137     // removal of ampersand only may not be enough there, instead the whole
0138     // parenthesis construct should be removed. Provide these filtering i18n
0139     // messages so that translators can use Transcript for custom removal.
0140     // """
0141     if (!actions().isEmpty()) {
0142         QAction* action = actions().first();
0143         setToolTip(i18nc("@info:tooltip of custom triple button", "%1", action->toolTip()));
0144     }
0145 }
0146 
0147 void KexiGroupButton::mousePressEvent(QMouseEvent *e)
0148 {
0149     if (!isChecked()) { // only allow clicking to check; unchecking happens automatically
0150         QToolButton::mousePressEvent(e);
0151     }
0152 }