diff --git a/src/kcmodule/kcmwacomtabletwidget.cpp b/src/kcmodule/kcmwacomtabletwidget.cpp index f12a934..f5f13c3 100644 --- a/src/kcmodule/kcmwacomtabletwidget.cpp +++ b/src/kcmodule/kcmwacomtabletwidget.cpp @@ -1,501 +1,509 @@ /* * This file is part of the KDE wacomtablet project. For copyright * information and license terms see the AUTHORS and COPYING files * in the top-level directory of this distribution. * * 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 . */ #include "kcmwacomtabletwidget.h" #include "ui_kcmwacomtabletwidget.h" #include "ui_errorwidget.h" #include "logging.h" #include "profilemanagement.h" #include "generalpagewidget.h" #include "styluspagewidget.h" #include "buttonpagewidget.h" #include "tabletpagewidget.h" #include "touchpagewidget.h" // common #include "dbustabletinterface.h" #include "devicetype.h" #include //Qt includes #include #include #include #include #include #include #include #include #include +#include using namespace Wacom; namespace Wacom { /** * Private class for the d-pointer. */ class KCMWacomTabletWidgetPrivate { public: Ui::KCMWacomTabletWidget ui; //!< This user interface. GeneralPageWidget generalPage; //!< Widget that shows some basic information about the tablet. StylusPageWidget stylusPage; //!< Widget for the pen settings (stylus/eraser). ButtonPageWidget buttonPage; //!< Widget for the express button settings. TabletPageWidget tabletPage; //!< Widget for the tablet settings. TouchPageWidget touchPage; //!< Widget for the touch settings. QWidget deviceErrorWidget; //!< Device error widget. Ui::ErrorWidget deviceErrorUi; //!< Device error widget ui. bool profileChanged; //!< True if the profile was changed and not saved yet. }; // CLASS } // NAMESPACE +void makeScrollableTab(QTabWidget *parent, QWidget &tab, const QString &title) { + auto scrollableTab = new QScrollArea(parent); + scrollableTab->setWidget(&tab); + scrollableTab->setWidgetResizable(true); + scrollableTab->setFrameShadow(QFrame::Shadow::Plain); + parent->addTab(scrollableTab, title); +} KCMWacomTabletWidget::KCMWacomTabletWidget( QWidget *parent ) : QWidget( parent ), d_ptr(new KCMWacomTabletWidgetPrivate) { setupUi(); loadTabletInformation(); showHideConfig(); } KCMWacomTabletWidget::~KCMWacomTabletWidget() { delete this->d_ptr; } void KCMWacomTabletWidget::setupUi() { Q_D( KCMWacomTabletWidget ); DBusTabletInterface* dbusTabletInterface = &DBusTabletInterface::instance(); if(!dbusTabletInterface->isValid()) { qCWarning(KCM) << "DBus interface not available"; } d->profileChanged = false; // setup error widget d->deviceErrorUi.setupUi(&(d->deviceErrorWidget)); d->deviceErrorUi.errorImage->setPixmap( QIcon::fromTheme( QLatin1String( "dialog-warning" ) ).pixmap(48) ); connect(d->deviceErrorUi.buttonRunTabletFinder, &QCommandLinkButton::clicked, this, &KCMWacomTabletWidget::showTabletFinder); d->deviceErrorUi.buttonRunTabletFinder->setVisible(false); // setup normal ui d->ui.setupUi( this ); d->ui.addProfileButton->setIcon( QIcon::fromTheme( QLatin1String( "document-new" ) ) ); d->ui.delProfileButton->setIcon( QIcon::fromTheme( QLatin1String( "edit-delete-page" ) ) ); // connect tablet selector connect( d->ui.tabletListSelector, SIGNAL(currentIndexChanged(QString)), SLOT(onTabletSelectionChanged()) ); // connect profile selector connect( d->ui.addProfileButton, SIGNAL(clicked(bool)), SLOT(addProfile()) ); connect( d->ui.delProfileButton, SIGNAL(clicked(bool)), SLOT(delProfile()) ); connect( d->ui.profileSelector, SIGNAL(currentIndexChanged(QString)), SLOT(switchProfile(QString)) ); // connect configuration tabs connect( &(d->generalPage), SIGNAL(changed()), SLOT(profileChanged()) ); connect( &(d->stylusPage), SIGNAL(changed()), SLOT(profileChanged()) ); connect( &(d->buttonPage), SIGNAL(changed()), SLOT(profileChanged()) ); connect( &(d->tabletPage), SIGNAL(changed()), SLOT(profileChanged()) ); connect( &(d->touchPage), SIGNAL(changed()), SLOT(profileChanged()) ); // connect rotation handling connect( &(d->tabletPage), SIGNAL(rotationChanged(ScreenRotation)), &(d->touchPage), SLOT(onRotationChanged(ScreenRotation))); // connect DBus signals connect( dbusTabletInterface, SIGNAL(tabletAdded(QString)), SLOT(onTabletAdded(QString)) ); connect( dbusTabletInterface, SIGNAL(tabletRemoved(QString)), SLOT(onTabletRemoved(QString)) ); } void KCMWacomTabletWidget::loadTabletInformation() { Q_D( KCMWacomTabletWidget ); QDBusReply connectedTablets = DBusTabletInterface::instance().getTabletList(); if(!connectedTablets.isValid()) { return; } d->ui.tabletListSelector->blockSignals(true); foreach(const QString &tabletId, connectedTablets.value()) { addTabletToSelector(tabletId); } d->ui.tabletListSelector->blockSignals(false); } void KCMWacomTabletWidget::showHideConfig() { // request this to see if dbus works and tablets are connected QDBusReply connectedTablets = DBusTabletInterface::instance().getTabletList(); if( !connectedTablets.isValid() ) { QString errorTitle = i18n( "KDE tablet service not found" ); QString errorMsg = i18n( "Please start the KDE wacom tablet service to use this configuration dialog.\n" "The service is required for tablet detection and profile support." ); showError( errorTitle, errorMsg ); } else if(!QX11Info::isPlatformX11()) { QString errorTitle = i18n("Unsupported platform detected"); QString errorMsg = i18n("Currently only X11 is supported."); showError(errorTitle, errorMsg); } else if( connectedTablets.value().count() == 0 ) { QString errorTitle = i18n( "No tablet device detected" ); QString errorMsg = i18n( "Please connect a tablet device to continue.\n" "If your device is already connected, it is currently not in the device database." ); showError(errorTitle, errorMsg, true); } else { showConfig(); } } void KCMWacomTabletWidget::onTabletAdded(const QString &tabletId) { addTabletToSelector(tabletId); } void KCMWacomTabletWidget::onTabletRemoved(const QString &tabletId) { Q_D( KCMWacomTabletWidget ); int index = d->ui.tabletListSelector->findData(tabletId); if(index >= 0) { d->ui.tabletListSelector->removeItem(index); } } void KCMWacomTabletWidget::onTabletSelectionChanged() { Q_D( KCMWacomTabletWidget ); showSaveChanges(); //tell all widgets to operate on a different tablet now QString tabletId = d->ui.tabletListSelector->itemData(d->ui.tabletListSelector->currentIndex()).toString(); d->generalPage.setTabletId(tabletId); d->stylusPage.setTabletId(tabletId); d->buttonPage.setTabletId(tabletId); d->tabletPage.setTabletId(tabletId); d->touchPage.setTabletId(tabletId); showHideConfig(); } void KCMWacomTabletWidget::addProfile() { bool ok; QString text = QInputDialog::getText( this, i18n( "Add new profile" ), i18n( "Profile name:" ), QLineEdit::Normal, QString(), &ok); if( !ok || text.isEmpty() ) { return; } ProfileManagement::instance().createNewProfile( text ); refreshProfileSelector(text); switchProfile( text ); } void KCMWacomTabletWidget::delProfile() { Q_D( KCMWacomTabletWidget ); ProfileManagement::instance().deleteProfile(); refreshProfileSelector(); switchProfile( d->ui.profileSelector->currentText() ); //update profile rotation selection d->generalPage.reloadWidget(); } void KCMWacomTabletWidget::saveProfile() { Q_D( KCMWacomTabletWidget ); auto &profileManagement = ProfileManagement::instance(); d->generalPage.saveToProfile(); d->stylusPage.saveToProfile(profileManagement); d->buttonPage.saveToProfile(profileManagement); d->tabletPage.saveToProfile(profileManagement); d->touchPage.saveToProfile(profileManagement); d->profileChanged = false; emit changed( false ); applyProfile(); } void KCMWacomTabletWidget::switchProfile( const QString &profile ) { showSaveChanges(); ProfileManagement::instance().setProfileName( profile ); reloadProfile(); applyProfile(); } void KCMWacomTabletWidget::reloadProfile() { Q_D( KCMWacomTabletWidget ); auto &profileManagement = ProfileManagement::instance(); d->generalPage.loadFromProfile(); d->stylusPage.loadFromProfile(profileManagement); d->buttonPage.loadFromProfile(profileManagement); d->tabletPage.loadFromProfile(profileManagement); d->touchPage.loadFromProfile(profileManagement); d->profileChanged = false; emit changed( false ); } void KCMWacomTabletWidget::applyProfile() { Q_D( KCMWacomTabletWidget ); QString tabletId = d->ui.tabletListSelector->itemData(d->ui.tabletListSelector->currentIndex()).toString(); DBusTabletInterface::instance().setProfile( tabletId, ProfileManagement::instance().profileName() ); } void KCMWacomTabletWidget::profileChanged() { Q_D( KCMWacomTabletWidget ); d->profileChanged = true; emit changed( true ); } void KCMWacomTabletWidget::showError(const QString& errorTitle, const QString &errorMsg, bool showTabletFinderButton) { Q_D( KCMWacomTabletWidget ); hideError(); hideConfig(); d->deviceErrorUi.errorTitle->setText(errorTitle); d->deviceErrorUi.errorText->setText (errorMsg); d->ui.verticalLayout->addWidget (&(d->deviceErrorWidget)); d->deviceErrorWidget.setVisible(true); d->deviceErrorUi.buttonRunTabletFinder->setVisible(showTabletFinderButton); } void KCMWacomTabletWidget::hideConfig() { Q_D( KCMWacomTabletWidget ); d->ui.tabletListSelector->setVisible( false ); d->ui.tabletListLabel->setVisible( false ); d->ui.profileSelector->setVisible( false ); d->ui.profileLabel->setVisible( false ); d->ui.addProfileButton->setVisible( false ); d->ui.delProfileButton->setVisible( false ); d->ui.tabletListSelector->setEnabled( false ); d->ui.profileSelector->setEnabled( false ); d->ui.addProfileButton->setEnabled( false ); d->ui.delProfileButton->setEnabled( false ); d->ui.deviceTabWidget->setVisible( false ); } void KCMWacomTabletWidget::hideError() { Q_D( KCMWacomTabletWidget ); d->deviceErrorWidget.setVisible(false); d->ui.verticalLayout->removeWidget (&(d->deviceErrorWidget)); } bool KCMWacomTabletWidget::refreshProfileSelector ( const QString& profile ) { Q_D( KCMWacomTabletWidget ); int index = -1; QStringList profiles = ProfileManagement::instance().availableProfiles(); d->ui.profileSelector->blockSignals( true ); d->ui.profileSelector->clear(); d->ui.profileSelector->addItems( profiles ); if (!profile.isEmpty()) { index = d->ui.profileSelector->findText( profile ); d->ui.profileSelector->setCurrentIndex( index ); } else if (!profiles.isEmpty()) { index = 0; d->ui.profileSelector->setCurrentIndex( index ); } d->ui.profileSelector->blockSignals( false ); return (index >= 0); } void KCMWacomTabletWidget::showConfig() { Q_D( KCMWacomTabletWidget ); // make sure no error message is active hideError(); // reload profile and widget data QString tabletId = d->ui.tabletListSelector->itemData(d->ui.tabletListSelector->currentIndex()).toString(); ProfileManagement::instance().setTabletId(tabletId); ProfileManagement::instance().reload(); d->generalPage.setTabletId(tabletId); d->stylusPage.setTabletId(tabletId); d->buttonPage.setTabletId(tabletId); d->tabletPage.setTabletId(tabletId); QDBusReply touchDeviceName = DBusTabletInterface::instance().getDeviceName(tabletId, DeviceType::Touch.key()); QDBusReply touchSensorId = DBusTabletInterface::instance().getTouchSensorId(tabletId); const bool hasBuiltInTouch = (touchDeviceName.isValid() && !touchDeviceName.value().isEmpty()); const bool hasPairedTouch = (touchSensorId.isValid() && !touchSensorId.value().isEmpty()); if (hasPairedTouch) { d->touchPage.setTabletId(touchSensorId.value()); } else { d->touchPage.setTabletId(tabletId); } d->generalPage.reloadWidget(); d->stylusPage.reloadWidget(); d->buttonPage.reloadWidget(); d->tabletPage.reloadWidget(); d->touchPage.reloadWidget(); //show tablet Selector d->ui.tabletListSelector->setEnabled( true ); d->ui.tabletListLabel->setVisible( true ); d->ui.tabletListSelector->setVisible( true ); // initialize profile selector d->ui.profileSelector->setEnabled( true ); d->ui.addProfileButton->setEnabled( true ); d->ui.delProfileButton->setEnabled( true ); d->ui.profileLabel->setVisible( true ); d->ui.profileSelector->setVisible( true ); d->ui.addProfileButton->setVisible( true ); d->ui.delProfileButton->setVisible( true ); if( ProfileManagement::instance().availableProfiles().isEmpty() ) { ProfileManagement::instance().createNewProfile(i18nc( "Name of the default profile that will be created if none exist.","Default" )); applyProfile(); } refreshProfileSelector(); // initialize configuration tabs d->ui.deviceTabWidget->clear(); - d->ui.deviceTabWidget->addTab( &(d->generalPage), i18nc( "Basic overview page for the tablet hardware", "General" ) ); - d->ui.deviceTabWidget->addTab( &(d->stylusPage), i18n( "Stylus" ) ); + makeScrollableTab(d->ui.deviceTabWidget, d->generalPage, i18nc( "Basic overview page for the tablet hardware", "General" ) ); + makeScrollableTab(d->ui.deviceTabWidget, d->stylusPage, i18n( "Stylus" ) ); QDBusReply hasPadButtons = DBusTabletInterface::instance().hasPadButtons(tabletId); if( hasPadButtons.isValid() && hasPadButtons.value() ) { - d->ui.deviceTabWidget->addTab( &(d->buttonPage), i18n( "Express Buttons" ) ); + makeScrollableTab(d->ui.deviceTabWidget, d->buttonPage, i18n( "Express Buttons" ) ); } - d->ui.deviceTabWidget->addTab( &(d->tabletPage), i18n ("Tablet") ); + makeScrollableTab(d->ui.deviceTabWidget, d->tabletPage, i18n ("Tablet") ); if (hasBuiltInTouch || hasPairedTouch) { - d->ui.deviceTabWidget->addTab( &(d->touchPage), i18n ("Touch") ); + makeScrollableTab(d->ui.deviceTabWidget, d->touchPage, i18n ("Touch") ); } d->ui.deviceTabWidget->setEnabled( true ); d->ui.deviceTabWidget->setVisible( true ); // switch to the currently active profile QDBusReply profile = DBusTabletInterface::instance().getProfile(tabletId); if( profile.isValid() ) { d->ui.profileSelector->setCurrentText( profile ); switchProfile( profile ); } } void KCMWacomTabletWidget::showSaveChanges() { Q_D( KCMWacomTabletWidget ); if (!d->profileChanged) { return; } // TODO: This should be a proper Yes/No/Cancel dialog // but this probably requires custom ComboBoxes for canceling selection if (KMessageBox::questionYesNo(this, i18n("Save changes to the current profile?")) == KMessageBox::Yes) { saveProfile(); } } void KCMWacomTabletWidget::showTabletFinder() { bool success = QProcess::startDetached(QStringLiteral("kde_wacom_tabletfinder")); if (!success) { QString err = i18n("Failed to launch Wacom tablet finder tool. Check your installation."); QMessageBox::warning(QApplication::activeWindow(), QApplication::applicationName(), err); } } void KCMWacomTabletWidget::addTabletToSelector(const QString &tabletId) { Q_D( KCMWacomTabletWidget ); QDBusReply deviceName = DBusTabletInterface::instance().getInformation(tabletId, TabletInfo::TabletName.key()); QDBusReply inputDevices = DBusTabletInterface::instance().getDeviceList(tabletId); QDBusReply isTouchSensor = DBusTabletInterface::instance().isTouchSensor(tabletId); if (isTouchSensor.isValid() && isTouchSensor.value()) { qCDebug(KCM) << "Ignoring tablet" << deviceName << tabletId << "because it's a touch sensor"; return; } qCDebug(KCM) << "Adding tablet" << deviceName << tabletId << "with" << inputDevices.value(); d->ui.tabletListSelector->addItem(QString::fromLatin1("%1 [%2]").arg(deviceName).arg(tabletId),tabletId); } diff --git a/src/kcmodule/tabletpagewidget.ui b/src/kcmodule/tabletpagewidget.ui index 7ef0fa2..c03f2f4 100644 --- a/src/kcmodule/tabletpagewidget.ui +++ b/src/kcmodule/tabletpagewidget.ui @@ -1,417 +1,405 @@ TabletPageWidget 0 0 - 645 - 280 + 790 + 602 - - - Tablet - - - - + + + + + + 0 + 0 + + + + Defines how the cursor movement mode will be used. + + + Stylus Tracking Mode + + - + - + 0 0 - - Defines how the cursor movement mode will be used. + + &Map to Screen (Absolute Mode) - - Stylus Tracking Mode + + true - - - - - - 0 - 0 - - - - Map to Screen (Absolute Mode) - - - true - - - - - - - - 0 - 0 - - - - Map to Cursor (Relative Mode) - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 1 - 5 - - - - - - + - + 0 0 - - Tablet Mapping + + Map &to Cursor (Relative Mode) - - - - - - 0 - 0 - - - - Allows one to specify the tablet area for different screen selections in absolute cursor mode. - - - Map Tablet Area to Screen - - - - - - - - - - 16 - 16 - - - - - 16 - 16 - - - - - - - - - - - Your currently selected mapping can not be applied in relative tracking mode. - - - true - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 1 - 5 - - - - - + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 1 + 5 + + + + - - - + + + + + + + 0 + 0 + + + + Tablet Mapping + + - + - + 0 0 - Changes the orientation of the tablet. + Allows one to specify the tablet area for different screen selections in absolute cursor mode. - - Orientation + + Map Tablet Area to Screen - - - - - - - - If enabled, the tablet rotates together with the screen. - - - Auto-Rotate with Screen - - - - - - - false - - - If enabled the automatic tablet rotation for clockwise and counterclockwise rotations will be inverted. - - - Invert Auto-Rotation - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 1 - 5 - - - - - - - - - 0 - 0 - + + + + + + 16 + 16 + + + + + 16 + 16 + + + + + + + + Your currently selected mapping can not be applied in relative tracking mode. + + + true + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 1 + 5 + + + + + + + + + + + + + + + + 0 + 0 + + + + Changes the orientation of the tablet. + + + Orientation + + + + + + + + + If enabled, the tablet rotates together with the screen. + + + Auto-Rotate with Screen + + + + + + + false + + + If enabled the automatic tablet rotation for clockwise and counterclockwise rotations will be inverted. + + + Invert Auto-Rotation + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 1 + 5 + + + + - - - + + + + + + + 0 + 0 + + + + + Qt::Vertical QSizePolicy::Expanding 1 1 rotateWithScreenCheckBox stateChanged(int) TabletPageWidget onAutoRotateChanged(int) 106 94 203 231 rotateWithScreenInvertCheckBox stateChanged(int) TabletPageWidget onProfileChanged() 106 119 203 231 padMappingTabletButton clicked() TabletPageWidget onTabletMappingClicked() 300 99 203 231 rotatationSelectionComboBox currentIndexChanged(int) TabletPageWidget onProfileChanged() 106 68 203 231 trackAbsoluteRadioButton toggled(bool) TabletPageWidget onTrackingModeAbsolute(bool) 122 69 235 132 trackRelativeRadioButton toggled(bool) TabletPageWidget onTrackingModeRelative(bool) 122 94 235 132 rotatationSelectionComboBox currentIndexChanged(int) TabletPageWidget onRotationChanged() 140 164 271 143 rotateWithScreenCheckBox stateChanged(int) TabletPageWidget onRotationChanged() 140 190 271 143 rotateWithScreenInvertCheckBox stateChanged(int) TabletPageWidget onRotationChanged() 140 215 271 143 onAutoRotateChanged(int) onTabletMappingClicked() onProfileChanged() onTrackingModeAbsolute(bool) onTrackingModeRelative(bool) onRotationChanged() diff --git a/src/kcmodule/touchpagewidget.cpp b/src/kcmodule/touchpagewidget.cpp index aaf9a88..ffe748b 100644 --- a/src/kcmodule/touchpagewidget.cpp +++ b/src/kcmodule/touchpagewidget.cpp @@ -1,391 +1,390 @@ /* * This file is part of the KDE wacomtablet project. For copyright * information and license terms see the AUTHORS and COPYING files * in the top-level directory of this distribution. * * 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 . */ #include "touchpagewidget.h" #include "ui_touchpagewidget.h" #include "dbustabletinterface.h" #include "deviceprofile.h" #include "profilemanagement.h" #include "property.h" #include "stringutils.h" #include "tabletareaselectiondialog.h" -#include "x11info.h" #include "x11wacom.h" #include #include using namespace Wacom; TouchPageWidget::TouchPageWidget(QWidget* parent) : QWidget(parent) , ui(new Ui::TouchPageWidget) { setupUi(); } TouchPageWidget::~TouchPageWidget() { delete ui; } void TouchPageWidget::setTabletId(const QString &tabletId) { _tabletId = tabletId; } void TouchPageWidget::loadFromProfile(ProfileManagementInterface &profileManagement) { DeviceProfile touchProfile = profileManagement.loadDeviceProfile( DeviceType::Touch ); // set all properties no matter if the tablet supports that device // to get all widgets properly initialized. setTouchSupportEnabled( touchProfile.getPropertyAsBool( Property::Touch ) ); setTrackingMode( touchProfile.getProperty( Property::Mode ) ); setScreenSpace( touchProfile.getProperty( Property::ScreenSpace ) ); setScreenMap( touchProfile.getProperty( Property::ScreenMap ) ); setGesturesSupportEnabled( touchProfile.getPropertyAsBool( Property::Gesture ) ); setScrollDistance( touchProfile.getProperty( Property::ScrollDistance ) ); setScrollInversion( touchProfile.getProperty( Property::InvertScroll) ); setZoomDistance( touchProfile.getProperty( Property::ZoomDistance ) ); setTapTime( touchProfile.getProperty( Property::TapTime ) ); } void TouchPageWidget::reloadWidget() { // get all tablet device names we need QDBusReply touchDeviceNameReply = DBusTabletInterface::instance().getDeviceName(_tabletId, DeviceType::Touch.key()); // update name and maximum tablet area for all devices _touchDeviceName.clear(); _tabletGeometry = TabletArea(); _screenMap = ScreenMap(); if (touchDeviceNameReply.isValid()) { _touchDeviceName = touchDeviceNameReply.value(); if (!_touchDeviceName.isEmpty()) { // touch device available _tabletGeometry = X11Wacom::getMaximumTabletArea(touchDeviceNameReply.value()); _screenMap = ScreenMap(_tabletGeometry); } } } void TouchPageWidget::saveToProfile(ProfileManagementInterface &profileManagement) { if (_touchDeviceName.isEmpty()) { return; // no touch device available } DeviceProfile touchProfile = profileManagement.loadDeviceProfile( DeviceType::Touch ); touchProfile.setProperty ( Property::Touch, getTouchSupportEnabled() ); touchProfile.setProperty ( Property::Mode, getTrackingMode() ); touchProfile.setProperty ( Property::ScreenSpace, getScreenSpaceAsString() ); touchProfile.setProperty ( Property::ScreenMap, getScreenMapAsString() ); touchProfile.setProperty ( Property::Gesture, getGestureSupportEnabled() ); touchProfile.setProperty ( Property::ScrollDistance, getScrollDistance() ); touchProfile.setProperty ( Property::InvertScroll, getScrollInversion() ); touchProfile.setProperty ( Property::ZoomDistance, getZoomDistance() ); touchProfile.setProperty ( Property::TapTime, getTapTime() ); touchProfile.setProperty ( Property::Rotate, _tabletRotation.key() ); profileManagement.saveDeviceProfile(touchProfile); } void TouchPageWidget::onGesturesModeChanged(int state) { setGesturesSupportEnabled(state == Qt::Checked); onProfileChanged(); } void TouchPageWidget::onProfileChanged() { emit changed(); } void TouchPageWidget::onRotationChanged(const ScreenRotation& rotation) { _tabletRotation = rotation; } void TouchPageWidget::onTabletMappingClicked() { TabletAreaSelectionDialog selectionDialog; selectionDialog.setupWidget( getScreenMap(), _touchDeviceName, _tabletRotation); selectionDialog.select( getScreenSpace() ); if (selectionDialog.exec() == QDialog::Accepted) { setScreenMap(selectionDialog.getScreenMap()); setScreenSpace(selectionDialog.getScreenSpace()); onProfileChanged(); } } void TouchPageWidget::onTouchModeChanged(int state) { setTouchSupportEnabled(state == Qt::Checked); onProfileChanged(); } void TouchPageWidget::onTrackingModeAbsolute(bool activated) { if (!activated) { return; } setTrackingMode(QLatin1String("absolute")); onProfileChanged(); } void TouchPageWidget::onTrackingModeRelative(bool activated) { if (!activated) { return; } setTrackingMode(QLatin1String("relative")); onProfileChanged(); } const QString TouchPageWidget::getGestureSupportEnabled() const { return (isGesturesSupportEnabled() ? QLatin1String("on") : QLatin1String("off")); } const ScreenMap& TouchPageWidget::getScreenMap() const { return _screenMap; } const QString TouchPageWidget::getScreenMapAsString() const { return getScreenMap().toString(); } const ScreenSpace& TouchPageWidget::getScreenSpace() const { return _screenSpace; } const QString TouchPageWidget::getScreenSpaceAsString() const { return getScreenSpace().toString(); } const QString TouchPageWidget::getScrollDistance() const { return QString::number(ui->scrollDistanceSpinBox->value()); } const QString TouchPageWidget::getScrollInversion() const { return (ui->scrollInversionCheckBox->isChecked() ? QLatin1String("on") : QLatin1String("off")); } const QString TouchPageWidget::getTapTime() const { return QString::number(ui->tapTimeSpinBox->value()); } const QString TouchPageWidget::getTouchSupportEnabled() const { return (isTouchSupportEnabled() ? QLatin1String("on") : QLatin1String("off")); } const QString TouchPageWidget::getTrackingMode() const { if (ui->trackAbsoluteRadioButton->isChecked()) { return QLatin1String("absolute"); } return QLatin1String("relative"); } const QString TouchPageWidget::getZoomDistance() const { return QString::number(ui->zoomDistanceSpinBox->value()); } bool TouchPageWidget::isGesturesSupportEnabled() const { - return (ui->gesturesCheckBox->isChecked() && ui->touchGroupBox->isEnabled()); + return ui->gesturesCheckBox->isChecked(); } bool TouchPageWidget::isTouchSupportEnabled() const { - return (ui->touchCheckBox->isChecked() && ui->touchGroupBox->isEnabled()); + return ui->touchCheckBox->isChecked(); } void TouchPageWidget::setGesturesSupportEnabled(bool value) { ui->gesturesGroupBox->setEnabled(value); ui->gesturesCheckBox->blockSignals(true); ui->gesturesCheckBox->setChecked(value); ui->gesturesCheckBox->blockSignals(false); } void TouchPageWidget::setScreenMap(const ScreenMap &screenMap) { _screenMap = screenMap; assertValidTabletMapping(); } void TouchPageWidget::setScreenMap(const QString& value) { setScreenMap(ScreenMap(value)); } void TouchPageWidget::setScreenSpace(const ScreenSpace& screenSpace) { _screenSpace = screenSpace; assertValidTabletMapping(); } void TouchPageWidget::setScreenSpace(const QString& value) { setScreenSpace(ScreenSpace(value)); } void TouchPageWidget::setScrollDistance(const QString& value) { ui->scrollDistanceSpinBox->blockSignals(true); ui->scrollDistanceSpinBox->setValue(value.toInt()); ui->scrollDistanceSpinBox->blockSignals(false); } void TouchPageWidget::setScrollInversion(const QString& value) { ui->scrollInversionCheckBox->blockSignals(true); ui->scrollInversionCheckBox->setChecked(StringUtils::asBool(value)); ui->scrollInversionCheckBox->blockSignals(false); } void TouchPageWidget::setTouchSupportEnabled(bool value) { ui->trackingModeGroupBox->setEnabled(value); ui->touchMappingGroupBox->setEnabled(value); ui->gesturesCheckBox->setEnabled(value); if (isGesturesSupportEnabled()) { ui->gesturesGroupBox->setEnabled(value); } ui->touchCheckBox->blockSignals(true); ui->touchCheckBox->setChecked(value); ui->touchCheckBox->blockSignals(false); } void TouchPageWidget::setTapTime(const QString& value) { ui->tapTimeSpinBox->blockSignals(true); ui->tapTimeSpinBox->setValue(value.toInt()); ui->tapTimeSpinBox->blockSignals(false); } void TouchPageWidget::setTrackingMode(const QString& value) { ui->trackAbsoluteRadioButton->blockSignals(true); ui->trackRelativeRadioButton->blockSignals(true); if (value.contains(QLatin1String("absolute"), Qt::CaseInsensitive)) { ui->trackAbsoluteRadioButton->setChecked(true); ui->trackRelativeRadioButton->setChecked(false); } else { ui->trackAbsoluteRadioButton->setChecked(false); ui->trackRelativeRadioButton->setChecked(true); } ui->trackAbsoluteRadioButton->blockSignals(false); ui->trackRelativeRadioButton->blockSignals(false); assertValidTabletMapping(); } void TouchPageWidget::setZoomDistance(const QString& value) { ui->zoomDistanceSpinBox->blockSignals(true); ui->zoomDistanceSpinBox->setValue(value.toInt()); ui->zoomDistanceSpinBox->blockSignals(false); } void TouchPageWidget::assertValidTabletMapping() { bool isWarningVisible = false; if (ui->trackRelativeRadioButton->isChecked()) { // Relative mode is selected. In relative mode a // device can not be mapped to a single monitor ScreenSpace screenSpace = getScreenSpace(); if (screenSpace.isMonitor()) { isWarningVisible = true; } } ui->trackingWarningIcon->setVisible(isWarningVisible); ui->trackingWarningLabel->setVisible(isWarningVisible); } void TouchPageWidget::setupUi() { ui->setupUi(this); // init screen mapping warning ui->trackingWarningIcon->setPixmap(QIcon::fromTheme(QLatin1String("dialog-warning")).pixmap(QSize(16,16))); ui->trackingWarningIcon->setVisible(false); ui->trackingWarningLabel->setVisible(false); } diff --git a/src/kcmodule/touchpagewidget.ui b/src/kcmodule/touchpagewidget.ui index 13d25a2..9b5f8df 100644 --- a/src/kcmodule/touchpagewidget.ui +++ b/src/kcmodule/touchpagewidget.ui @@ -1,529 +1,520 @@ TouchPageWidget 0 0 663 - 349 + 418 - - - Touch + + + If enabled the tablet will emit touch events. - - - - - If enabled the tablet will emit touch events. - - - Enable Touch - - - - - + + Enable Touch + + + + + + + + + false + + + + 0 + 0 + + + + Defines how the cursor movement mode will be used. + + + Touch Tracking Mode + + - - - false + + + + 0 + 0 + + + + &Map to Screen (Absolute Mode) + + true + + + + + - + 0 0 - - Defines how the cursor movement mode will be used. - - - Touch Tracking Mode - - - - - - - 0 - 0 - - - - Map to Screen (Absolute Mode) - - - true - - - - - - - - 0 - 0 - - - - Map to Cursor (Relative Mode) - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 1 - 5 - - - - - + + Map &to Cursor (Relative Mode) + - - - false + + + Qt::Vertical + + QSizePolicy::MinimumExpanding + + + + 1 + 5 + + + + + + + + + + + false + + + + 0 + 0 + + + + Touch Mapping + + + + - + 0 0 - - Touch Mapping - - - - - - - 0 - 0 - - - - Allows one to specify the tablet area for different screen selections in absolute cursor mode. - - - Map Touch Area to Screen - - - - - - - - - - 16 - 16 - - - - - 16 - 16 - - - - - - - - - - - Your currently selected mapping can not be applied in relative tracking mode. - - - true - - - - - - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 1 - 5 - - - - - + + Allows one to specify the tablet area for different screen selections in absolute cursor mode. + + + Map Touch Area to Screen + - - - - - - false - - - If enabled the touch events can recognize gestures. - - - Enable Gestures - - - - - - - - false + + + + + + 16 + 16 + + + + + 16 + 16 + + + + + + + + + + + Your currently selected mapping can not be applied in relative tracking mode. + + + true + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + 1 + 5 + + + + + + + + + + + + + false + + + If enabled the touch events can recognize gestures. + + + Enable Gestures + + + + + + + + + false + + + + 0 + 0 + + + + Gestures + + + + - + 0 0 - - Gestures - - - - - - - 0 - 0 - - - - Minimum motion before sending a scroll gesture. - - - Scroll Distance - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - The minimum motion in tablet units before sending a scroll event. - - - 1000 - - - 10 - - - - - - - - 0 - 0 - - - - Minimum distance for a zoom gesture is recognized. - - - Zoom Distance - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - The minimum distance in tablet units for a zoom gesture to be recognized. - - - 1000 - - - 10 - - - - - - - - 0 - 0 - - - - Minimum time between taps for a right click. - - - Tap Time - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - The minimum time in milliseconds between taps to trigger a right click. - - - 1000 - - - 10 - - - - - - - Invert Scroll Direction - - - - - - - If selected, the scroll direction for the scroll gesture is inverted. - - - - - - - + + Minimum motion before sending a scroll gesture. + + + Scroll Distance + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + - - + + - + 0 0 + + The minimum motion in tablet units before sending a scroll event. + + + 1000 + + + 10 + + + + + + + + 0 + 0 + + + + Minimum distance for a zoom gesture is recognized. + + + Zoom Distance + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + The minimum distance in tablet units for a zoom gesture to be recognized. + + + 1000 + + + 10 + + + + + + + + 0 + 0 + + + + Minimum time between taps for a right click. + + + Tap Time + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + The minimum time in milliseconds between taps to trigger a right click. + + + 1000 + + + 10 + + + + + + + Invert Scroll Direction + + + + + + + If selected, the scroll direction for the scroll gesture is inverted. + + + + - - - + + + + + + + 0 + 0 + + + + + Qt::Vertical QSizePolicy::Expanding 1 1 touchCheckBox stateChanged(int) TouchPageWidget onTouchModeChanged(int) 203 194 203 231 trackAbsoluteRadioButton toggled(bool) TouchPageWidget onTrackingModeAbsolute(bool) 109 247 203 231 trackRelativeRadioButton toggled(bool) TouchPageWidget onTrackingModeRelative(bool) 109 272 203 231 touchMappingTabletButton clicked() TouchPageWidget onTabletMappingClicked() 302 278 203 231 scrollDistanceSpinBox valueChanged(int) TouchPageWidget onProfileChanged() 120 375 203 231 zoomDistanceSpinBox valueChanged(int) TouchPageWidget onProfileChanged() 120 401 203 231 tapTimeSpinBox valueChanged(int) TouchPageWidget onProfileChanged() 120 427 203 231 gesturesCheckBox stateChanged(int) TouchPageWidget onGesturesModeChanged(int) 203 322 203 231 scrollInversionCheckBox toggled(bool) TouchPageWidget onProfileChanged() 143 214 271 167 onTouchModeChanged(int) onGesturesModeChanged(int) onProfileChanged() onTabletMappingClicked() onTrackingModeAbsolute(bool) onTrackingModeRelative(bool)