diff --git a/src/kcmodule/CMakeLists.txt b/src/kcmodule/CMakeLists.txt
index a056a00..02c66e1 100644
--- a/src/kcmodule/CMakeLists.txt
+++ b/src/kcmodule/CMakeLists.txt
@@ -1,81 +1,80 @@
########### next target ###############
set( kcm_tablet_SRCS
areaselectionwidget.cpp
buttonactiondisplaywidget.cpp
buttonactionselectiondialog.cpp
buttonactionselectionwidget.cpp
buttonactionselectorwidget.cpp
buttonpagewidget.cpp
calibrationdialog.cpp
generalpagewidget.cpp
kcmwacomtabletwidget.cpp
keysequenceinputbutton.cpp
keysequenceinputwidget.cpp
pressurecurvewidget.cpp
pressurecurvedialog.cpp
styluspagewidget.cpp
tabletareaselectioncontroller.cpp
tabletareaselectiondialog.cpp
tabletareaselectionview.cpp
tabletareaselectionwidget.cpp
tabletpagewidget.cpp
touchpagewidget.cpp
../common/globalactions.cpp # FIXME: why?
)
ki18n_wrap_ui( kcm_tablet_SRCS
buttonactionselectionwidget.ui
buttonactionselectorwidget.ui
buttonpagewidget.ui
errorwidget.ui
generalpagewidget.ui
kcmwacomtabletwidget.ui
pressurecurvedialog.ui
- saveprofile.ui
styluspagewidget.ui
tabletareaselectionview.ui
tabletpagewidget.ui
touchpagewidget.ui
)
ecm_qt_declare_logging_category(
kcm_tablet_SRCS
HEADER "logging.h"
IDENTIFIER "KCM"
CATEGORY_NAME "org.kde.wacomtablet.kcm")
set(kcm_wacomtablet_PLUGIN_SRC
kcmwacomtablet.cpp
)
set(kcm_wacomtablet_LIBS
wacom_common
Qt5::Core
Qt5::Widgets
Qt5::X11Extras
KF5::CoreAddons
KF5::XmlGui
KF5::WidgetsAddons
KF5::WindowSystem
${X11_LIBRARIES}
${X11_Xinput_LIB}
)
add_definitions(-DTRANSLATION_DOMAIN=\"wacomtablet\")
add_library(kcm_wacomtablet MODULE ${kcm_wacomtablet_PLUGIN_SRC} ${kcm_tablet_SRCS})
target_link_libraries(kcm_wacomtablet ${kcm_wacomtablet_LIBS})
install(TARGETS kcm_wacomtablet DESTINATION ${KDE_INSTALL_PLUGINDIR})
install(FILES kcm_wacomtablet.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
install(FILES org.kde.wacomtablet.metainfo.xml DESTINATION "${KDE_INSTALL_METAINFODIR}")
## LIBRARY FOR UNIT TESTS
if (BUILD_TESTING)
## build static library for unit testing
add_library( kcm_testlib STATIC ${kcm_tablet_SRCS} )
target_link_libraries( kcm_testlib ${kcm_wacomtablet_LIBS} )
set_target_properties( kcm_testlib PROPERTIES COMPILE_FLAGS "-fPIC" )
endif (BUILD_TESTING)
diff --git a/src/kcmodule/kcmwacomtabletwidget.cpp b/src/kcmodule/kcmwacomtabletwidget.cpp
index 0e1999f..f12a934 100644
--- a/src/kcmodule/kcmwacomtabletwidget.cpp
+++ b/src/kcmodule/kcmwacomtabletwidget.cpp
@@ -1,517 +1,501 @@
/*
* 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_saveprofile.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
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
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" ) );
QDBusReply hasPadButtons = DBusTabletInterface::instance().hasPadButtons(tabletId);
if( hasPadButtons.isValid() && hasPadButtons.value() ) {
d->ui.deviceTabWidget->addTab( &(d->buttonPage), i18n( "Express Buttons" ) );
}
d->ui.deviceTabWidget->addTab( &(d->tabletPage), i18n ("Tablet") );
if (hasBuiltInTouch || hasPairedTouch) {
d->ui.deviceTabWidget->addTab( &(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 ) {
- QPointer saveDialog = new QDialog();
- QWidget* widget = new QWidget( this );
-
- Ui::SaveProfile askToSave;
- askToSave.setupUi( widget );
-
- QVBoxLayout* layout = new QVBoxLayout;
- QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Apply | QDialogButtonBox::Cancel);
- layout->addWidget( widget );
- layout->addWidget( buttonBox);
-
- connect( buttonBox, &QDialogButtonBox::clicked, [saveDialog, buttonBox](QAbstractButton* button) {
- auto standardButton = buttonBox->standardButton(button);
- if (standardButton == QDialogButtonBox::Apply) {
- saveDialog->accept();
- } else { // Cancel
- saveDialog->reject();
- }
- });
-
- if( saveDialog->exec() == QDialog::Accepted ) {
- saveProfile();
- }
+ if (!d->profileChanged) {
+ return;
+ }
- delete saveDialog;
+ // 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/saveprofile.ui b/src/kcmodule/saveprofile.ui
deleted file mode 100644
index 5765fad..0000000
--- a/src/kcmodule/saveprofile.ui
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- SaveProfile
-
-
-
- 0
- 0
- 400
- 21
-
-
-
- -
-
-
- Save changes to the current profile?
-
-
-
-
-
-
-
-