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 "touchpagewidget.h"
0021 #include "ui_touchpagewidget.h"
0022 
0023 #include "dbustabletinterface.h"
0024 #include "deviceprofile.h"
0025 #include "profilemanagement.h"
0026 #include "property.h"
0027 #include "stringutils.h"
0028 #include "tabletareaselectiondialog.h"
0029 #include "x11wacom.h"
0030 
0031 #include <QStringList>
0032 
0033 using namespace Wacom;
0034 
0035 TouchPageWidget::TouchPageWidget(QWidget *parent)
0036     : QWidget(parent)
0037     , ui(new Ui::TouchPageWidget)
0038 {
0039     setupUi();
0040 }
0041 
0042 TouchPageWidget::~TouchPageWidget()
0043 {
0044     delete ui;
0045 }
0046 
0047 void TouchPageWidget::setTabletId(const QString &tabletId)
0048 {
0049     _tabletId = tabletId;
0050 }
0051 
0052 void TouchPageWidget::loadFromProfile(ProfileManagementInterface &profileManagement)
0053 {
0054     DeviceProfile touchProfile = profileManagement.loadDeviceProfile(DeviceType::Touch);
0055 
0056     // set all properties no matter if the tablet supports that device
0057     // to get all widgets properly initialized.
0058 
0059     setTouchSupportEnabled(touchProfile.getPropertyAsBool(Property::Touch));
0060     setTrackingMode(touchProfile.getProperty(Property::Mode));
0061     setScreenSpace(touchProfile.getProperty(Property::ScreenSpace));
0062     setScreenMap(touchProfile.getProperty(Property::ScreenMap));
0063     setGesturesSupportEnabled(touchProfile.getPropertyAsBool(Property::Gesture));
0064     setScrollDistance(touchProfile.getProperty(Property::ScrollDistance));
0065     setScrollInversion(touchProfile.getProperty(Property::InvertScroll));
0066     setZoomDistance(touchProfile.getProperty(Property::ZoomDistance));
0067     setTapTime(touchProfile.getProperty(Property::TapTime));
0068 }
0069 
0070 void TouchPageWidget::reloadWidget()
0071 {
0072     // get all tablet device names we need
0073     QDBusReply<QString> touchDeviceNameReply = DBusTabletInterface::instance().getDeviceName(_tabletId, DeviceType::Touch.key());
0074 
0075     // update name and maximum tablet area for all devices
0076     _touchDeviceName.clear();
0077     _tabletGeometry = TabletArea();
0078     _screenMap = ScreenMap();
0079 
0080     if (touchDeviceNameReply.isValid()) {
0081         _touchDeviceName = touchDeviceNameReply.value();
0082         if (!_touchDeviceName.isEmpty()) { // touch device available
0083             _tabletGeometry = X11Wacom::getMaximumTabletArea(touchDeviceNameReply.value());
0084             _screenMap = ScreenMap(_tabletGeometry);
0085         }
0086     }
0087 }
0088 
0089 void TouchPageWidget::saveToProfile(ProfileManagementInterface &profileManagement)
0090 {
0091     if (_touchDeviceName.isEmpty()) {
0092         return; // no touch device available
0093     }
0094 
0095     DeviceProfile touchProfile = profileManagement.loadDeviceProfile(DeviceType::Touch);
0096 
0097     touchProfile.setProperty(Property::Touch, getTouchSupportEnabled());
0098     touchProfile.setProperty(Property::Mode, getTrackingMode());
0099     touchProfile.setProperty(Property::ScreenSpace, getScreenSpaceAsString());
0100     touchProfile.setProperty(Property::ScreenMap, getScreenMapAsString());
0101     touchProfile.setProperty(Property::Gesture, getGestureSupportEnabled());
0102     touchProfile.setProperty(Property::ScrollDistance, getScrollDistance());
0103     touchProfile.setProperty(Property::InvertScroll, getScrollInversion());
0104     touchProfile.setProperty(Property::ZoomDistance, getZoomDistance());
0105     touchProfile.setProperty(Property::TapTime, getTapTime());
0106     touchProfile.setProperty(Property::Rotate, _tabletRotation.key());
0107 
0108     profileManagement.saveDeviceProfile(touchProfile);
0109 }
0110 
0111 void TouchPageWidget::onGesturesModeChanged(int state)
0112 {
0113     if (state == Qt::Unchecked) {
0114         ui->gesturesWarning->animatedHide();
0115     } else {
0116         ui->gesturesWarning->animatedShow();
0117     }
0118 
0119     setGesturesSupportEnabled(state == Qt::Checked);
0120     onProfileChanged();
0121 }
0122 
0123 void TouchPageWidget::onProfileChanged()
0124 {
0125     emit changed();
0126 }
0127 
0128 void TouchPageWidget::onRotationChanged(const ScreenRotation &rotation)
0129 {
0130     _tabletRotation = rotation;
0131 }
0132 
0133 void TouchPageWidget::onTabletMappingClicked()
0134 {
0135     TabletAreaSelectionDialog selectionDialog;
0136     selectionDialog.setupWidget(getScreenMap(), _touchDeviceName, _tabletRotation);
0137     selectionDialog.select(getScreenSpace());
0138 
0139     if (selectionDialog.exec() == QDialog::Accepted) {
0140         setScreenMap(selectionDialog.getScreenMap());
0141         setScreenSpace(selectionDialog.getScreenSpace());
0142         onProfileChanged();
0143     }
0144 }
0145 
0146 void TouchPageWidget::onTouchModeChanged(int state)
0147 {
0148     // Show/hide the gestures warning as needed, since its UI gets enabled and
0149     // disabled dynamically when touch is turned on or off
0150     if (state == Qt::Unchecked) {
0151         ui->gesturesWarning->animatedHide();
0152     } else if (ui->gesturesCheckBox->isChecked()) {
0153         ui->gesturesWarning->animatedShow();
0154     }
0155 
0156     setTouchSupportEnabled(state == Qt::Checked);
0157     onProfileChanged();
0158 }
0159 
0160 void TouchPageWidget::onTrackingModeAbsolute(bool activated)
0161 {
0162     if (!activated) {
0163         return;
0164     }
0165 
0166     setTrackingMode(QLatin1String("absolute"));
0167     onProfileChanged();
0168 }
0169 
0170 void TouchPageWidget::onTrackingModeRelative(bool activated)
0171 {
0172     if (!activated) {
0173         return;
0174     }
0175 
0176     setTrackingMode(QLatin1String("relative"));
0177     onProfileChanged();
0178 }
0179 
0180 const QString TouchPageWidget::getGestureSupportEnabled() const
0181 {
0182     return (isGesturesSupportEnabled() ? QLatin1String("on") : QLatin1String("off"));
0183 }
0184 
0185 const ScreenMap &TouchPageWidget::getScreenMap() const
0186 {
0187     return _screenMap;
0188 }
0189 
0190 const QString TouchPageWidget::getScreenMapAsString() const
0191 {
0192     return getScreenMap().toString();
0193 }
0194 
0195 const ScreenSpace &TouchPageWidget::getScreenSpace() const
0196 {
0197     return _screenSpace;
0198 }
0199 
0200 const QString TouchPageWidget::getScreenSpaceAsString() const
0201 {
0202     return getScreenSpace().toString();
0203 }
0204 
0205 const QString TouchPageWidget::getScrollDistance() const
0206 {
0207     return QString::number(ui->scrollDistanceSpinBox->value());
0208 }
0209 
0210 const QString TouchPageWidget::getScrollInversion() const
0211 {
0212     return (ui->scrollInversionCheckBox->isChecked() ? QLatin1String("on") : QLatin1String("off"));
0213 }
0214 
0215 const QString TouchPageWidget::getTapTime() const
0216 {
0217     return QString::number(ui->tapTimeSpinBox->value());
0218 }
0219 
0220 const QString TouchPageWidget::getTouchSupportEnabled() const
0221 {
0222     return (isTouchSupportEnabled() ? QLatin1String("on") : QLatin1String("off"));
0223 }
0224 
0225 const QString TouchPageWidget::getTrackingMode() const
0226 {
0227     if (ui->trackAbsoluteRadioButton->isChecked()) {
0228         return QLatin1String("absolute");
0229     }
0230 
0231     return QLatin1String("relative");
0232 }
0233 
0234 const QString TouchPageWidget::getZoomDistance() const
0235 {
0236     return QString::number(ui->zoomDistanceSpinBox->value());
0237 }
0238 
0239 bool TouchPageWidget::isGesturesSupportEnabled() const
0240 {
0241     return ui->gesturesCheckBox->isChecked();
0242 }
0243 
0244 bool TouchPageWidget::isTouchSupportEnabled() const
0245 {
0246     return ui->touchCheckBox->isChecked();
0247 }
0248 
0249 void TouchPageWidget::setGesturesSupportEnabled(bool value)
0250 {
0251     ui->gesturesGroupBox->setEnabled(value);
0252 
0253     ui->gesturesCheckBox->blockSignals(true);
0254     ui->gesturesCheckBox->setChecked(value);
0255     ui->gesturesCheckBox->blockSignals(false);
0256 }
0257 
0258 void TouchPageWidget::setScreenMap(const ScreenMap &screenMap)
0259 {
0260     _screenMap = screenMap;
0261 
0262     assertValidTabletMapping();
0263 }
0264 
0265 void TouchPageWidget::setScreenMap(const QString &value)
0266 {
0267     setScreenMap(ScreenMap(value));
0268 }
0269 
0270 void TouchPageWidget::setScreenSpace(const ScreenSpace &screenSpace)
0271 {
0272     _screenSpace = screenSpace;
0273 
0274     assertValidTabletMapping();
0275 }
0276 
0277 void TouchPageWidget::setScreenSpace(const QString &value)
0278 {
0279     setScreenSpace(ScreenSpace(value));
0280 }
0281 
0282 void TouchPageWidget::setScrollDistance(const QString &value)
0283 {
0284     ui->scrollDistanceSpinBox->blockSignals(true);
0285     ui->scrollDistanceSpinBox->setValue(value.toInt());
0286     ui->scrollDistanceSpinBox->blockSignals(false);
0287 }
0288 
0289 void TouchPageWidget::setScrollInversion(const QString &value)
0290 {
0291     ui->scrollInversionCheckBox->blockSignals(true);
0292     ui->scrollInversionCheckBox->setChecked(StringUtils::asBool(value));
0293     ui->scrollInversionCheckBox->blockSignals(false);
0294 }
0295 
0296 void TouchPageWidget::setTouchSupportEnabled(bool value)
0297 {
0298     ui->trackingModeGroupBox->setEnabled(value);
0299     ui->touchMappingGroupBox->setEnabled(value);
0300     ui->gesturesCheckBox->setEnabled(value);
0301 
0302     if (isGesturesSupportEnabled()) {
0303         ui->gesturesGroupBox->setEnabled(value);
0304     }
0305 
0306     ui->touchCheckBox->blockSignals(true);
0307     ui->touchCheckBox->setChecked(value);
0308     ui->touchCheckBox->blockSignals(false);
0309 }
0310 
0311 void TouchPageWidget::setTapTime(const QString &value)
0312 {
0313     ui->tapTimeSpinBox->blockSignals(true);
0314     ui->tapTimeSpinBox->setValue(value.toInt());
0315     ui->tapTimeSpinBox->blockSignals(false);
0316 }
0317 
0318 void TouchPageWidget::setTrackingMode(const QString &value)
0319 {
0320     ui->trackAbsoluteRadioButton->blockSignals(true);
0321     ui->trackRelativeRadioButton->blockSignals(true);
0322 
0323     if (value.contains(QLatin1String("absolute"), Qt::CaseInsensitive)) {
0324         ui->trackAbsoluteRadioButton->setChecked(true);
0325         ui->trackRelativeRadioButton->setChecked(false);
0326     } else {
0327         ui->trackAbsoluteRadioButton->setChecked(false);
0328         ui->trackRelativeRadioButton->setChecked(true);
0329     }
0330 
0331     ui->trackAbsoluteRadioButton->blockSignals(false);
0332     ui->trackRelativeRadioButton->blockSignals(false);
0333 
0334     assertValidTabletMapping();
0335 }
0336 
0337 void TouchPageWidget::setZoomDistance(const QString &value)
0338 {
0339     ui->zoomDistanceSpinBox->blockSignals(true);
0340     ui->zoomDistanceSpinBox->setValue(value.toInt());
0341     ui->zoomDistanceSpinBox->blockSignals(false);
0342 }
0343 
0344 void TouchPageWidget::assertValidTabletMapping()
0345 {
0346     bool isWarningVisible = false;
0347 
0348     if (ui->trackRelativeRadioButton->isChecked()) {
0349         // Relative mode is selected. In relative mode a
0350         // device can not be mapped to a single monitor
0351         ScreenSpace screenSpace = getScreenSpace();
0352 
0353         if (screenSpace.isMonitor()) {
0354             isWarningVisible = true;
0355         }
0356     }
0357 
0358     ui->trackingWarningIcon->setVisible(isWarningVisible);
0359     ui->trackingWarningLabel->setVisible(isWarningVisible);
0360 }
0361 
0362 void TouchPageWidget::setupUi()
0363 {
0364     ui->setupUi(this);
0365 
0366     // init screen mapping warning
0367     ui->trackingWarningIcon->setPixmap(QIcon::fromTheme(QLatin1String("dialog-warning")).pixmap(QSize(16, 16)));
0368     ui->trackingWarningIcon->setVisible(false);
0369     ui->trackingWarningLabel->setVisible(false);
0370 }
0371 
0372 #include "moc_touchpagewidget.cpp"