File indexing completed on 2025-01-26 05:09:32

0001 /*
0002  * This file is part of the KDE wacomtablet project. For copyright
0003  * information and license terms see the AUTHORS and COPYING files
0004  * in the top-level directory of this distribution.
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 as
0008  * published by the Free Software Foundation; either version 2 of
0009  * 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, see <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "tabletareaselectionview.h"
0021 
0022 #include "ui_tabletareaselectionview.h"
0023 
0024 #include <logging.h>
0025 
0026 using namespace Wacom;
0027 
0028 namespace Wacom
0029 {
0030 class TabletAreaSelectionViewPrivate
0031 {
0032 public:
0033     TabletAreaSelectionViewPrivate()
0034         : ui(new Ui::TabletAreaSelectionView)
0035     {
0036     }
0037     ~TabletAreaSelectionViewPrivate()
0038     {
0039         delete ui;
0040     }
0041 
0042     Ui::TabletAreaSelectionView *ui = nullptr;
0043 }; // PRIVATE CLASS
0044 } // NAMESPACE
0045 
0046 TabletAreaSelectionView::TabletAreaSelectionView(QWidget *parent)
0047     : QWidget(parent)
0048     , d_ptr(new TabletAreaSelectionViewPrivate)
0049 {
0050     setupUi();
0051 }
0052 
0053 TabletAreaSelectionView::~TabletAreaSelectionView()
0054 {
0055     delete this->d_ptr;
0056 }
0057 
0058 const TabletArea TabletAreaSelectionView::getSelection() const
0059 {
0060     Q_D(const TabletAreaSelectionView);
0061     return TabletArea(d->ui->areaWidget->getSelection());
0062 }
0063 
0064 void TabletAreaSelectionView::selectFullTablet()
0065 {
0066     Q_D(TabletAreaSelectionView);
0067 
0068     setTabletAreaType(TabletAreaSelectionView::FullTabletArea);
0069     d->ui->areaWidget->clearSelection();
0070 }
0071 
0072 void TabletAreaSelectionView::selectPartOfTablet(const TabletArea &selection)
0073 {
0074     Q_D(TabletAreaSelectionView);
0075 
0076     setTabletAreaType(TabletAreaSelectionView::PartialTabletArea);
0077     d->ui->areaWidget->setSelection(selection, true);
0078 }
0079 
0080 void TabletAreaSelectionView::select(QString output, bool isDesktop, const TabletArea &tabletSelection)
0081 {
0082     Q_D(TabletAreaSelectionView);
0083 
0084     if (isDesktop) {
0085         // select full desktop
0086         d->ui->screenArea->clearSelection();
0087     } else {
0088         // select monitor
0089         d->ui->screenArea->setSelection(output);
0090     }
0091 
0092     if (isFullAreaSelection(tabletSelection)) {
0093         // full tablet selection
0094         selectFullTablet();
0095     } else {
0096         // part of tablet selection
0097         selectPartOfTablet(tabletSelection);
0098     }
0099 }
0100 
0101 void TabletAreaSelectionView::setTrackingModeWarning(bool doShow)
0102 {
0103     Q_D(TabletAreaSelectionView);
0104 
0105     d->ui->warningIcon->setVisible(doShow);
0106     d->ui->warningLabel->setVisible(doShow);
0107 }
0108 
0109 void TabletAreaSelectionView::setupScreens(const QMap<QString, QRect> &screenGeometries, const QSize &widgetTargetSize)
0110 {
0111     Q_D(TabletAreaSelectionView);
0112 
0113     // disable screen toggling by default
0114     d->ui->screenToggleButton->setEnabled(false);
0115 
0116     // setup screen area
0117     d->ui->screenArea->setEnabled(false);
0118     d->ui->screenArea->setWidgetTargetSize(widgetTargetSize);
0119     d->ui->screenArea->setFont(QFont(QLatin1String("sans"), 8));
0120     d->ui->screenArea->paintBelow = true;
0121 
0122     if (screenGeometries.count() > 0) {
0123         d->ui->screenArea->setDrawAreaCaptions(true);
0124         d->ui->screenArea->setDrawSelectionCaption(true);
0125         d->ui->screenArea->setAreas(screenGeometries, screenGeometries.keys());
0126 
0127         // allow screen toggling if we have more than one screen
0128         if (screenGeometries.count() > 1) {
0129             d->ui->screenToggleButton->setEnabled(true);
0130         }
0131 
0132     } else {
0133         // no valid parameters passed, draw error box
0134         d->ui->screenArea->setDrawAreaCaptions(true);
0135         d->ui->screenArea->setDrawSelectionCaption(false);
0136         d->ui->screenArea->setArea(QRect(0, 0, 1920, 1200), i18n("Internal Error"));
0137         // We call this intentionally with no screens from setupUI()
0138         qCWarning(KCM) << "Call to TabletAreaSelectionView::setupScreens made with no valid screens.";
0139     }
0140 
0141     // defaults to full selection
0142     d->ui->screenArea->clearSelection();
0143 }
0144 
0145 void TabletAreaSelectionView::setupTablet(const TabletArea &geometry, const QSize &widgetTargetSize)
0146 {
0147     Q_D(TabletAreaSelectionView);
0148 
0149     d->ui->areaWidget->setWidgetTargetSize(widgetTargetSize);
0150     d->ui->areaWidget->setOutOfBoundsMargin(.1);
0151 
0152     if (geometry.isValid()) {
0153         QString caption = QString::fromLatin1("%1x%2").arg(geometry.width()).arg(geometry.height());
0154 
0155         d->ui->areaWidget->setDrawAreaCaptions(true);
0156         d->ui->areaWidget->setDrawSelectionCaption(true);
0157         d->ui->areaWidget->setArea(geometry, caption);
0158 
0159     } else {
0160         // draw error message
0161         d->ui->areaWidget->setDrawAreaCaptions(true);
0162         d->ui->areaWidget->setDrawSelectionCaption(false);
0163         d->ui->areaWidget->setArea(QRect(0, 0, 1920, 1200), i18n("Internal Error"));
0164         qCWarning(KCM) << "Internal error, invalid tablet geometry -" << geometry.toString();
0165     }
0166 
0167     // defaults to full selection
0168     setTabletAreaType(TabletAreaSelectionView::FullTabletArea);
0169 }
0170 
0171 void TabletAreaSelectionView::onCalibrateClicked()
0172 {
0173     emit signalCalibrateClicked();
0174 }
0175 
0176 void TabletAreaSelectionView::onForceProportionsClicked()
0177 {
0178     emit signalSetScreenProportions();
0179 }
0180 
0181 void TabletAreaSelectionView::onFullTabletSelected(bool checked)
0182 {
0183     if (!checked) {
0184         return;
0185     }
0186     setTabletAreaType(TabletAreaSelectionView::FullTabletArea);
0187 }
0188 
0189 void TabletAreaSelectionView::onScreenToggle()
0190 {
0191     emit signalScreenToggle();
0192 }
0193 
0194 void TabletAreaSelectionView::onTabletAreaSelected(bool checked)
0195 {
0196     if (!checked) {
0197         return;
0198     }
0199     setTabletAreaType(TabletAreaSelectionView::PartialTabletArea);
0200 }
0201 
0202 void TabletAreaSelectionView::onLockProportionsToggled(bool enabled)
0203 {
0204     Q_D(TabletAreaSelectionView);
0205 
0206     d->ui->areaWidget->lockProportions(enabled);
0207 }
0208 
0209 void TabletAreaSelectionView::setSelection(const TabletArea &selection)
0210 {
0211     if (selection.isValid()) {
0212         if (isFullAreaSelection(selection)) {
0213             selectFullTablet();
0214         } else {
0215             selectPartOfTablet(selection);
0216         }
0217     } else {
0218         selectFullTablet();
0219     }
0220 }
0221 
0222 void TabletAreaSelectionView::setTabletAreaType(TabletAreaSelectionView::TabletAreaType type)
0223 {
0224     Q_D(TabletAreaSelectionView);
0225 
0226     d->ui->fullTabletRadioButton->blockSignals(true);
0227     d->ui->tabletAreaRadioButton->blockSignals(true);
0228 
0229     if (type == TabletAreaSelectionView::FullTabletArea) {
0230         d->ui->fullTabletRadioButton->setChecked(true);
0231         d->ui->tabletAreaRadioButton->setChecked(false);
0232 
0233         d->ui->areaWidget->clearSelection();
0234         d->ui->areaWidget->setEnabled(false);
0235 
0236         emit signalFullTabletSelection();
0237 
0238     } else {
0239         d->ui->tabletAreaRadioButton->setChecked(true);
0240         d->ui->fullTabletRadioButton->setChecked(false);
0241 
0242         d->ui->areaWidget->setEnabled(true);
0243 
0244         emit signalTabletAreaSelection();
0245     }
0246 
0247     d->ui->fullTabletRadioButton->blockSignals(false);
0248     d->ui->tabletAreaRadioButton->blockSignals(false);
0249 }
0250 
0251 void TabletAreaSelectionView::onSelectionChanged()
0252 {
0253     Q_D(TabletAreaSelectionView);
0254 
0255     const auto selection = d->ui->areaWidget->getSelection();
0256 
0257     d->ui->lineEditX->setText(QString::number(selection.x()));
0258     d->ui->lineEditY->setText(QString::number(selection.y()));
0259     d->ui->lineEditWidth->setText(QString::number(selection.width()));
0260     d->ui->lineEditHeight->setText(QString::number(selection.height()));
0261 }
0262 
0263 void TabletAreaSelectionView::onFineTuneValuesChanged(QString)
0264 {
0265     Q_D(TabletAreaSelectionView);
0266 
0267     bool xvalid = true;
0268     bool yvalid = true;
0269     bool wvalid = true;
0270     bool hvalid = true;
0271 
0272     const QRect newSelection(d->ui->lineEditX->text().toInt(&xvalid),
0273                              d->ui->lineEditY->text().toInt(&yvalid),
0274                              d->ui->lineEditWidth->text().toInt(&wvalid),
0275                              d->ui->lineEditHeight->text().toInt(&hvalid));
0276 
0277     if (newSelection.isEmpty() || !newSelection.isValid() || !xvalid || !yvalid || !wvalid || !hvalid) {
0278         return;
0279     }
0280 
0281     d->ui->areaWidget->setSelection(newSelection, false);
0282 }
0283 
0284 bool TabletAreaSelectionView::isFullAreaSelection(const TabletArea &selection) const
0285 {
0286     Q_D(const TabletAreaSelectionView);
0287 
0288     return (selection.isEmpty() || selection == d->ui->areaWidget->getVirtualArea());
0289 }
0290 
0291 void TabletAreaSelectionView::setupUi()
0292 {
0293     Q_D(TabletAreaSelectionView);
0294 
0295     d->ui->setupUi(this);
0296     d->ui->iconLabel->setPixmap(QIcon::fromTheme(QLatin1String("help-about")).pixmap(QSize(16, 16)));
0297 
0298     d->ui->warningIcon->setPixmap(QIcon::fromTheme(QLatin1String("dialog-warning")).pixmap(QSize(16, 16)));
0299     d->ui->warningIcon->setVisible(true);
0300     d->ui->warningLabel->setVisible(false);
0301 
0302     // FIXME: signal-slot editor can't see this signal for some reason
0303     // TODO: rename areaWidget and screenArea, this is confusing
0304     connect(d->ui->areaWidget, &AreaSelectionWidget::selectionChanged, this, &TabletAreaSelectionView::onSelectionChanged);
0305 
0306     connect(d->ui->lineEditX, &QLineEdit::textChanged, this, &TabletAreaSelectionView::onFineTuneValuesChanged);
0307     connect(d->ui->lineEditY, &QLineEdit::textChanged, this, &TabletAreaSelectionView::onFineTuneValuesChanged);
0308     connect(d->ui->lineEditHeight, &QLineEdit::textChanged, this, &TabletAreaSelectionView::onFineTuneValuesChanged);
0309     connect(d->ui->lineEditWidth, &QLineEdit::textChanged, this, &TabletAreaSelectionView::onFineTuneValuesChanged);
0310 
0311     // Is this next call, like, fake?
0312     setupScreens(QMap<QString, QRect>(), QSize(200, 200));
0313     setupTablet(TabletArea(), QSize(400, 400));
0314 }
0315 
0316 #include "moc_tabletareaselectionview.cpp"