File indexing completed on 2024-04-28 04:18:53

0001 // vim: set tabstop=4 shiftwidth=4 expandtab:
0002 /*
0003 Gwenview: an image viewer
0004 Copyright 2007 Aurélien Gâteau <agateau@kde.org>
0005 
0006 This program is free software; you can redistribute it and/or
0007 modify it under the terms of the GNU General Public License
0008 as published by the Free Software Foundation; either version 2
0009 of the License, or (at your option) any later version.
0010 
0011 This program is distributed in the hope that it will be useful,
0012 but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 GNU General Public License for more details.
0015 
0016 You should have received a copy of the GNU General Public License
0017 along with this program; if not, write to the Free Software
0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0019 
0020 */
0021 // Self
0022 #include <statusbartoolbutton.h>
0023 
0024 // Qt
0025 #include <QAction>
0026 #include <QStyleOptionToolBar>
0027 #include <QStyleOptionToolButton>
0028 #include <QStylePainter>
0029 
0030 // KF
0031 #include <KLocalizedString>
0032 
0033 namespace Gwenview
0034 {
0035 StatusBarToolButton::StatusBarToolButton(QWidget *parent)
0036     : QToolButton(parent)
0037     , mGroupPosition(NotGrouped)
0038 {
0039     setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0040     setFocusPolicy(Qt::NoFocus);
0041     setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
0042 }
0043 
0044 QSize StatusBarToolButton::sizeHint() const
0045 {
0046     QSize sizeHint = QToolButton::sizeHint();
0047 
0048     QStyleOptionToolButton opt;
0049     initStyleOption(&opt);
0050 
0051     const bool isIconOnly = opt.toolButtonStyle == Qt::ToolButtonIconOnly || (!opt.icon.isNull() && opt.text.isEmpty());
0052     const bool isTextOnly = opt.toolButtonStyle == Qt::ToolButtonTextOnly || (opt.icon.isNull() && !opt.text.isEmpty());
0053 
0054     if (isIconOnly || isTextOnly) {
0055         QSize contentSize;
0056         if (isIconOnly) {
0057             contentSize.setHeight(qMax(opt.iconSize.height(), opt.fontMetrics.height()));
0058             contentSize.setWidth(contentSize.height());
0059         } else if (isTextOnly) {
0060             // copying the default text size behavior for text only QToolButtons
0061             QSize textSize = opt.fontMetrics.size(Qt::TextShowMnemonic, opt.text);
0062             // NOTE: QToolButton really does use horizontalAdvance() instead of boundingRect().width()
0063             textSize.setWidth(textSize.width() + opt.fontMetrics.horizontalAdvance(QLatin1Char(' ')) * 2);
0064             contentSize.setHeight(qMax(opt.iconSize.height(), textSize.height()));
0065             contentSize.setWidth(textSize.width());
0066         }
0067         if (popupMode() == MenuButtonPopup) {
0068             contentSize.setWidth(contentSize.width() + style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &opt, this));
0069         }
0070         sizeHint = style()->sizeFromContents(QStyle::CT_ToolButton, &opt, contentSize, this);
0071     }
0072 
0073     return sizeHint;
0074 }
0075 
0076 void StatusBarToolButton::setGroupPosition(StatusBarToolButton::GroupPosition groupPosition)
0077 {
0078     mGroupPosition = groupPosition;
0079 }
0080 
0081 void StatusBarToolButton::paintEvent(QPaintEvent *event)
0082 {
0083     if (mGroupPosition == NotGrouped) {
0084         QToolButton::paintEvent(event);
0085         return;
0086     }
0087     QStylePainter painter(this);
0088     QStyleOptionToolButton opt;
0089     initStyleOption(&opt);
0090     QStyleOptionToolButton panelOpt = opt;
0091 
0092     // Panel
0093     QRect &panelRect = panelOpt.rect;
0094     switch (mGroupPosition) {
0095     case GroupLeft:
0096         panelRect.setWidth(panelRect.width() * 2);
0097         break;
0098     case GroupCenter:
0099         panelRect.setLeft(panelRect.left() - panelRect.width());
0100         panelRect.setWidth(panelRect.width() * 3);
0101         break;
0102     case GroupRight:
0103         panelRect.setLeft(panelRect.left() - panelRect.width());
0104         break;
0105     case NotGrouped:
0106         Q_ASSERT(0);
0107     }
0108     painter.drawPrimitive(QStyle::PE_PanelButtonTool, panelOpt);
0109 
0110     // Separator
0111     QStyleOptionToolBar tbOpt;
0112     tbOpt.palette = opt.palette;
0113     tbOpt.state = QStyle::State_Horizontal;
0114     const int width = style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent);
0115     const int height = opt.rect.height() - 2;
0116     const int y = opt.rect.y() + (opt.rect.height() - height) / 2;
0117     if (mGroupPosition & GroupRight) {
0118         // Kinda hacky. This is needed because of the way toolbar separators are horizontally aligned.
0119         // Tested with Breeze (width: 8), Fusion (width: 6) and Oxygen (width: 8)
0120         const int x = opt.rect.left() - width / 1.5;
0121         tbOpt.rect = QRect(x, y, width, height);
0122         painter.drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, tbOpt);
0123     }
0124     if (mGroupPosition & GroupLeft) {
0125         const int x = opt.rect.right() - width / 2;
0126         tbOpt.rect = QRect(x, y, width, height);
0127         painter.drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, tbOpt);
0128     }
0129 
0130     // Text
0131     painter.drawControl(QStyle::CE_ToolButtonLabel, opt);
0132 
0133     // Filtering message on tooltip text for CJK to remove accelerators.
0134     // Quoting ktoolbar.cpp:
0135     // """
0136     // CJK languages use more verbose accelerator marker: they add a Latin
0137     // letter in parenthesis, and put accelerator on that. Hence, the default
0138     // removal of ampersand only may not be enough there, instead the whole
0139     // parenthesis construct should be removed. Provide these filtering i18n
0140     // messages so that translators can use Transcript for custom removal.
0141     // """
0142     if (!actions().isEmpty()) {
0143         QAction *action = actions().constFirst();
0144         setToolTip(i18nc("@info:tooltip of custom toolbar button", "%1", action->toolTip()));
0145     }
0146 }
0147 
0148 } // namespace
0149 
0150 #include "moc_statusbartoolbutton.cpp"