Fix decoration for static builds

- Also fix finding static web view and JavaScript provider
This commit is contained in:
Martchus 2016-08-29 15:41:11 +02:00
parent 72296a2768
commit 7f9afcda73
33 changed files with 935 additions and 904 deletions

View File

@ -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
)

View File

@ -1,76 +1,76 @@
#include "./aboutdialog.h"
#include "../misc/dialogutils.h"
#include "ui_aboutdialog.h"
#include <QGraphicsPixmapItem>
#include <QApplication>
#include <QDesktopWidget>
#include <QStyle>
/*!
\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 <a href=\"%1\" style=\"text-decoration: underline; color: palette(link);\">project website</a>.").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 <QGraphicsPixmapItem>
#include <QApplication>
#include <QDesktopWidget>
#include <QStyle>
/*!
\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 <a href=\"%1\" style=\"text-decoration: underline; color: palette(link);\">project website</a>.").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()
{}
}

View File

@ -1,34 +1,34 @@
#ifndef DIALOGS_ABOUTDIALOG_H
#define DIALOGS_ABOUTDIALOG_H
#include <c++utilities/application/global.h>
#include <QDialog>
#include <memory>
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<Ui::AboutDialog> m_ui;
QGraphicsScene *m_iconScene;
};
}
#endif // DIALOGS_ABOUTDIALOG_H
#ifndef DIALOGS_ABOUTDIALOG_H
#define DIALOGS_ABOUTDIALOG_H
#include "../global.h"
#include <QDialog>
#include <memory>
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<Ui::AboutDialog> m_ui;
QGraphicsScene *m_iconScene;
};
}
#endif // DIALOGS_ABOUTDIALOG_H

View File

@ -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)

View File

@ -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})

View File

@ -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)

View File

@ -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)

View File

@ -1,332 +1,332 @@
#include "./enterpassworddialog.h"
#include "../misc/dialogutils.h"
#include "ui_enterpassworddialog.h"
#include <QEvent>
#include <QGraphicsPixmapItem>
#include <QKeyEvent>
#include <QMessageBox>
#include <QGuiApplication>
#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION
# if defined(Q_OS_WIN32)
# include <windows.h>
# elif defined(X_AVAILABLE)
# include <X11/XKBlib.h>
# 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<QKeyEvent *>(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<QKeyEvent *>(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<QWidget *>(sender)->grabKeyboard();
}
break;
case QEvent::FocusOut:
if(sender == m_ui->userNameLineEdit || sender == m_ui->password1LineEdit || sender == m_ui->password2LineEdit) {
qobject_cast<QWidget *>(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 <QEvent>
#include <QGraphicsPixmapItem>
#include <QKeyEvent>
#include <QMessageBox>
#include <QGuiApplication>
#ifdef PLATFORM_SPECIFIC_CAPSLOCK_DETECTION
# if defined(Q_OS_WIN32)
# include <windows.h>
# elif defined(X_AVAILABLE)
# include <X11/XKBlib.h>
# 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<QKeyEvent *>(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<QKeyEvent *>(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<QWidget *>(sender)->grabKeyboard();
}
break;
case QEvent::FocusOut:
if(sender == m_ui->userNameLineEdit || sender == m_ui->password1LineEdit || sender == m_ui->password2LineEdit) {
qobject_cast<QWidget *>(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
}
}

View File

@ -1,106 +1,106 @@
#ifndef DIALOGS_ENTERPASSWORDDIALOG_H
#define DIALOGS_ENTERPASSWORDDIALOG_H
#include <c++utilities/application/global.h>
#include <QDialog>
#include <memory>
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<Ui::EnterPasswordDialog> 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 <QDialog>
#include <memory>
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<Ui::EnterPasswordDialog> 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

17
global.h Normal file
View File

@ -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 <c++utilities/application/global.h>
#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

View File

@ -1,27 +1,25 @@
#include "desktoputils.h"
#include <c++utilities/application/global.h>
#include <QDesktopServices>
#include <QUrl>
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 <QDesktopServices>
#include <QUrl>
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
}
}

View File

@ -1,14 +1,16 @@
#ifndef DESKTOP_UTILS_DESKTOPSERVICES_H
#define DESKTOP_UTILS_DESKTOPSERVICES_H
#include <QtGlobal>
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 <QtGlobal>
QT_FORWARD_DECLARE_CLASS(QString)
namespace DesktopUtils {
bool QT_UTILITIES_EXPORT openLocalFileOrDir(const QString &path);
}
#endif // DESKTOP_UTILS_DESKTOPSERVICES_H

View File

@ -1,7 +1,7 @@
#ifndef DIALOGS_DIALOGUTILS_H
#define DIALOGS_DIALOGUTILS_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QtGlobal>
@ -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

View File

@ -1,168 +1,168 @@
#include "recentmenumanager.h"
#include <QStringList>
#include <QCoreApplication>
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QPushButton>
#include <QFile>
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<QAction *> 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<QAction *> 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<QAction *> 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<QAction *>(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<QAction *> 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 <QStringList>
#include <QCoreApplication>
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QPushButton>
#include <QFile>
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<QAction *> 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<QAction *> 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<QAction *> 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<QAction *>(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<QAction *> 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.
*/
}

View File

@ -1,40 +1,40 @@
#ifndef MISC_UTILS_RECENTMENUMANAGER_H
#define MISC_UTILS_RECENTMENUMANAGER_H
#include <c++utilities/application/global.h>
#include <QObject>
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 <QObject>
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

View File

@ -1,7 +1,7 @@
#ifndef MODELS_CHECKLISTMODEL_H
#define MODELS_CHECKLISTMODEL_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QAbstractListModel>
#include <QList>
@ -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:

View File

@ -1,7 +1,7 @@
#ifndef WIDGETS_COLORBUTTON_H
#define WIDGETS_COLORBUTTON_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QToolButton>
@ -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)

View File

@ -1,6 +1,8 @@
#include "./paletteeditor.h"
#include "./colorbutton.h"
#include "ui_paletteeditor.h"
#include <QMetaProperty>
#include <QPainter>
#include <QToolButton>
@ -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,

View File

@ -1,11 +1,14 @@
#ifndef WIDGETS_PALETTEEDITOR_H
#define WIDGETS_PALETTEEDITOR_H
#include "ui_paletteeditor.h"
#include "../global.h"
#include <c++utilities/application/global.h>
#include <c++utilities/conversion/types.h>
#include <QItemDelegate>
#include <QDialog>
#include <memory>
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<Ui::PaletteEditor> 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

View File

@ -1,11 +1,13 @@
#ifndef APPLICATION_UTILITIES_QTCONFIGARGUMENTS_H
#define APPLICATION_UTILITIES_QTCONFIGARGUMENTS_H
#include "../global.h"
#include <c++utilities/application/argumentparser.h>
namespace ApplicationUtilities {
class LIB_EXPORT QtConfigArguments
class QT_UTILITIES_EXPORT QtConfigArguments
{
public:
QtConfigArguments();

View File

@ -1,7 +1,7 @@
#ifndef APPLICATION_UTILITIES_RESOURCES_H
#define APPLICATION_UTILITIES_RESOURCES_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QtGlobal>
@ -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<QString> repositoryNames);
LIB_EXPORT void loadQtTranslationFile(std::initializer_list<QString> 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<QString> repositoryNames);
QT_UTILITIES_EXPORT void loadQtTranslationFile(std::initializer_list<QString> 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);
}

View File

@ -1,7 +1,7 @@
#ifndef DIALOGS_OPTIONSCATEGORY_H
#define DIALOGS_OPTIONSCATEGORY_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QObject>
#include <QIcon>
@ -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)

View File

@ -1,7 +1,7 @@
#ifndef DIALOGS_OPTIONCATEGORYMODEL_H
#define DIALOGS_OPTIONCATEGORYMODEL_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QList>
#include <QAbstractListModel>
@ -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:

View File

@ -1,7 +1,7 @@
#ifndef DIALOGS_OPTIONSPAGE_H
#define DIALOGS_OPTIONSPAGE_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QObject>
#include <QWidget>
@ -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 UiClass>
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<UiClass>::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<UiClass>::ui()
class SomeClass; \
} \
typedef ::Dialogs::UiFileBasedOptionPage<Ui::SomeClass> SomeClass ## Base; \
class LIB_EXPORT SomeClass : public ::Dialogs::UiFileBasedOptionPage<Ui::SomeClass> \
class QT_UTILITIES_EXPORT SomeClass : public ::Dialogs::UiFileBasedOptionPage<Ui::SomeClass> \
{ \
public: \
~SomeClass(); \

View File

@ -40,7 +40,7 @@ private:
QtSettingsData &m_settings;
END_DECLARE_OPTION_PAGE
class LIB_EXPORT QtSettings
class QT_UTILITIES_EXPORT QtSettings
{
public:
QtSettings();

View File

@ -1,7 +1,7 @@
#ifndef DIALOGS_SETTINGSDIALOG_H
#define DIALOGS_SETTINGSDIALOG_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QDialog>
@ -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)

View File

@ -1,7 +1,7 @@
#ifndef WIDGETS_BUTTONOVERLAY_H
#define WIDGETS_BUTTONOVERLAY_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QtGlobal>
@ -14,7 +14,7 @@ namespace Widgets {
class IconButton;
class LIB_EXPORT ButtonOverlay
class QT_UTILITIES_EXPORT ButtonOverlay
{
public:
explicit ButtonOverlay(QWidget *widget);

View File

@ -3,13 +3,11 @@
#include "./buttonoverlay.h"
#include <c++utilities/application/global.h>
#include <QComboBox>
namespace Widgets {
class LIB_EXPORT ClearComboBox : public QComboBox, public ButtonOverlay
class QT_UTILITIES_EXPORT ClearComboBox : public QComboBox, public ButtonOverlay
{
Q_OBJECT
public:

View File

@ -3,19 +3,15 @@
#include "./buttonoverlay.h"
#include <c++utilities/application/global.h>
#include <QLineEdit>
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:

View File

@ -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:

View File

@ -3,20 +3,16 @@
#include "./buttonoverlay.h"
#include <c++utilities/application/global.h>
#include <QSpinBox>
#include <QLineEdit>
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)

View File

@ -1,14 +1,14 @@
#ifndef WIDGETS_ICONBUTTON_H
#define WIDGETS_ICONBUTTON_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QAbstractButton>
#include <QPixmap>
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)

View File

@ -1,7 +1,7 @@
#ifndef WIDGETS_PATHSELECTION_H
#define WIDGETS_PATHSELECTION_H
#include <c++utilities/application/global.h>
#include "../global.h"
#include <QFileDialog>
@ -12,7 +12,7 @@ namespace Widgets {
class ClearLineEdit;
class LIB_EXPORT PathSelection : public QWidget
class QT_UTILITIES_EXPORT PathSelection : public QWidget
{
Q_OBJECT
public: