File indexing completed on 2024-05-12 16:02:14

0001 /* SPDX-FileCopyrightText: 2008 Peter Simonsson <peter.simonsson@gmail.com>
0002  *
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  */
0005 
0006 #include "KoZoomInput.h"
0007 
0008 #include <WidgetsDebug.h>
0009 #include <klocalizedstring.h>
0010 
0011 #include <QComboBox>
0012 #include <QLabel>
0013 #include <QHBoxLayout>
0014 #include <QStyle>
0015 #include <QStyleOption>
0016 #include <QPainter>
0017 #include <QPalette>
0018 #include <QAbstractItemView>
0019 #include <QEvent>
0020 #include <QKeyEvent>
0021 #include <QLineEdit>
0022 
0023 class KoZoomInput::Private
0024 {
0025     public:
0026         QComboBox* combo;
0027         QLabel* label;
0028         bool inside;
0029         bool isFlat;
0030 };
0031 
0032 KoZoomInput::KoZoomInput(QWidget* parent)
0033     : QStackedWidget(parent), d(new Private)
0034 {
0035 #ifdef Q_OS_MACOS
0036     setAttribute(Qt::WA_MacMiniSize, true);
0037 #endif
0038 
0039     QWidget* first = new QWidget(this);
0040     QHBoxLayout* layout = new QHBoxLayout(first);
0041     layout->setSpacing(0);
0042     layout->setMargin(0);
0043     d->label = new QLabel(first);
0044     d->label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
0045     layout->addWidget(d->label, 10);
0046     QLabel* icon = new QLabel(first);
0047     QStyleOption option;
0048     option.state = QStyle::State_Enabled;
0049     QPixmap pixmap(16, 16);
0050     pixmap.fill(QColor(255, 255, 255, 0));
0051     QPainter painter(&pixmap);
0052     painter.translate(8, 8);
0053     style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &option, &painter);
0054     icon->setPixmap(pixmap);
0055     layout->addWidget(icon);
0056     addWidget(first);
0057     d->combo = new QComboBox(this);
0058     d->combo->setMaxVisibleItems(15);
0059     d->combo->setEditable(true);
0060     d->combo->installEventFilter(this);
0061     addWidget(d->combo);
0062     d->inside = false;
0063     d->isFlat = true;
0064 
0065     connect(d->combo, SIGNAL(activated(QString)), this, SIGNAL(zoomLevelChanged(QString)));
0066 }
0067 
0068 KoZoomInput::~KoZoomInput()
0069 {
0070     delete d;
0071 }
0072 
0073 void KoZoomInput::enterEvent(QEvent* event)
0074 {
0075     Q_UNUSED(event);
0076 
0077     d->inside = true;
0078     if (!isFlat()) {
0079         return;
0080     }
0081 
0082     if (d->combo->view())
0083     {
0084         d->combo->view()->removeEventFilter(this);
0085     }
0086 
0087     setCurrentIndex(1);
0088 }
0089 
0090 void KoZoomInput::leaveEvent(QEvent* event)
0091 {
0092     Q_UNUSED(event);
0093 
0094     d->inside = false;
0095     if (!isFlat()) {
0096         return;
0097     }
0098 
0099     if(d->combo->view() && d->combo->view()->isVisible())
0100     {
0101         d->combo->view()->installEventFilter(this);
0102         return;
0103     }
0104 
0105     if(!d->combo->hasFocus())
0106         setCurrentIndex(0);
0107 }
0108 
0109 void KoZoomInput::keyPressEvent(QKeyEvent* event)
0110 {
0111     if (event->key() == Qt::Key_Return ||
0112         event->key() == Qt::Key_Enter)
0113     {
0114         focusNextChild();
0115     }
0116 }
0117 
0118 bool KoZoomInput::isFlat() const
0119 {
0120     return d->isFlat;
0121 }
0122 
0123 void KoZoomInput::setFlat(bool flat)
0124 {
0125     if (flat == d->isFlat) {
0126         return;
0127     }
0128 
0129     d->isFlat = flat;
0130 
0131     if (flat) {
0132         d->combo->installEventFilter(this);
0133         if (d->inside) {
0134             enterEvent(nullptr);
0135         } else {
0136             leaveEvent(nullptr);
0137         }
0138         d->combo->setEditable(true);
0139     } else {
0140         d->combo->removeEventFilter(this);
0141         if (d->combo->view()) {
0142             d->combo->view()->removeEventFilter(this);
0143         }
0144         d->combo->setCurrentIndex(d->combo->findText(d->label->text()));
0145         d->combo->setEditable(false);
0146         setCurrentIndex(1);
0147     }
0148 }
0149 
0150 void KoZoomInput::setZoomLevels(const QStringList& levels)
0151 {
0152     d->combo->clear();
0153     d->combo->addItems(levels);
0154 }
0155 
0156 void KoZoomInput::setCurrentZoomLevel(const QString& level)
0157 {
0158     d->combo->setCurrentIndex(d->combo->findText(level));
0159     d->label->setText(level);
0160 }
0161 
0162 bool KoZoomInput::eventFilter(QObject* watched, QEvent* event)
0163 {
0164     if(watched == d->combo->view() && event->type() == QEvent::Hide)
0165     {
0166         focusNextChild();
0167         setCurrentIndex(0);
0168     }
0169     else if (watched == d->combo && event->type() == QEvent::FocusOut &&
0170             (d->combo->view() && !d->combo->view()->hasFocus()) && !d->inside)
0171     {
0172         setCurrentIndex(0);
0173     }
0174     return false;
0175 }