kde-extraapps/kcalc/kcalc_button.cpp
Ivailo Monev 5d6defafb8 kcalc: automatically replaced tabs with space
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2021-11-29 22:05:38 +02:00

249 lines
8.2 KiB
C++

/*
Copyright (C) 2001 - 2013 Evan Teran
evan.teran@gmail.com
Copyright (C) 1996 - 2000 Bernd Johannes Wuebben
wuebben@kde.org
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "kcalc_button.h"
#include <QAbstractTextDocumentLayout>
#include <QApplication>
#include <QtGui/qstyleoption.h>
#include <QStylePainter>
#include <QTextDocument>
#include "moc_kcalc_button.cpp"
//------------------------------------------------------------------------------
// Name: KCalcButton
// Desc: constructor
//------------------------------------------------------------------------------
KCalcButton::KCalcButton(QWidget *parent) : KPushButton(parent), show_shortcut_mode_(false), mode_flags_(ModeNormal), size_() {
setAcceptDrops(true); // allow color drops
setFocusPolicy(Qt::TabFocus);
setAutoDefault(false);
// use preferred size policy for vertical
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
}
//------------------------------------------------------------------------------
// Name: KCalcButton
// Desc: constructor
//------------------------------------------------------------------------------
KCalcButton::KCalcButton(const QString &label, QWidget *parent, const QString &tooltip) : KPushButton(label, parent), show_shortcut_mode_(false), mode_flags_(ModeNormal), size_() {
setAutoDefault(false);
addMode(ModeNormal, label, tooltip);
// use preferred size policy for vertical
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
}
//------------------------------------------------------------------------------
// Name: addMode
// Desc:
//------------------------------------------------------------------------------
void KCalcButton::addMode(ButtonModeFlags mode, const QString &label, const QString &tooltip) {
if (mode_.contains(mode)) {
mode_.remove(mode);
}
mode_[mode] = ButtonMode(label, tooltip);
calcSizeHint();
// Need to put each button into default mode first
if (mode == ModeNormal) {
slotSetMode(ModeNormal, true);
}
}
//------------------------------------------------------------------------------
// Name: slotSetMode
// Desc:
//------------------------------------------------------------------------------
void KCalcButton::slotSetMode(ButtonModeFlags mode, bool flag) {
ButtonModeFlags new_mode;
if (flag) { // if the specified mode is to be set (i.e. flag = true)
new_mode = ButtonModeFlags(mode_flags_ | mode);
} else if (mode_flags_ && mode) { // if the specified mode is to be cleared (i.e. flag = false)
new_mode = ButtonModeFlags(mode_flags_ - mode);
} else {
return; // nothing to do
}
if (mode_.contains(new_mode)) {
// save shortcut, because setting label erases it
QKeySequence current_shortcut = shortcut();
setText(mode_[new_mode].label);
this->setToolTip(mode_[new_mode].tooltip);
mode_flags_ = new_mode;
// restore shortcut
setShortcut(current_shortcut);
}
// this is necessary for people pressing CTRL and changing mode at
// the same time...
if (show_shortcut_mode_) {
slotSetAccelDisplayMode(true);
}
update();
}
//------------------------------------------------------------------------------
// Name: slotSetAccelDisplayMode
// Desc:
//------------------------------------------------------------------------------
void KCalcButton::slotSetAccelDisplayMode(bool flag) {
show_shortcut_mode_ = flag;
// save shortcut, because setting label erases it
QKeySequence current_shortcut = shortcut();
if (flag) {
setText(shortcut().toString());
} else {
setText(mode_[mode_flags_].label);
}
// restore shortcut
setShortcut(current_shortcut);
update();
}
//------------------------------------------------------------------------------
// Name: paintEvent
// Desc: draws the button
//------------------------------------------------------------------------------
void KCalcButton::paintEvent(QPaintEvent *) {
QPainter p(this);
QStyleOptionButton option;
initStyleOption(&option);
const bool is_down = isDown() || isChecked();
const int x_offset = is_down ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option, this) : 0;
const int y_offset = is_down ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option, this) : 0;
// draw bevel
style()->drawControl(QStyle::CE_PushButtonBevel, &option, &p, this);
// draw label...
p.save();
// rant: Qt4 needs QSimpleRichText, dammit!
QTextDocument doc;
QAbstractTextDocumentLayout::PaintContext context;
doc.setHtml(QLatin1String("<center>") + text() + QLatin1String("</center>"));
doc.setDefaultFont(font());
context.palette = palette();
context.palette.setColor(QPalette::Text, context.palette.buttonText().color());
p.translate((width() / 2 - doc.size().width() / 2) + x_offset, (height() / 2 - doc.size().height() / 2) + y_offset);
doc.documentLayout()->draw(&p, context);
p.restore();
// draw focus
if (hasFocus()) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(option);
fropt.rect = style()->subElementRect(QStyle::SE_PushButtonFocusRect, &option, this);
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, &p, this);
}
}
//------------------------------------------------------------------------------
// Name: sizeHint
// Desc:
//------------------------------------------------------------------------------
QSize KCalcButton::sizeHint() const {
// reimplemented to provide a smaller button
return size_;
}
//------------------------------------------------------------------------------
// Name: calcSizeHint
// Desc:
//------------------------------------------------------------------------------
void KCalcButton::calcSizeHint() {
int margin = style()->pixelMetric(QStyle::PM_ButtonMargin, 0, this);
// want narrow margin than normal
margin = qMax(margin / 2, 3);
// approximation because metrics doesn't account for richtext
size_ = fontMetrics().size(0, mode_[ModeNormal].label);
if (mode_.contains(ModeShift)) {
size_ = size_.expandedTo(fontMetrics().size(0, mode_[ModeShift].label));
}
if (mode_.contains(ModeHyperbolic)) {
size_ = size_.expandedTo(fontMetrics().size(0, mode_[ModeHyperbolic].label));
}
size_ += QSize(margin * 2, margin * 2);
size_ = size_.expandedTo(QApplication::globalStrut());
}
//------------------------------------------------------------------------------
// Name: setFont
// Desc:
//------------------------------------------------------------------------------
void KCalcButton::setFont(const QFont &fnt) {
KPushButton::setFont(fnt);
calcSizeHint();
}
//------------------------------------------------------------------------------
// Name: setText
// Desc:
//------------------------------------------------------------------------------
void KCalcButton::setText(const QString &text) {
KPushButton::setText(text);
// normal mode may not have been explicitly set
if (mode_[ModeNormal].label.isEmpty()) {
mode_[ModeNormal].label = text;
}
calcSizeHint();
}
//------------------------------------------------------------------------------
// Name: setToolTip
// Desc:
//------------------------------------------------------------------------------
void KCalcButton::setToolTip(const QString &tip) {
KPushButton::setToolTip(tip);
// normal mode may not have been explicitly set
if (mode_[ModeNormal].tooltip.isEmpty()) {
mode_[ModeNormal].tooltip = tip;
}
}