diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d72090..95a7781 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ set(WIDGETS_UI_FILES set(CMAKE_MODULE_FILES cmake/modules/QtConfig.cmake cmake/modules/QtGuiConfig.cmake + cmake/modules/QtLinkage.cmake cmake/modules/JsProviderConfig.cmake cmake/modules/WebViewProviderConfig.cmake ) diff --git a/aboutdialog/aboutdialog.cpp b/aboutdialog/aboutdialog.cpp index c9ba1d9..f0d647f 100644 --- a/aboutdialog/aboutdialog.cpp +++ b/aboutdialog/aboutdialog.cpp @@ -1,76 +1,76 @@ -#include "./aboutdialog.h" -#include "../misc/dialogutils.h" - -#include "ui_aboutdialog.h" - -#include -#include -#include -#include - -/*! - \namespace Dialogs - \brief Provides common dialogs such as AboutDialog, EnterPasswordDialog and SettingsDialog. -*/ - -namespace Dialogs { - -/*! - * \class Dialogs::AboutDialog - * \brief The AboutDialog class provides a simple about dialog. - */ - -/*! - * \brief Constructs an about dialog with the provided information. - * \param parent Specifies the parent widget. - * \param applicationName Specifies the name of the application. If empty, QApplication::applicationName() will be used. - * \param creator Specifies the creator of the application. If empty, QApplication::organizationName() will be used. - * \param version Specifies the version of the application. If empty, QApplication::applicationVersion() will be used. - * \param description Specifies a short description about the application. - * \param website Specifies the URL to the website of the application. If empty, QApplication::organizationDomain() will be used. - * \param image Specifies the application icon. If the image is null, the standard information icon will be used. - */ -AboutDialog::AboutDialog(QWidget *parent, const QString &applicationName, const QString &creator, const QString &version, const QString &website, const QString &description, const QImage &image) : - QDialog(parent), - m_ui(new Ui::AboutDialog) -{ - m_ui->setupUi(this); - makeHeading(m_ui->productNameLabel); - setStyleSheet(dialogStyle()); - setWindowFlags(Qt::Tool); - if(!applicationName.isEmpty()) { - m_ui->productNameLabel->setText(applicationName); - } else if(!QApplication::applicationDisplayName().isEmpty()) { - m_ui->productNameLabel->setText(QApplication::applicationDisplayName()); - } else { - m_ui->productNameLabel->setText(QApplication::applicationName()); - } - m_ui->creatorLabel->setText(tr("developed by %1").arg( - creator.isEmpty() ? QApplication::organizationName() : creator)); - m_ui->versionLabel->setText(version.isEmpty() ? QApplication::applicationVersion() : version); - m_ui->websiteLabel->setText(tr("For updates and bug reports visit the project website.").arg( - website.isEmpty() ? QApplication::organizationDomain() : website)); - m_ui->descLabel->setText(description); - m_iconScene = new QGraphicsScene(this); - auto *item = image.isNull() - ? new QGraphicsPixmapItem(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation, nullptr, this).pixmap(128)) - : new QGraphicsPixmapItem(QPixmap::fromImage(image)); - m_iconScene->addItem(item); - m_ui->graphicsView->setScene(m_iconScene); - setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, size(), parentWidget() ? parentWidget()->geometry() : QApplication::desktop()->availableGeometry())); -} - -/*! - * \brief Constructs an about dialog with the specified \a parent, \a description and \a image. - */ -AboutDialog::AboutDialog(QWidget *parent, const QString &description, const QImage &image) : - AboutDialog(parent, QString(), QString(), QString(), QString(), description, image) -{} - -/*! - * \brief Destroys the about dialog. - */ -AboutDialog::~AboutDialog() -{} - -} +#include "./aboutdialog.h" +#include "../misc/dialogutils.h" + +#include "ui_aboutdialog.h" + +#include +#include +#include +#include + +/*! + \namespace Dialogs + \brief Provides common dialogs such as AboutDialog, EnterPasswordDialog and SettingsDialog. +*/ + +namespace Dialogs { + +/*! + * \class Dialogs::AboutDialog + * \brief The AboutDialog class provides a simple about dialog. + */ + +/*! + * \brief Constructs an about dialog with the provided information. + * \param parent Specifies the parent widget. + * \param applicationName Specifies the name of the application. If empty, QApplication::applicationName() will be used. + * \param creator Specifies the creator of the application. If empty, QApplication::organizationName() will be used. + * \param version Specifies the version of the application. If empty, QApplication::applicationVersion() will be used. + * \param description Specifies a short description about the application. + * \param website Specifies the URL to the website of the application. If empty, QApplication::organizationDomain() will be used. + * \param image Specifies the application icon. If the image is null, the standard information icon will be used. + */ +AboutDialog::AboutDialog(QWidget *parent, const QString &applicationName, const QString &creator, const QString &version, const QString &website, const QString &description, const QImage &image) : + QDialog(parent), + m_ui(new Ui::AboutDialog) +{ + m_ui->setupUi(this); + makeHeading(m_ui->productNameLabel); + setStyleSheet(dialogStyle()); + setWindowFlags(Qt::Tool); + if(!applicationName.isEmpty()) { + m_ui->productNameLabel->setText(applicationName); + } else if(!QApplication::applicationDisplayName().isEmpty()) { + m_ui->productNameLabel->setText(QApplication::applicationDisplayName()); + } else { + m_ui->productNameLabel->setText(QApplication::applicationName()); + } + m_ui->creatorLabel->setText(tr("developed by %1").arg( + creator.isEmpty() ? QApplication::organizationName() : creator)); + m_ui->versionLabel->setText(version.isEmpty() ? QApplication::applicationVersion() : version); + m_ui->websiteLabel->setText(tr("For updates and bug reports visit the project website.").arg( + website.isEmpty() ? QApplication::organizationDomain() : website)); + m_ui->descLabel->setText(description); + m_iconScene = new QGraphicsScene(this); + auto *item = image.isNull() + ? new QGraphicsPixmapItem(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation, nullptr, this).pixmap(128)) + : new QGraphicsPixmapItem(QPixmap::fromImage(image)); + m_iconScene->addItem(item); + m_ui->graphicsView->setScene(m_iconScene); + setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, size(), parentWidget() ? parentWidget()->geometry() : QApplication::desktop()->availableGeometry())); +} + +/*! + * \brief Constructs an about dialog with the specified \a parent, \a description and \a image. + */ +AboutDialog::AboutDialog(QWidget *parent, const QString &description, const QImage &image) : + AboutDialog(parent, QString(), QString(), QString(), QString(), description, image) +{} + +/*! + * \brief Destroys the about dialog. + */ +AboutDialog::~AboutDialog() +{} + +} diff --git a/aboutdialog/aboutdialog.h b/aboutdialog/aboutdialog.h index 05dd8a5..684d203 100644 --- a/aboutdialog/aboutdialog.h +++ b/aboutdialog/aboutdialog.h @@ -1,34 +1,34 @@ -#ifndef DIALOGS_ABOUTDIALOG_H -#define DIALOGS_ABOUTDIALOG_H - -#include - -#include - -#include - -QT_FORWARD_DECLARE_CLASS(QGraphicsScene) - -namespace Dialogs { - -namespace Ui { -class AboutDialog; -} - -class LIB_EXPORT AboutDialog : public QDialog -{ - Q_OBJECT - -public: - explicit AboutDialog(QWidget *parent, const QString &applicationName, const QString &creator, const QString &version, const QString &website = QString(), const QString &description = QString(), const QImage &image = QImage()); - explicit AboutDialog(QWidget *parent, const QString &description = QString(), const QImage &image = QImage()); - ~AboutDialog(); - -private: - std::unique_ptr m_ui; - QGraphicsScene *m_iconScene; -}; - -} - -#endif // DIALOGS_ABOUTDIALOG_H +#ifndef DIALOGS_ABOUTDIALOG_H +#define DIALOGS_ABOUTDIALOG_H + +#include "../global.h" + +#include + +#include + +QT_FORWARD_DECLARE_CLASS(QGraphicsScene) + +namespace Dialogs { + +namespace Ui { +class AboutDialog; +} + +class QT_UTILITIES_EXPORT AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent, const QString &applicationName, const QString &creator, const QString &version, const QString &website = QString(), const QString &description = QString(), const QImage &image = QImage()); + explicit AboutDialog(QWidget *parent, const QString &description = QString(), const QImage &image = QImage()); + ~AboutDialog(); + +private: + std::unique_ptr m_ui; + QGraphicsScene *m_iconScene; +}; + +} + +#endif // DIALOGS_ABOUTDIALOG_H diff --git a/cmake/modules/JsProviderConfig.cmake b/cmake/modules/JsProviderConfig.cmake index 12a1baf..a772501 100644 --- a/cmake/modules/JsProviderConfig.cmake +++ b/cmake/modules/JsProviderConfig.cmake @@ -1,5 +1,7 @@ # determines the JavaScript provider (either Qt Script or Qt Declarative) +include(QtLinkage) + set(JS_PROVIDER "auto" CACHE STRING "specifies the JavaScript provider: auto (default), qml, script or none") if(${JS_PROVIDER} STREQUAL "auto") find_package(Qt5Script) diff --git a/cmake/modules/QtConfig.cmake b/cmake/modules/QtConfig.cmake index 99b328d..424ca49 100644 --- a/cmake/modules/QtConfig.cmake +++ b/cmake/modules/QtConfig.cmake @@ -21,21 +21,7 @@ if(DBUS_FILES) list(APPEND QT_MODULES DBus) endif() -# determine Qt linkage -set(QT_LINKAGE "AUTO_LINKAGE") -if(BUILD_STATIC_LIBS AND BUILD_SHARED_LIBS) - message(FATAL_ERROR "When using Qt/KDE modules it is not possible to build shared and static libraries at the same time.") -endif() -# set USE_STATIC_QT_BUILD variable to ON to use static Qt -# this only works with patched mingw-w64-qt5-* packages found in my PKGBUILDs repository -# in any other environment you must ensure that the available Qt version is in accordance with the specified STATIC_LINKAGE/STATIC_LIBRARY_LINKAGE options -if(BUILD_STATIC_LIBS OR ("${QT_LINKAGE}" STREQUAL "AUTO_LINKAGE" AND ((STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") OR (STATIC_LIBRARY_LINKAGE AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) OR ("${QT_LINKAGE}" STREQUAL "STATIC")) - set(USE_STATIC_QT_BUILD ON) - message(STATUS "Linking ${META_PROJECT_NAME} statically against Qt 5.") -elseif(("${QT_LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${QT_LINKAGE}" STREQUAL "SHARED")) - set(USE_STATIC_QT_BUILD OFF) - message(STATUS "Linking ${META_PROJECT_NAME} dynamically against Qt 5.") -endif() +include(QtLinkage) # actually find the required Qt/KF modules foreach(QT_MODULE ${QT_MODULES}) diff --git a/cmake/modules/QtLinkage.cmake b/cmake/modules/QtLinkage.cmake new file mode 100644 index 0000000..50131e1 --- /dev/null +++ b/cmake/modules/QtLinkage.cmake @@ -0,0 +1,21 @@ +# determines the Qt linkage + +if(NOT DEFINED QT_LINKAGE_DETERMINED) + set(QT_LINKAGE_DETERMINED true) + + set(QT_LINKAGE "AUTO_LINKAGE") + if(BUILD_STATIC_LIBS AND BUILD_SHARED_LIBS) + message(FATAL_ERROR "When using Qt/KDE modules it is not possible to build shared and static libraries at the same time.") + endif() + # set USE_STATIC_QT_BUILD variable to ON to use static Qt + # this only works with patched mingw-w64-qt5-* packages found in my PKGBUILDs repository + # in any other environment you must ensure that the available Qt version is in accordance with the specified STATIC_LINKAGE/STATIC_LIBRARY_LINKAGE options + if(BUILD_STATIC_LIBS OR ("${QT_LINKAGE}" STREQUAL "AUTO_LINKAGE" AND ((STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") OR (STATIC_LIBRARY_LINKAGE AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) OR ("${QT_LINKAGE}" STREQUAL "STATIC")) + set(USE_STATIC_QT_BUILD ON) + message(STATUS "Linking ${META_PROJECT_NAME} statically against Qt 5.") + elseif(("${QT_LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${QT_LINKAGE}" STREQUAL "SHARED")) + set(USE_STATIC_QT_BUILD OFF) + message(STATUS "Linking ${META_PROJECT_NAME} dynamically against Qt 5.") + endif() + +endif(NOT DEFINED QT_LINKAGE_DETERMINED) diff --git a/cmake/modules/WebViewProviderConfig.cmake b/cmake/modules/WebViewProviderConfig.cmake index c0b2a65..8ec1de9 100644 --- a/cmake/modules/WebViewProviderConfig.cmake +++ b/cmake/modules/WebViewProviderConfig.cmake @@ -1,5 +1,7 @@ # determines the web view provider (either Qt WebKit or Qt WebEngine) +include(QtLinkage) + set(WEBVIEW_PROVIDER "auto" CACHE STRING "specifies the web view provider: auto (default), webkit, webengine or none") if(${WEBVIEW_PROVIDER} STREQUAL "auto") find_package(Qt5WebKitWidgets) diff --git a/enterpassworddialog/enterpassworddialog.cpp b/enterpassworddialog/enterpassworddialog.cpp index 608985c..45422e7 100644 --- a/enterpassworddialog/enterpassworddialog.cpp +++ b/enterpassworddialog/enterpassworddialog.cpp @@ -1,332 +1,332 @@ -#include "./enterpassworddialog.h" -#include "../misc/dialogutils.h" - -#include "ui_enterpassworddialog.h" - -#include -#include -#include -#include -#include - -#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION -# if defined(Q_OS_WIN32) -# include -# elif defined(X_AVAILABLE) -# include -# undef KeyPress -# undef KeyRelease -# undef FocusIn -# undef FocusOut -# endif -#endif - -namespace Dialogs { - -/*! - * \class Dialogs::EnterPasswordDialog - * \brief The EnterPasswordDialog class provides a simple dialog to ask the user for a password. - */ - -/*! - * \brief Constructs a password dialog. - * \param parent Specifies the parent widget. - */ -EnterPasswordDialog::EnterPasswordDialog(QWidget *parent) : - QDialog(parent), - m_ui(new Ui::EnterPasswordDialog) -{ - // setup ui - m_ui->setupUi(this); - makeHeading(m_ui->instructionLabel); - setStyleSheet(dialogStyle()); - setDescription(); - setPromptForUserName(false); - setVerificationRequired(false); - setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); - installEventFilter(this); - m_ui->userNameLineEdit->installEventFilter(this); - m_ui->password1LineEdit->installEventFilter(this); - m_ui->password2LineEdit->installEventFilter(this); - // capslock key detection -#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION - m_capslockPressed = isCapslockPressed(); -#else - m_capslockPressed = false; -#endif - m_ui->capslockWarningWidget->setVisible(m_capslockPressed); - // draw icon to capslock warning graphics view - QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, this); - QGraphicsScene* scene = new QGraphicsScene(); - QGraphicsPixmapItem* item = new QGraphicsPixmapItem(icon.pixmap(16, 16)); - scene->addItem(item); - m_ui->capslockWarningGraphicsView->setScene(scene); - // connect signals and slots - connect(m_ui->showPasswordCheckBox, &QCheckBox::clicked, this, &EnterPasswordDialog::updateShowPassword); - connect(m_ui->noPwCheckBox, &QCheckBox::clicked, this, &EnterPasswordDialog::updateShowPassword); - connect(m_ui->confirmPushButton, &QPushButton::clicked, this, &EnterPasswordDialog::confirm); - connect(m_ui->abortPushButton, &QPushButton::clicked, this, &EnterPasswordDialog::abort); - // grab the keyboard - grabKeyboard(); -} - -/*! - * \brief Destroys the password dialog. - */ -EnterPasswordDialog::~EnterPasswordDialog() -{} - -/*! - * \brief Returns the description. The description is shown under the instruction text. - * \sa setDescription() - */ -QString EnterPasswordDialog::description() const -{ - return m_ui->descLabel->text(); -} - -/*! - * \brief Sets the description. - * \sa description() - */ -void EnterPasswordDialog::setDescription(const QString &description) -{ - m_ui->descLabel->setText(description); - m_ui->descLabel->setHidden(description.isEmpty()); - adjustSize(); -} - -/*! - * \brief Returns whether the dialogs prompts for a user name as well. - * - * The dialog does not prompt for a user name by default. - * - * \sa setPromptForUserName() - */ -bool EnterPasswordDialog::promtForUserName() const -{ - return !m_ui->userNameLineEdit->isHidden(); -} - -/*! - * \brief Sets whethere the dialog prompts for a user name as well. - * \sa promptForUserName() - */ -void EnterPasswordDialog::setPromptForUserName(bool prompt) -{ - m_ui->userNameLineEdit->setHidden(!prompt); - adjustSize(); -} - -/*! - * \brief Returns an indication whether a verification (password has to be entered twice) is required. - * - * \sa EnterPasswordDialog::setVerificationRequired() - */ -bool EnterPasswordDialog::isVerificationRequired() const -{ - return !m_ui->password2LineEdit->isHidden(); -} - -/*! - * \brief Returns an indication whether the user is force to enter a password. - * - * If no password is required, the user is allowed to skip the dialog without entering - * a password. - * - * \sa EnterPasswordDialog::setPasswordRequired() - */ -bool EnterPasswordDialog::isPasswordRequired() const -{ - return m_ui->noPwCheckBox->isHidden(); -} - -/*! - * \brief Sets whether the user is force to enter a password. - * - * If no password is required, the user is allowed to skip the dialog without entering - * a password. - * - * \sa EnterPasswordDialog::isPasswordRequired() - */ -void EnterPasswordDialog::setPasswordRequired(bool value) -{ - m_ui->noPwCheckBox->setHidden(value); - m_ui->noPwCheckBox->setChecked(false); - adjustSize(); -} - -/*! - * \brief Updates the relevant controls to show entered characters or to mask them them. - * - * This private slot is called when m_ui->showPasswordCheckBox is clicked. - */ -void EnterPasswordDialog::updateShowPassword() -{ - m_ui->password1LineEdit->setEchoMode(m_ui->showPasswordCheckBox->isChecked() - ? QLineEdit::Normal - : QLineEdit::Password); - m_ui->password1LineEdit->setEnabled(!m_ui->noPwCheckBox->isChecked()); - m_ui->password2LineEdit->setEnabled(!(m_ui->showPasswordCheckBox->isChecked() || m_ui->noPwCheckBox->isChecked())); -} - -/*! - * \brief Sets whether a verification (password has to be entered twice) is required. - * - * \sa EnterPasswordDialog::isVerificationRequired() - */ -void EnterPasswordDialog::setVerificationRequired(bool value) -{ - if(m_instruction.isEmpty()) { - m_ui->instructionLabel->setText(value ? tr("Enter the new password") : tr("Enter the password")); - } - m_ui->password2LineEdit->setHidden(!value); - adjustSize(); -} - -/*! - * \brief Sets the instruction text. - * - * \sa EnterPasswordDialog::instruction() - */ -void EnterPasswordDialog::setInstruction(const QString &value) -{ - m_instruction = value; - if(m_instruction.isEmpty()) { - m_ui->instructionLabel->setText(isVerificationRequired() ? tr("Enter the new password") : tr("Enter the password")); - } else { - m_ui->instructionLabel->setText(value); - } - adjustSize(); -} - -bool EnterPasswordDialog::event(QEvent *event) -{ - switch(event->type()) { - case QEvent::KeyPress: { - QKeyEvent *keyEvent = static_cast(event); - if(keyEvent->key() == Qt::Key_CapsLock) { - m_capslockPressed = !m_capslockPressed; - } - m_ui->capslockWarningWidget->setVisible(m_capslockPressed); - break; - } - default: - ; - } - return QDialog::event(event); -} - -/*! - * \brief Internal method to notice when the capslock key is pressed by the user. - * - * Invocation of this method is done by installing the event filter in the constructor. - */ -bool EnterPasswordDialog::eventFilter(QObject *sender, QEvent *event) -{ - switch(event->type()) { - case QEvent::KeyPress: { - QKeyEvent *keyEvent = static_cast(event); - if(keyEvent->key() == Qt::Key_CapsLock) { - m_capslockPressed = !m_capslockPressed; - } else { - QString text = keyEvent->text(); - if(text.length()) { - QChar firstChar = text.at(0); - bool shiftPressed = (keyEvent->modifiers() & Qt::ShiftModifier) != 0; - if((shiftPressed && firstChar.isLower()) || (!shiftPressed && firstChar.isUpper())) { - m_capslockPressed = true; - } else if(firstChar.isLetter()) { - m_capslockPressed = false; - } - } - } - m_ui->capslockWarningWidget->setVisible(m_capslockPressed); - } - break; - case QEvent::FocusIn: - if(sender == m_ui->userNameLineEdit || sender == m_ui->password1LineEdit || sender == m_ui->password2LineEdit) { - releaseKeyboard(); - qobject_cast(sender)->grabKeyboard(); - } - break; - case QEvent::FocusOut: - if(sender == m_ui->userNameLineEdit || sender == m_ui->password1LineEdit || sender == m_ui->password2LineEdit) { - qobject_cast(sender)->releaseKeyboard(); - grabKeyboard(); - } - break; - default: - ; - } - return false; -} - -/*! - * \brief Sets the dialog status to QDialog::Accepted if a valid password has been enterd. - * Displays an error message otherwise. - * - * This private slot is called when m_ui->confirmPushButton is clicked. - */ -void EnterPasswordDialog::confirm() -{ - if(!isPasswordRequired() && m_ui->noPwCheckBox->isChecked()) { - m_password.clear(); - done(QDialog::Accepted); - } else { - QString userName = m_ui->userNameLineEdit->text(); - QString password = m_ui->password1LineEdit->text(); - QString repeatedPassword = m_ui->password2LineEdit->text(); - if(promtForUserName() && userName.isEmpty()) { - QMessageBox::warning(this, windowTitle(), tr("You didn't enter a user name.")); - } else if(password.isEmpty()) { - QMessageBox::warning(this, windowTitle(), tr("You didn't enter a password.")); - } else { - if(isVerificationRequired() && (password != repeatedPassword) && !m_ui->showPasswordCheckBox->isChecked()) { - if(repeatedPassword.isEmpty()) { - QMessageBox::warning(this, windowTitle(), tr("You have to enter the new password twice to ensure you enterd it correct.")); - } else { - QMessageBox::warning(this, windowTitle(), tr("You mistyped the password.")); - } - } else { - m_userName = userName; - m_password = password; - done(QDialog::Accepted); - } - } - } -} - -/*! - * \brief Returns an indication whether the capslock key is pressed using platform specific functions. - * - * \remarks - Returns always false for unsupported platforms. - * - This method always returns false when not built with - * PLATFORM_SPECIFIC_CAPSLOCK_DETECTION defined. - * - This static function will be used internally to detect whether the capslock key is pressed - * when initializing the dialog if available. - * - The function requires the application to be linked against X11 on Linux/Unix. - */ -bool EnterPasswordDialog::isCapslockPressed() -{ -#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION - // platform dependent method of determining if CAPS LOCK is pressed -# if defined(Q_OS_WIN32) - return GetKeyState(VK_CAPITAL) == 1; -# elif defined(X_AVAILABLE) - Display *d = XOpenDisplay((char*)0); - bool caps_state = false; - if (d) { - unsigned n; - XkbGetIndicatorState(d, XkbUseCoreKbd, &n); - caps_state = (n & 0x01) == 1; - } - return caps_state; -# else - return false; -# endif - return false; -#endif -} - -} +#include "./enterpassworddialog.h" +#include "../misc/dialogutils.h" + +#include "ui_enterpassworddialog.h" + +#include +#include +#include +#include +#include + +#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION +# if defined(Q_OS_WIN32) +# include +# elif defined(X_AVAILABLE) +# include +# undef KeyPress +# undef KeyRelease +# undef FocusIn +# undef FocusOut +# endif +#endif + +namespace Dialogs { + +/*! + * \class Dialogs::EnterPasswordDialog + * \brief The EnterPasswordDialog class provides a simple dialog to ask the user for a password. + */ + +/*! + * \brief Constructs a password dialog. + * \param parent Specifies the parent widget. + */ +EnterPasswordDialog::EnterPasswordDialog(QWidget *parent) : + QDialog(parent), + m_ui(new Ui::EnterPasswordDialog) +{ + // setup ui + m_ui->setupUi(this); + makeHeading(m_ui->instructionLabel); + setStyleSheet(dialogStyle()); + setDescription(); + setPromptForUserName(false); + setVerificationRequired(false); + setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); + installEventFilter(this); + m_ui->userNameLineEdit->installEventFilter(this); + m_ui->password1LineEdit->installEventFilter(this); + m_ui->password2LineEdit->installEventFilter(this); + // capslock key detection +#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION + m_capslockPressed = isCapslockPressed(); +#else + m_capslockPressed = false; +#endif + m_ui->capslockWarningWidget->setVisible(m_capslockPressed); + // draw icon to capslock warning graphics view + QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, this); + QGraphicsScene* scene = new QGraphicsScene(); + QGraphicsPixmapItem* item = new QGraphicsPixmapItem(icon.pixmap(16, 16)); + scene->addItem(item); + m_ui->capslockWarningGraphicsView->setScene(scene); + // connect signals and slots + connect(m_ui->showPasswordCheckBox, &QCheckBox::clicked, this, &EnterPasswordDialog::updateShowPassword); + connect(m_ui->noPwCheckBox, &QCheckBox::clicked, this, &EnterPasswordDialog::updateShowPassword); + connect(m_ui->confirmPushButton, &QPushButton::clicked, this, &EnterPasswordDialog::confirm); + connect(m_ui->abortPushButton, &QPushButton::clicked, this, &EnterPasswordDialog::abort); + // grab the keyboard + grabKeyboard(); +} + +/*! + * \brief Destroys the password dialog. + */ +EnterPasswordDialog::~EnterPasswordDialog() +{} + +/*! + * \brief Returns the description. The description is shown under the instruction text. + * \sa setDescription() + */ +QString EnterPasswordDialog::description() const +{ + return m_ui->descLabel->text(); +} + +/*! + * \brief Sets the description. + * \sa description() + */ +void EnterPasswordDialog::setDescription(const QString &description) +{ + m_ui->descLabel->setText(description); + m_ui->descLabel->setHidden(description.isEmpty()); + adjustSize(); +} + +/*! + * \brief Returns whether the dialogs prompts for a user name as well. + * + * The dialog does not prompt for a user name by default. + * + * \sa setPromptForUserName() + */ +bool EnterPasswordDialog::promtForUserName() const +{ + return !m_ui->userNameLineEdit->isHidden(); +} + +/*! + * \brief Sets whethere the dialog prompts for a user name as well. + * \sa promptForUserName() + */ +void EnterPasswordDialog::setPromptForUserName(bool prompt) +{ + m_ui->userNameLineEdit->setHidden(!prompt); + adjustSize(); +} + +/*! + * \brief Returns an indication whether a verification (password has to be entered twice) is required. + * + * \sa EnterPasswordDialog::setVerificationRequired() + */ +bool EnterPasswordDialog::isVerificationRequired() const +{ + return !m_ui->password2LineEdit->isHidden(); +} + +/*! + * \brief Returns an indication whether the user is force to enter a password. + * + * If no password is required, the user is allowed to skip the dialog without entering + * a password. + * + * \sa EnterPasswordDialog::setPasswordRequired() + */ +bool EnterPasswordDialog::isPasswordRequired() const +{ + return m_ui->noPwCheckBox->isHidden(); +} + +/*! + * \brief Sets whether the user is force to enter a password. + * + * If no password is required, the user is allowed to skip the dialog without entering + * a password. + * + * \sa EnterPasswordDialog::isPasswordRequired() + */ +void EnterPasswordDialog::setPasswordRequired(bool value) +{ + m_ui->noPwCheckBox->setHidden(value); + m_ui->noPwCheckBox->setChecked(false); + adjustSize(); +} + +/*! + * \brief Updates the relevant controls to show entered characters or to mask them them. + * + * This private slot is called when m_ui->showPasswordCheckBox is clicked. + */ +void EnterPasswordDialog::updateShowPassword() +{ + m_ui->password1LineEdit->setEchoMode(m_ui->showPasswordCheckBox->isChecked() + ? QLineEdit::Normal + : QLineEdit::Password); + m_ui->password1LineEdit->setEnabled(!m_ui->noPwCheckBox->isChecked()); + m_ui->password2LineEdit->setEnabled(!(m_ui->showPasswordCheckBox->isChecked() || m_ui->noPwCheckBox->isChecked())); +} + +/*! + * \brief Sets whether a verification (password has to be entered twice) is required. + * + * \sa EnterPasswordDialog::isVerificationRequired() + */ +void EnterPasswordDialog::setVerificationRequired(bool value) +{ + if(m_instruction.isEmpty()) { + m_ui->instructionLabel->setText(value ? tr("Enter the new password") : tr("Enter the password")); + } + m_ui->password2LineEdit->setHidden(!value); + adjustSize(); +} + +/*! + * \brief Sets the instruction text. + * + * \sa EnterPasswordDialog::instruction() + */ +void EnterPasswordDialog::setInstruction(const QString &value) +{ + m_instruction = value; + if(m_instruction.isEmpty()) { + m_ui->instructionLabel->setText(isVerificationRequired() ? tr("Enter the new password") : tr("Enter the password")); + } else { + m_ui->instructionLabel->setText(value); + } + adjustSize(); +} + +bool EnterPasswordDialog::event(QEvent *event) +{ + switch(event->type()) { + case QEvent::KeyPress: { + QKeyEvent *keyEvent = static_cast(event); + if(keyEvent->key() == Qt::Key_CapsLock) { + m_capslockPressed = !m_capslockPressed; + } + m_ui->capslockWarningWidget->setVisible(m_capslockPressed); + break; + } + default: + ; + } + return QDialog::event(event); +} + +/*! + * \brief Internal method to notice when the capslock key is pressed by the user. + * + * Invocation of this method is done by installing the event filter in the constructor. + */ +bool EnterPasswordDialog::eventFilter(QObject *sender, QEvent *event) +{ + switch(event->type()) { + case QEvent::KeyPress: { + QKeyEvent *keyEvent = static_cast(event); + if(keyEvent->key() == Qt::Key_CapsLock) { + m_capslockPressed = !m_capslockPressed; + } else { + QString text = keyEvent->text(); + if(text.length()) { + QChar firstChar = text.at(0); + bool shiftPressed = (keyEvent->modifiers() & Qt::ShiftModifier) != 0; + if((shiftPressed && firstChar.isLower()) || (!shiftPressed && firstChar.isUpper())) { + m_capslockPressed = true; + } else if(firstChar.isLetter()) { + m_capslockPressed = false; + } + } + } + m_ui->capslockWarningWidget->setVisible(m_capslockPressed); + } + break; + case QEvent::FocusIn: + if(sender == m_ui->userNameLineEdit || sender == m_ui->password1LineEdit || sender == m_ui->password2LineEdit) { + releaseKeyboard(); + qobject_cast(sender)->grabKeyboard(); + } + break; + case QEvent::FocusOut: + if(sender == m_ui->userNameLineEdit || sender == m_ui->password1LineEdit || sender == m_ui->password2LineEdit) { + qobject_cast(sender)->releaseKeyboard(); + grabKeyboard(); + } + break; + default: + ; + } + return false; +} + +/*! + * \brief Sets the dialog status to QDialog::Accepted if a valid password has been enterd. + * Displays an error message otherwise. + * + * This private slot is called when m_ui->confirmPushButton is clicked. + */ +void EnterPasswordDialog::confirm() +{ + if(!isPasswordRequired() && m_ui->noPwCheckBox->isChecked()) { + m_password.clear(); + done(QDialog::Accepted); + } else { + QString userName = m_ui->userNameLineEdit->text(); + QString password = m_ui->password1LineEdit->text(); + QString repeatedPassword = m_ui->password2LineEdit->text(); + if(promtForUserName() && userName.isEmpty()) { + QMessageBox::warning(this, windowTitle(), tr("You didn't enter a user name.")); + } else if(password.isEmpty()) { + QMessageBox::warning(this, windowTitle(), tr("You didn't enter a password.")); + } else { + if(isVerificationRequired() && (password != repeatedPassword) && !m_ui->showPasswordCheckBox->isChecked()) { + if(repeatedPassword.isEmpty()) { + QMessageBox::warning(this, windowTitle(), tr("You have to enter the new password twice to ensure you enterd it correct.")); + } else { + QMessageBox::warning(this, windowTitle(), tr("You mistyped the password.")); + } + } else { + m_userName = userName; + m_password = password; + done(QDialog::Accepted); + } + } + } +} + +/*! + * \brief Returns an indication whether the capslock key is pressed using platform specific functions. + * + * \remarks - Returns always false for unsupported platforms. + * - This method always returns false when not built with + * PLATFORM_SPECIFIC_CAPSLOCK_DETECTION defined. + * - This static function will be used internally to detect whether the capslock key is pressed + * when initializing the dialog if available. + * - The function requires the application to be linked against X11 on Linux/Unix. + */ +bool EnterPasswordDialog::isCapslockPressed() +{ +#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION + // platform dependent method of determining if CAPS LOCK is pressed +# if defined(Q_OS_WIN32) + return GetKeyState(VK_CAPITAL) == 1; +# elif defined(X_AVAILABLE) + Display *d = XOpenDisplay((char*)0); + bool caps_state = false; + if (d) { + unsigned n; + XkbGetIndicatorState(d, XkbUseCoreKbd, &n); + caps_state = (n & 0x01) == 1; + } + return caps_state; +# else + return false; +# endif + return false; +#endif +} + +} diff --git a/enterpassworddialog/enterpassworddialog.h b/enterpassworddialog/enterpassworddialog.h index 1c2d361..fab9bdd 100644 --- a/enterpassworddialog/enterpassworddialog.h +++ b/enterpassworddialog/enterpassworddialog.h @@ -1,106 +1,106 @@ -#ifndef DIALOGS_ENTERPASSWORDDIALOG_H -#define DIALOGS_ENTERPASSWORDDIALOG_H - -#include - -#include - -#include - -namespace Dialogs { - -namespace Ui { -class EnterPasswordDialog; -} - -class LIB_EXPORT EnterPasswordDialog : public QDialog -{ - Q_OBJECT - Q_PROPERTY(QString userName READ userName) - Q_PROPERTY(QString password READ password) - Q_PROPERTY(QString description READ description WRITE setDescription) - Q_PROPERTY(bool promtForUserName READ promtForUserName WRITE setPromptForUserName) - Q_PROPERTY(bool isVerificationRequired READ isVerificationRequired WRITE setVerificationRequired) - Q_PROPERTY(bool isPasswordRequired READ isPasswordRequired WRITE setPasswordRequired) - Q_PROPERTY(QString instruction READ instruction WRITE setInstruction) - Q_PROPERTY(bool isCapslockPressed READ isCapslockPressed) - -public: - explicit EnterPasswordDialog(QWidget *parent = nullptr); - ~EnterPasswordDialog(); - const QString &userName() const; - const QString &password() const; - QString description() const; - void setDescription(const QString &description = QString()); - bool promtForUserName() const; - void setPromptForUserName(bool prompt); - bool isVerificationRequired() const; - void setVerificationRequired(bool value); - bool isPasswordRequired() const; - void setPasswordRequired(bool value); - const QString &instruction() const; - void setInstruction(const QString &value); - static bool isCapslockPressed(); - -protected: - bool event(QEvent *event); - bool eventFilter(QObject *sender, QEvent *event); - -private Q_SLOTS: - void updateShowPassword(); - void confirm(); - void abort(); - -private: - std::unique_ptr m_ui; - QString m_userName; - QString m_password; - QString m_instruction; - bool m_capslockPressed; -}; - -/*! - * \brief Returns the entered user name. - */ -inline const QString &EnterPasswordDialog::userName() const -{ - return m_userName; -} - -/*! - * \brief Returns the entered password. - */ -inline const QString &EnterPasswordDialog::password() const -{ - return m_password; -} - -/*! - * \brief Returns the instruction text. - * - * The instruction text is displayed at the top of the dialog. - * If the instruction text is empty the default text "Enter the new password" - * or "Enter the password" (depending on whether the verification is requried or - * not) displayed. - * - * \sa EnterPasswordDialog::setInstruction() - */ -inline const QString &EnterPasswordDialog::instruction() const -{ - return m_instruction; -} - -/*! - * \brief Clears all results and sets the dialog status to QDialog::Rejected. - * - * This private slot is called when m_ui->abortPushButton is clicked. - */ -inline void EnterPasswordDialog::abort() -{ - m_password.clear(); - done(QDialog::Rejected); -} - -} - -#endif // DIALOGS_ENTERPASSWORDDIALOG_H +#ifndef DIALOGS_ENTERPASSWORDDIALOG_H +#define DIALOGS_ENTERPASSWORDDIALOG_H + +#include "../global.h" + +#include + +#include + +namespace Dialogs { + +namespace Ui { +class EnterPasswordDialog; +} + +class QT_UTILITIES_EXPORT EnterPasswordDialog : public QDialog +{ + Q_OBJECT + Q_PROPERTY(QString userName READ userName) + Q_PROPERTY(QString password READ password) + Q_PROPERTY(QString description READ description WRITE setDescription) + Q_PROPERTY(bool promtForUserName READ promtForUserName WRITE setPromptForUserName) + Q_PROPERTY(bool isVerificationRequired READ isVerificationRequired WRITE setVerificationRequired) + Q_PROPERTY(bool isPasswordRequired READ isPasswordRequired WRITE setPasswordRequired) + Q_PROPERTY(QString instruction READ instruction WRITE setInstruction) + Q_PROPERTY(bool isCapslockPressed READ isCapslockPressed) + +public: + explicit EnterPasswordDialog(QWidget *parent = nullptr); + ~EnterPasswordDialog(); + const QString &userName() const; + const QString &password() const; + QString description() const; + void setDescription(const QString &description = QString()); + bool promtForUserName() const; + void setPromptForUserName(bool prompt); + bool isVerificationRequired() const; + void setVerificationRequired(bool value); + bool isPasswordRequired() const; + void setPasswordRequired(bool value); + const QString &instruction() const; + void setInstruction(const QString &value); + static bool isCapslockPressed(); + +protected: + bool event(QEvent *event); + bool eventFilter(QObject *sender, QEvent *event); + +private Q_SLOTS: + void updateShowPassword(); + void confirm(); + void abort(); + +private: + std::unique_ptr m_ui; + QString m_userName; + QString m_password; + QString m_instruction; + bool m_capslockPressed; +}; + +/*! + * \brief Returns the entered user name. + */ +inline const QString &EnterPasswordDialog::userName() const +{ + return m_userName; +} + +/*! + * \brief Returns the entered password. + */ +inline const QString &EnterPasswordDialog::password() const +{ + return m_password; +} + +/*! + * \brief Returns the instruction text. + * + * The instruction text is displayed at the top of the dialog. + * If the instruction text is empty the default text "Enter the new password" + * or "Enter the password" (depending on whether the verification is requried or + * not) displayed. + * + * \sa EnterPasswordDialog::setInstruction() + */ +inline const QString &EnterPasswordDialog::instruction() const +{ + return m_instruction; +} + +/*! + * \brief Clears all results and sets the dialog status to QDialog::Rejected. + * + * This private slot is called when m_ui->abortPushButton is clicked. + */ +inline void EnterPasswordDialog::abort() +{ + m_password.clear(); + done(QDialog::Rejected); +} + +} + +#endif // DIALOGS_ENTERPASSWORDDIALOG_H diff --git a/global.h b/global.h new file mode 100644 index 0000000..196e833 --- /dev/null +++ b/global.h @@ -0,0 +1,17 @@ +// Created via CMake from template global.h.in +// WARNING! Any changes to this file will be overwritten by the next CMake run! + +#ifndef QT_UTILITIES_GLOBAL +#define QT_UTILITIES_GLOBAL + +#include + +#ifdef QT_UTILITIES_STATIC +# define QT_UTILITIES_EXPORT +# define QT_UTILITIES_IMPORT +#else +# define QT_UTILITIES_EXPORT LIB_EXPORT +# define QT_UTILITIES_IMPORT LIB_IMPORT +#endif + +#endif // QT_UTILITIES_GLOBAL diff --git a/misc/desktoputils.cpp b/misc/desktoputils.cpp index 4178a59..a82b035 100644 --- a/misc/desktoputils.cpp +++ b/misc/desktoputils.cpp @@ -1,27 +1,25 @@ -#include "desktoputils.h" - -#include - -#include -#include - -namespace DesktopUtils { - -/*! - * \brief Shows the specified file or directory using the default file browser. - * \remarks \a path musn't be specified as URL. (Conversion to URL is the purpose of this function). - */ -bool LIB_EXPORT openLocalFileOrDir(const QString &path) -{ -#ifdef Q_OS_WIN32 - // backslashes are commonly used under Windows - // -> replace backslashes with slashes to support Windows paths - QString tmp(path); - tmp.replace(QChar('\\'), QChar('/')); - return QDesktopServices::openUrl(QUrl(QStringLiteral("file:///") + path, QUrl::TolerantMode)); -#else - return QDesktopServices::openUrl(QUrl(QStringLiteral("file://") + path, QUrl::TolerantMode)); -#endif -} - -} +#include "./desktoputils.h" + +#include +#include + +namespace DesktopUtils { + +/*! + * \brief Shows the specified file or directory using the default file browser. + * \remarks \a path musn't be specified as URL. (Conversion to URL is the purpose of this function). + */ +bool openLocalFileOrDir(const QString &path) +{ +#ifdef Q_OS_WIN32 + // backslashes are commonly used under Windows + // -> replace backslashes with slashes to support Windows paths + QString tmp(path); + tmp.replace(QChar('\\'), QChar('/')); + return QDesktopServices::openUrl(QUrl(QStringLiteral("file:///") + path, QUrl::TolerantMode)); +#else + return QDesktopServices::openUrl(QUrl(QStringLiteral("file://") + path, QUrl::TolerantMode)); +#endif +} + +} diff --git a/misc/desktoputils.h b/misc/desktoputils.h index ac7364f..246572f 100644 --- a/misc/desktoputils.h +++ b/misc/desktoputils.h @@ -1,14 +1,16 @@ -#ifndef DESKTOP_UTILS_DESKTOPSERVICES_H -#define DESKTOP_UTILS_DESKTOPSERVICES_H - -#include - -QT_FORWARD_DECLARE_CLASS(QString) - -namespace DesktopUtils { - -bool openLocalFileOrDir(const QString &path); - -} - -#endif // DESKTOP_UTILS_DESKTOPSERVICES_H +#ifndef DESKTOP_UTILS_DESKTOPSERVICES_H +#define DESKTOP_UTILS_DESKTOPSERVICES_H + +#include "../global.h" + +#include + +QT_FORWARD_DECLARE_CLASS(QString) + +namespace DesktopUtils { + +bool QT_UTILITIES_EXPORT openLocalFileOrDir(const QString &path); + +} + +#endif // DESKTOP_UTILS_DESKTOPSERVICES_H diff --git a/misc/dialogutils.h b/misc/dialogutils.h index ef97617..4cb75bf 100644 --- a/misc/dialogutils.h +++ b/misc/dialogutils.h @@ -1,7 +1,7 @@ #ifndef DIALOGS_DIALOGUTILS_H #define DIALOGS_DIALOGUTILS_H -#include +#include "../global.h" #include @@ -20,19 +20,19 @@ enum class DocumentStatus { Unsaved /**< There is a document opened and there are unsaved modifications. */ }; -QString LIB_EXPORT generateWindowTitle(DocumentStatus documentStatus, const QString &documentPath); +QString QT_UTILITIES_EXPORT generateWindowTitle(DocumentStatus documentStatus, const QString &documentPath); #ifndef GUI_NONE # ifdef Q_OS_WIN32 -QColor LIB_EXPORT windowFrameColor(); -QColor LIB_EXPORT instructionTextColor(); +QColor QT_UTILITIES_EXPORT windowFrameColor(); +QColor QT_UTILITIES_EXPORT instructionTextColor(); # endif -const QString LIB_EXPORT &dialogStyle(); +const QString QT_UTILITIES_EXPORT &dialogStyle(); # ifdef GUI_QTWIDGETS -void LIB_EXPORT centerWidget(QWidget *widget); -void LIB_EXPORT cornerWidget(QWidget *widget); -void LIB_EXPORT makeHeading(QWidget *widget); -void LIB_EXPORT updateStyle(QWidget *widget); +void QT_UTILITIES_EXPORT centerWidget(QWidget *widget); +void QT_UTILITIES_EXPORT cornerWidget(QWidget *widget); +void QT_UTILITIES_EXPORT makeHeading(QWidget *widget); +void QT_UTILITIES_EXPORT updateStyle(QWidget *widget); # endif #endif diff --git a/misc/recentmenumanager.cpp b/misc/recentmenumanager.cpp index d1a115e..01cfe30 100644 --- a/misc/recentmenumanager.cpp +++ b/misc/recentmenumanager.cpp @@ -1,168 +1,168 @@ -#include "recentmenumanager.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace MiscUtils { - -/*! - * \class RecentMenuManager - * \brief The RecentMenuManager class manages the entries for a "recently opened files" menu. - */ - -/*! - * \brief Constructs a new recent menu manager. - * \param menu Specifies the QMenu instance to operate with. - * \param parent Specifies the parent QObject; might be nullptr. - * \remarks - * - Menu title and icon are set within the constructor. - * - The current menu entries are cleared. - * - The menu entries shouldn't be manipulated manually by the caller till the manager is destructed. - * - The manager does not take ownership over \a menu. - */ -RecentMenuManager::RecentMenuManager(QMenu *menu, QObject *parent) : - QObject(parent), - m_menu(menu) -{ - m_menu->clear(); - m_menu->setTitle(tr("&Recent")); - m_menu->setIcon(QIcon::fromTheme(QStringLiteral("document-open-recent"))); - m_sep = m_menu->addSeparator(); - m_clearAction = m_menu->addAction(QIcon::fromTheme(QStringLiteral("edit-clear")), tr("&Clear list"), this, &RecentMenuManager::clearEntries); -} - -/*! - * \brief Restores the specified entries. - */ -void RecentMenuManager::restore(const QStringList &savedEntries) -{ - QAction *action = nullptr; - for(const QString &path : savedEntries) { - if(!path.isEmpty()) { - action = new QAction(path, m_menu); - action->setProperty("file_path", path); - m_menu->insertAction(m_sep, action); - connect(action, &QAction::triggered, this, &RecentMenuManager::handleActionTriggered); - } - } - if(action) { - m_menu->actions().front()->setShortcut(QKeySequence(Qt::Key_F6)); - m_menu->setEnabled(true); - } -} - -/*! - * \brief Saves the current entries. - */ -QStringList RecentMenuManager::save() -{ - QStringList existingEntires; - QList entryActions = m_menu->actions(); - existingEntires.reserve(entryActions.size()); - for(const QAction *action : entryActions) { - QVariant path = action->property("file_path"); - if(!path.isNull()) { - existingEntires << path.toString(); - } - } - return existingEntires; -} - -/*! - * \brief Ensures an entry for the specified \a path is present and the first entry in the list. - */ -void RecentMenuManager::addEntry(const QString &path) -{ - QList existingEntries = m_menu->actions(); - QAction *entry = nullptr; - // remove shortcut from existing entries - for(QAction *existingEntry : existingEntries) { - existingEntry->setShortcut(QKeySequence()); - // check whether existing entry matches entry to add - if(existingEntry->property("file_path").toString() == path) { - entry = existingEntry; - break; - } - } - if(!entry) { - // remove old entries to have never more then 10 entries - for(int i = existingEntries.size() - 1; i > 8; --i) { - delete existingEntries[i]; - } - existingEntries = m_menu->actions(); - // create new action - entry = new QAction(path, this); - entry->setProperty("file_path", path); - connect(entry, &QAction::triggered, this, &RecentMenuManager::handleActionTriggered); - } else { - // remove existing action (will be inserted again as first action) - m_menu->removeAction(entry); - } - // add shortcut for new entry - entry->setShortcut(QKeySequence(Qt::Key_F6)); - // ensure menu is enabled - m_menu->setEnabled(true); - // add action as first action in the recent menu - m_menu->insertAction(m_menu->isEmpty() ? nullptr : m_menu->actions().front(), entry); -} - -/*! - * \brief Clears all entries. - */ -void RecentMenuManager::clearEntries() -{ - QList entries = m_menu->actions(); - for(auto i = entries.begin(), end = entries.end() - 2; i != end; ++i) { - if(*i != m_clearAction) { - delete *i; - } - } - m_menu->setEnabled(false); -} - -/*! - * \brief Internally called to emit fileSelected() after an action has been triggered. - */ -void RecentMenuManager::handleActionTriggered() -{ - if(QAction *action = qobject_cast(sender())) { - const QString path = action->property("file_path").toString(); - if(!path.isEmpty()) { - if(QFile::exists(path)) { - emit fileSelected(path); - } else { - QMessageBox msg; - msg.setWindowTitle(tr("Recently opened files - ") + QCoreApplication::applicationName()); - msg.setText(tr("The selected file can't be found anymore. Do you want to delete the obsolete entry from the list?")); - msg.setIcon(QMessageBox::Warning); - QPushButton *keepEntryButton = msg.addButton(tr("keep entry"), QMessageBox::NoRole); - QPushButton *deleteEntryButton = msg.addButton(tr("delete entry"), QMessageBox::YesRole); - msg.setEscapeButton(keepEntryButton); - msg.exec(); - if(msg.clickedButton() == deleteEntryButton) { - delete action; - QList remainingActions = m_menu->actions(); - if(!remainingActions.isEmpty() && remainingActions.front() != m_sep && remainingActions.front() != m_clearAction) { - remainingActions.front()->setShortcut(QKeySequence(Qt::Key_F6)); - m_menu->setEnabled(true); - } else { - m_menu->setEnabled(false); - } - } - } - } - } -} - -/*! - * \fn RecentMenuManager::fileSelected() - * \brief Emitted after the user selected a file. - * \remarks Only emitted when the selected file still existed; otherwise the user is ask whether to keep or delete the entry. - */ - -} +#include "recentmenumanager.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace MiscUtils { + +/*! + * \class RecentMenuManager + * \brief The RecentMenuManager class manages the entries for a "recently opened files" menu. + */ + +/*! + * \brief Constructs a new recent menu manager. + * \param menu Specifies the QMenu instance to operate with. + * \param parent Specifies the parent QObject; might be nullptr. + * \remarks + * - Menu title and icon are set within the constructor. + * - The current menu entries are cleared. + * - The menu entries shouldn't be manipulated manually by the caller till the manager is destructed. + * - The manager does not take ownership over \a menu. + */ +RecentMenuManager::RecentMenuManager(QMenu *menu, QObject *parent) : + QObject(parent), + m_menu(menu) +{ + m_menu->clear(); + m_menu->setTitle(tr("&Recent")); + m_menu->setIcon(QIcon::fromTheme(QStringLiteral("document-open-recent"))); + m_sep = m_menu->addSeparator(); + m_clearAction = m_menu->addAction(QIcon::fromTheme(QStringLiteral("edit-clear")), tr("&Clear list"), this, &RecentMenuManager::clearEntries); +} + +/*! + * \brief Restores the specified entries. + */ +void RecentMenuManager::restore(const QStringList &savedEntries) +{ + QAction *action = nullptr; + for(const QString &path : savedEntries) { + if(!path.isEmpty()) { + action = new QAction(path, m_menu); + action->setProperty("file_path", path); + m_menu->insertAction(m_sep, action); + connect(action, &QAction::triggered, this, &RecentMenuManager::handleActionTriggered); + } + } + if(action) { + m_menu->actions().front()->setShortcut(QKeySequence(Qt::Key_F6)); + m_menu->setEnabled(true); + } +} + +/*! + * \brief Saves the current entries. + */ +QStringList RecentMenuManager::save() +{ + QStringList existingEntires; + QList entryActions = m_menu->actions(); + existingEntires.reserve(entryActions.size()); + for(const QAction *action : entryActions) { + QVariant path = action->property("file_path"); + if(!path.isNull()) { + existingEntires << path.toString(); + } + } + return existingEntires; +} + +/*! + * \brief Ensures an entry for the specified \a path is present and the first entry in the list. + */ +void RecentMenuManager::addEntry(const QString &path) +{ + QList existingEntries = m_menu->actions(); + QAction *entry = nullptr; + // remove shortcut from existing entries + for(QAction *existingEntry : existingEntries) { + existingEntry->setShortcut(QKeySequence()); + // check whether existing entry matches entry to add + if(existingEntry->property("file_path").toString() == path) { + entry = existingEntry; + break; + } + } + if(!entry) { + // remove old entries to have never more then 10 entries + for(int i = existingEntries.size() - 1; i > 8; --i) { + delete existingEntries[i]; + } + existingEntries = m_menu->actions(); + // create new action + entry = new QAction(path, this); + entry->setProperty("file_path", path); + connect(entry, &QAction::triggered, this, &RecentMenuManager::handleActionTriggered); + } else { + // remove existing action (will be inserted again as first action) + m_menu->removeAction(entry); + } + // add shortcut for new entry + entry->setShortcut(QKeySequence(Qt::Key_F6)); + // ensure menu is enabled + m_menu->setEnabled(true); + // add action as first action in the recent menu + m_menu->insertAction(m_menu->isEmpty() ? nullptr : m_menu->actions().front(), entry); +} + +/*! + * \brief Clears all entries. + */ +void RecentMenuManager::clearEntries() +{ + QList entries = m_menu->actions(); + for(auto i = entries.begin(), end = entries.end() - 2; i != end; ++i) { + if(*i != m_clearAction) { + delete *i; + } + } + m_menu->setEnabled(false); +} + +/*! + * \brief Internally called to emit fileSelected() after an action has been triggered. + */ +void RecentMenuManager::handleActionTriggered() +{ + if(QAction *action = qobject_cast(sender())) { + const QString path = action->property("file_path").toString(); + if(!path.isEmpty()) { + if(QFile::exists(path)) { + emit fileSelected(path); + } else { + QMessageBox msg; + msg.setWindowTitle(tr("Recently opened files - ") + QCoreApplication::applicationName()); + msg.setText(tr("The selected file can't be found anymore. Do you want to delete the obsolete entry from the list?")); + msg.setIcon(QMessageBox::Warning); + QPushButton *keepEntryButton = msg.addButton(tr("keep entry"), QMessageBox::NoRole); + QPushButton *deleteEntryButton = msg.addButton(tr("delete entry"), QMessageBox::YesRole); + msg.setEscapeButton(keepEntryButton); + msg.exec(); + if(msg.clickedButton() == deleteEntryButton) { + delete action; + QList remainingActions = m_menu->actions(); + if(!remainingActions.isEmpty() && remainingActions.front() != m_sep && remainingActions.front() != m_clearAction) { + remainingActions.front()->setShortcut(QKeySequence(Qt::Key_F6)); + m_menu->setEnabled(true); + } else { + m_menu->setEnabled(false); + } + } + } + } + } +} + +/*! + * \fn RecentMenuManager::fileSelected() + * \brief Emitted after the user selected a file. + * \remarks Only emitted when the selected file still existed; otherwise the user is ask whether to keep or delete the entry. + */ + +} diff --git a/misc/recentmenumanager.h b/misc/recentmenumanager.h index 1012335..537b81e 100644 --- a/misc/recentmenumanager.h +++ b/misc/recentmenumanager.h @@ -1,40 +1,40 @@ -#ifndef MISC_UTILS_RECENTMENUMANAGER_H -#define MISC_UTILS_RECENTMENUMANAGER_H - -#include - -#include - -QT_FORWARD_DECLARE_CLASS(QMenu) -QT_FORWARD_DECLARE_CLASS(QAction) - -namespace MiscUtils { - -class LIB_EXPORT RecentMenuManager : public QObject -{ - Q_OBJECT - -public: - RecentMenuManager(QMenu *menu, QObject *parent = nullptr); - -public Q_SLOTS: - void restore(const QStringList &savedEntries); - QStringList save(); - void addEntry(const QString &path); - void clearEntries(); - -Q_SIGNALS: - void fileSelected(const QString &path); - -private Q_SLOTS: - void handleActionTriggered(); - -private: - QMenu *m_menu; - QAction *m_sep; - QAction *m_clearAction; -}; - -} - -#endif // MISC_UTILS_RECENTMENUMANAGER_H +#ifndef MISC_UTILS_RECENTMENUMANAGER_H +#define MISC_UTILS_RECENTMENUMANAGER_H + +#include "../global.h" + +#include + +QT_FORWARD_DECLARE_CLASS(QMenu) +QT_FORWARD_DECLARE_CLASS(QAction) + +namespace MiscUtils { + +class QT_UTILITIES_EXPORT RecentMenuManager : public QObject +{ + Q_OBJECT + +public: + RecentMenuManager(QMenu *menu, QObject *parent = nullptr); + +public Q_SLOTS: + void restore(const QStringList &savedEntries); + QStringList save(); + void addEntry(const QString &path); + void clearEntries(); + +Q_SIGNALS: + void fileSelected(const QString &path); + +private Q_SLOTS: + void handleActionTriggered(); + +private: + QMenu *m_menu; + QAction *m_sep; + QAction *m_clearAction; +}; + +} + +#endif // MISC_UTILS_RECENTMENUMANAGER_H diff --git a/models/checklistmodel.h b/models/checklistmodel.h index 7a1bd4a..9eeef78 100644 --- a/models/checklistmodel.h +++ b/models/checklistmodel.h @@ -1,7 +1,7 @@ #ifndef MODELS_CHECKLISTMODEL_H #define MODELS_CHECKLISTMODEL_H -#include +#include "../global.h" #include #include @@ -12,7 +12,7 @@ namespace Models { class ChecklistModel; -class LIB_EXPORT ChecklistItem +class QT_UTILITIES_EXPORT ChecklistItem { friend class ChecklistModel; @@ -69,7 +69,7 @@ inline bool ChecklistItem::isChecked() const return m_checkState == Qt::Checked; } -class LIB_EXPORT ChecklistModel : public QAbstractListModel +class QT_UTILITIES_EXPORT ChecklistModel : public QAbstractListModel { Q_OBJECT public: diff --git a/paletteeditor/colorbutton.h b/paletteeditor/colorbutton.h index d4e6455..9c85585 100644 --- a/paletteeditor/colorbutton.h +++ b/paletteeditor/colorbutton.h @@ -1,7 +1,7 @@ #ifndef WIDGETS_COLORBUTTON_H #define WIDGETS_COLORBUTTON_H -#include +#include "../global.h" #include @@ -12,7 +12,7 @@ namespace Widgets { * * This is taken from qttools/src/shared/qtgradienteditor/qtcolorbutton.h. */ -class LIB_EXPORT ColorButton : public QToolButton +class QT_UTILITIES_EXPORT ColorButton : public QToolButton { Q_OBJECT Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered) diff --git a/paletteeditor/paletteeditor.cpp b/paletteeditor/paletteeditor.cpp index f0bfe99..7c78886 100644 --- a/paletteeditor/paletteeditor.cpp +++ b/paletteeditor/paletteeditor.cpp @@ -1,6 +1,8 @@ #include "./paletteeditor.h" #include "./colorbutton.h" +#include "ui_paletteeditor.h" + #include #include #include @@ -15,33 +17,33 @@ enum { BrushRole = 33 }; PaletteEditor::PaletteEditor(QWidget *parent) : QDialog(parent), + m_ui(new Ui::PaletteEditor), m_currentColorGroup(QPalette::Active), m_paletteModel(new PaletteModel(this)), m_modelUpdated(false), m_paletteUpdated(false), m_compute(true) { - m_ui.setupUi(this); - m_ui.paletteView->setModel(m_paletteModel); + m_ui->setupUi(this); + m_ui->paletteView->setModel(m_paletteModel); updatePreviewPalette(); updateStyledButton(); - m_ui.paletteView->setModel(m_paletteModel); + m_ui->paletteView->setModel(m_paletteModel); ColorDelegate *delegate = new ColorDelegate(this); - m_ui.paletteView->setItemDelegate(delegate); - m_ui.paletteView->setEditTriggers(QAbstractItemView::AllEditTriggers); + m_ui->paletteView->setItemDelegate(delegate); + m_ui->paletteView->setEditTriggers(QAbstractItemView::AllEditTriggers); connect(m_paletteModel, &PaletteModel::paletteChanged, this, &PaletteEditor::paletteChanged); - m_ui.paletteView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_ui.paletteView->setDragEnabled(true); - m_ui.paletteView->setDropIndicatorShown(true); - m_ui.paletteView->setRootIsDecorated(false); - m_ui.paletteView->setColumnHidden(2, true); - m_ui.paletteView->setColumnHidden(3, true); + m_ui->paletteView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_ui->paletteView->setDragEnabled(true); + m_ui->paletteView->setDropIndicatorShown(true); + m_ui->paletteView->setRootIsDecorated(false); + m_ui->paletteView->setColumnHidden(2, true); + m_ui->paletteView->setColumnHidden(3, true); } PaletteEditor::~PaletteEditor() -{ -} +{} QPalette PaletteEditor::palette() const { @@ -104,8 +106,8 @@ void PaletteEditor::on_computeRadio_clicked() { if (m_compute) return; - m_ui.paletteView->setColumnHidden(2, true); - m_ui.paletteView->setColumnHidden(3, true); + m_ui->paletteView->setColumnHidden(2, true); + m_ui->paletteView->setColumnHidden(3, true); m_compute = true; m_paletteModel->setCompute(true); } @@ -114,10 +116,10 @@ void PaletteEditor::on_detailsRadio_clicked() { if (!m_compute) return; - const int w = m_ui.paletteView->columnWidth(1); - m_ui.paletteView->setColumnHidden(2, false); - m_ui.paletteView->setColumnHidden(3, false); - QHeaderView *header = m_ui.paletteView->header(); + const int w = m_ui->paletteView->columnWidth(1); + m_ui->paletteView->setColumnHidden(2, false); + m_ui->paletteView->setColumnHidden(3, false); + QHeaderView *header = m_ui->paletteView->header(); header->resizeSection(1, w / 3); header->resizeSection(2, w / 3); header->resizeSection(3, w / 3); @@ -128,15 +130,16 @@ void PaletteEditor::on_detailsRadio_clicked() void PaletteEditor::paletteChanged(const QPalette &palette) { m_modelUpdated = true; - if (!m_paletteUpdated) + if (!m_paletteUpdated) { setPalette(palette); + } m_modelUpdated = false; } void PaletteEditor::buildPalette() { - const QColor btn = m_ui.buildButton->color(); - const QPalette temp = QPalette(btn); + const QColor btn(m_ui->buildButton->color()); + const QPalette temp(btn); setPalette(temp); } @@ -157,7 +160,7 @@ void PaletteEditor::updatePreviewPalette() void PaletteEditor::updateStyledButton() { - m_ui.buildButton->setColor(palette().color(QPalette::Active, QPalette::Button)); + m_ui->buildButton->setColor(palette().color(QPalette::Active, QPalette::Button)); } QPalette PaletteEditor::getPalette(QWidget *parent, const QPalette &init, diff --git a/paletteeditor/paletteeditor.h b/paletteeditor/paletteeditor.h index 73ba2a5..92709d3 100644 --- a/paletteeditor/paletteeditor.h +++ b/paletteeditor/paletteeditor.h @@ -1,11 +1,14 @@ #ifndef WIDGETS_PALETTEEDITOR_H #define WIDGETS_PALETTEEDITOR_H -#include "ui_paletteeditor.h" +#include "../global.h" -#include +#include #include +#include + +#include QT_FORWARD_DECLARE_CLASS(QListView) QT_FORWARD_DECLARE_CLASS(QLabel) @@ -16,13 +19,17 @@ class ColorButton; namespace Dialogs { +namespace Ui { +class PaletteEditor; +} + /*! * \brief The PaletteEditor class provides a dialog to customize a QPalette. * * This is taken from qttools/src/designer/src/components/propertyeditor/paletteeditor.cpp. * In contrast to the original version this version doesn't provide a preview. */ -class LIB_EXPORT PaletteEditor : public QDialog +class QT_UTILITIES_EXPORT PaletteEditor : public QDialog { Q_OBJECT public: @@ -57,7 +64,7 @@ private: return m_currentColorGroup; } - Ui::PaletteEditor m_ui; + std::unique_ptr m_ui; QPalette m_editPalette; QPalette m_parentPalette; QPalette::ColorGroup m_currentColorGroup; @@ -70,7 +77,7 @@ private: /*! * \brief The PaletteModel class is used by PaletteEditor. */ -class LIB_EXPORT PaletteModel : public QAbstractTableModel +class QT_UTILITIES_EXPORT PaletteModel : public QAbstractTableModel { Q_OBJECT Q_PROPERTY(QPalette::ColorRole colorRole READ colorRole) @@ -108,7 +115,7 @@ private: /*! * \brief The BrushEditor class is used by PaletteEditor. */ -class LIB_EXPORT BrushEditor : public QWidget +class QT_UTILITIES_EXPORT BrushEditor : public QWidget { Q_OBJECT @@ -133,7 +140,7 @@ private: /*! * \brief The RoleEditor class is used by PaletteEditor. */ -class LIB_EXPORT RoleEditor : public QWidget +class QT_UTILITIES_EXPORT RoleEditor : public QWidget { Q_OBJECT public: @@ -157,7 +164,7 @@ private: /*! * \brief The ColorDelegate class is used by PaletteEditor. */ -class LIB_EXPORT ColorDelegate : public QItemDelegate +class QT_UTILITIES_EXPORT ColorDelegate : public QItemDelegate { Q_OBJECT diff --git a/resources/qtconfigarguments.h b/resources/qtconfigarguments.h index 5813b9f..d9b412b 100644 --- a/resources/qtconfigarguments.h +++ b/resources/qtconfigarguments.h @@ -1,11 +1,13 @@ #ifndef APPLICATION_UTILITIES_QTCONFIGARGUMENTS_H #define APPLICATION_UTILITIES_QTCONFIGARGUMENTS_H +#include "../global.h" + #include namespace ApplicationUtilities { -class LIB_EXPORT QtConfigArguments +class QT_UTILITIES_EXPORT QtConfigArguments { public: QtConfigArguments(); diff --git a/resources/resources.h b/resources/resources.h index 0d26f03..2872c6b 100644 --- a/resources/resources.h +++ b/resources/resources.h @@ -1,7 +1,7 @@ #ifndef APPLICATION_UTILITIES_RESOURCES_H #define APPLICATION_UTILITIES_RESOURCES_H -#include +#include "../global.h" #include @@ -29,36 +29,36 @@ QT_FORWARD_DECLARE_CLASS(QSettings) namespace QtUtilitiesResources { -LIB_EXPORT void init(); -LIB_EXPORT void cleanup(); +QT_UTILITIES_EXPORT void init(); +QT_UTILITIES_EXPORT void cleanup(); } namespace TranslationFiles { -LIB_EXPORT QString &additionalTranslationFilePath(); -LIB_EXPORT void loadQtTranslationFile(std::initializer_list repositoryNames); -LIB_EXPORT void loadQtTranslationFile(std::initializer_list repositoryNames, const QString &localeName); -LIB_EXPORT void loadApplicationTranslationFile(const QString &applicationName); -LIB_EXPORT void loadApplicationTranslationFile(const QString &applicationName, const QString &localeName); +QT_UTILITIES_EXPORT QString &additionalTranslationFilePath(); +QT_UTILITIES_EXPORT void loadQtTranslationFile(std::initializer_list repositoryNames); +QT_UTILITIES_EXPORT void loadQtTranslationFile(std::initializer_list repositoryNames, const QString &localeName); +QT_UTILITIES_EXPORT void loadApplicationTranslationFile(const QString &applicationName); +QT_UTILITIES_EXPORT void loadApplicationTranslationFile(const QString &applicationName, const QString &localeName); } namespace ApplicationInstances { #if defined(GUI_QTWIDGETS) -LIB_EXPORT bool hasWidgetsApp(); +QT_UTILITIES_EXPORT bool hasWidgetsApp(); #endif #if defined(GUI_QTWIDGETS) || defined(GUI_QTQUICK) -LIB_EXPORT bool hasGuiApp(); +QT_UTILITIES_EXPORT bool hasGuiApp(); #endif -LIB_EXPORT bool hasCoreApp(); +QT_UTILITIES_EXPORT bool hasCoreApp(); } namespace ConfigFile { -LIB_EXPORT QString locateConfigFile(const QString &applicationName, const QString &fileName, const QSettings *settings = nullptr); +QT_UTILITIES_EXPORT QString locateConfigFile(const QString &applicationName, const QString &fileName, const QSettings *settings = nullptr); } diff --git a/settingsdialog/optioncategory.h b/settingsdialog/optioncategory.h index 0435c03..efd01f3 100644 --- a/settingsdialog/optioncategory.h +++ b/settingsdialog/optioncategory.h @@ -1,7 +1,7 @@ #ifndef DIALOGS_OPTIONSCATEGORY_H #define DIALOGS_OPTIONSCATEGORY_H -#include +#include "../global.h" #include #include @@ -11,7 +11,7 @@ namespace Dialogs { class OptionPage; -class LIB_EXPORT OptionCategory : public QObject +class QT_UTILITIES_EXPORT OptionCategory : public QObject { Q_OBJECT Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName NOTIFY displayNameChanged) diff --git a/settingsdialog/optioncategorymodel.h b/settingsdialog/optioncategorymodel.h index 6cd95ba..2f2b699 100644 --- a/settingsdialog/optioncategorymodel.h +++ b/settingsdialog/optioncategorymodel.h @@ -1,7 +1,7 @@ #ifndef DIALOGS_OPTIONCATEGORYMODEL_H #define DIALOGS_OPTIONCATEGORYMODEL_H -#include +#include "../global.h" #include #include @@ -11,7 +11,7 @@ namespace Dialogs { class OptionPage; class OptionCategory; -class LIB_EXPORT OptionCategoryModel : public QAbstractListModel +class QT_UTILITIES_EXPORT OptionCategoryModel : public QAbstractListModel { Q_OBJECT public: diff --git a/settingsdialog/optionpage.h b/settingsdialog/optionpage.h index a412b9d..f81a7b9 100644 --- a/settingsdialog/optionpage.h +++ b/settingsdialog/optionpage.h @@ -1,7 +1,7 @@ #ifndef DIALOGS_OPTIONSPAGE_H #define DIALOGS_OPTIONSPAGE_H -#include +#include "../global.h" #include #include @@ -10,7 +10,7 @@ namespace Dialogs { -class LIB_EXPORT OptionPage +class QT_UTILITIES_EXPORT OptionPage { public: explicit OptionPage(QWidget *parentWindow = nullptr); @@ -80,7 +80,7 @@ inline QStringList &OptionPage::errors() * \tparam UiClass Specifies the UI class generated by uic. */ template -class LIB_EXPORT UiFileBasedOptionPage : public OptionPage +class QT_UTILITIES_EXPORT UiFileBasedOptionPage : public OptionPage { public: explicit UiFileBasedOptionPage(QWidget *parentWindow = nullptr); @@ -143,7 +143,7 @@ inline UiClass *UiFileBasedOptionPage::ui() */ #define BEGIN_DECLARE_OPTION_PAGE(SomeClass) \ typedef ::Dialogs::OptionPage SomeClass ## Base; \ - class LIB_EXPORT SomeClass : public ::Dialogs::OptionPage \ + class QT_UTILITIES_EXPORT SomeClass : public ::Dialogs::OptionPage \ { \ public: \ explicit SomeClass(QWidget *parentWidget = nullptr); \ @@ -161,7 +161,7 @@ inline UiClass *UiFileBasedOptionPage::ui() class SomeClass; \ } \ typedef ::Dialogs::UiFileBasedOptionPage SomeClass ## Base; \ - class LIB_EXPORT SomeClass : public ::Dialogs::UiFileBasedOptionPage \ + class QT_UTILITIES_EXPORT SomeClass : public ::Dialogs::UiFileBasedOptionPage \ { \ public: \ ~SomeClass(); \ diff --git a/settingsdialog/qtsettings.h b/settingsdialog/qtsettings.h index c42f2a9..a7eb9f5 100644 --- a/settingsdialog/qtsettings.h +++ b/settingsdialog/qtsettings.h @@ -40,7 +40,7 @@ private: QtSettingsData &m_settings; END_DECLARE_OPTION_PAGE -class LIB_EXPORT QtSettings +class QT_UTILITIES_EXPORT QtSettings { public: QtSettings(); diff --git a/settingsdialog/settingsdialog.h b/settingsdialog/settingsdialog.h index e09aa23..7f5035c 100644 --- a/settingsdialog/settingsdialog.h +++ b/settingsdialog/settingsdialog.h @@ -1,7 +1,7 @@ #ifndef DIALOGS_SETTINGSDIALOG_H #define DIALOGS_SETTINGSDIALOG_H -#include +#include "../global.h" #include @@ -18,7 +18,7 @@ namespace Ui { class SettingsDialog; } -class LIB_EXPORT SettingsDialog : public QDialog +class QT_UTILITIES_EXPORT SettingsDialog : public QDialog { Q_OBJECT Q_PROPERTY(bool tabBarAlwaysVisible READ isTabBarAlwaysVisible WRITE setTabBarAlwaysVisible) diff --git a/widgets/buttonoverlay.h b/widgets/buttonoverlay.h index 5d77616..3eed963 100644 --- a/widgets/buttonoverlay.h +++ b/widgets/buttonoverlay.h @@ -1,7 +1,7 @@ #ifndef WIDGETS_BUTTONOVERLAY_H #define WIDGETS_BUTTONOVERLAY_H -#include +#include "../global.h" #include @@ -14,7 +14,7 @@ namespace Widgets { class IconButton; -class LIB_EXPORT ButtonOverlay +class QT_UTILITIES_EXPORT ButtonOverlay { public: explicit ButtonOverlay(QWidget *widget); diff --git a/widgets/clearcombobox.h b/widgets/clearcombobox.h index b4cdadb..627d9d4 100644 --- a/widgets/clearcombobox.h +++ b/widgets/clearcombobox.h @@ -3,13 +3,11 @@ #include "./buttonoverlay.h" -#include - #include namespace Widgets { -class LIB_EXPORT ClearComboBox : public QComboBox, public ButtonOverlay +class QT_UTILITIES_EXPORT ClearComboBox : public QComboBox, public ButtonOverlay { Q_OBJECT public: diff --git a/widgets/clearlineedit.h b/widgets/clearlineedit.h index 198ebe2..34152ca 100644 --- a/widgets/clearlineedit.h +++ b/widgets/clearlineedit.h @@ -3,19 +3,15 @@ #include "./buttonoverlay.h" -#include - #include -QT_BEGIN_NAMESPACE -class QHBoxLayout; -QT_END_NAMESPACE +QT_FORWARD_DECLARE_CLASS(QHBoxLayout) namespace Widgets { class IconButton; -class LIB_EXPORT ClearLineEdit : public QLineEdit, public ButtonOverlay +class QT_UTILITIES_EXPORT ClearLineEdit : public QLineEdit, public ButtonOverlay { Q_OBJECT public: diff --git a/widgets/clearplaintextedit.h b/widgets/clearplaintextedit.h index 123c2b6..2cc6ca5 100644 --- a/widgets/clearplaintextedit.h +++ b/widgets/clearplaintextedit.h @@ -7,7 +7,7 @@ namespace Widgets { -class LIB_EXPORT ClearPlainTextEdit : public QPlainTextEdit, public ButtonOverlay +class QT_UTILITIES_EXPORT ClearPlainTextEdit : public QPlainTextEdit, public ButtonOverlay { Q_OBJECT public: diff --git a/widgets/clearspinbox.h b/widgets/clearspinbox.h index d78d45e..23bbb27 100644 --- a/widgets/clearspinbox.h +++ b/widgets/clearspinbox.h @@ -3,20 +3,16 @@ #include "./buttonoverlay.h" -#include - #include #include -QT_BEGIN_NAMESPACE -class QHBoxLayout; -QT_END_NAMESPACE +QT_FORWARD_DECLARE_CLASS(QHBoxLayout) namespace Widgets { class IconButton; -class LIB_EXPORT ClearSpinBox : public QSpinBox, public ButtonOverlay +class QT_UTILITIES_EXPORT ClearSpinBox : public QSpinBox, public ButtonOverlay { Q_OBJECT Q_PROPERTY(bool minimumHidden READ minimumHidden WRITE setMinimumHidden) diff --git a/widgets/iconbutton.h b/widgets/iconbutton.h index ea2fd96..ac163ed 100644 --- a/widgets/iconbutton.h +++ b/widgets/iconbutton.h @@ -1,14 +1,14 @@ #ifndef WIDGETS_ICONBUTTON_H #define WIDGETS_ICONBUTTON_H -#include +#include "../global.h" #include #include namespace Widgets { -class LIB_EXPORT IconButton : public QAbstractButton +class QT_UTILITIES_EXPORT IconButton : public QAbstractButton { Q_OBJECT Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) diff --git a/widgets/pathselection.h b/widgets/pathselection.h index 9d54004..1f52d10 100644 --- a/widgets/pathselection.h +++ b/widgets/pathselection.h @@ -1,7 +1,7 @@ #ifndef WIDGETS_PATHSELECTION_H #define WIDGETS_PATHSELECTION_H -#include +#include "../global.h" #include @@ -12,7 +12,7 @@ namespace Widgets { class ClearLineEdit; -class LIB_EXPORT PathSelection : public QWidget +class QT_UTILITIES_EXPORT PathSelection : public QWidget { Q_OBJECT public: