7 Commits
0.2.3 ... 0.3.0

15 changed files with 402 additions and 63 deletions

View File

@ -19,6 +19,8 @@ set (PPIC_CPP_FILES
navigatorview.cpp
opacityhelper.cpp
toolbutton.cpp
settings.cpp
settingsdialog.cpp
)
set (PPIC_HEADER_FILES
@ -29,6 +31,8 @@ set (PPIC_HEADER_FILES
navigatorview.h
opacityhelper.h
toolbutton.h
settings.h
settingsdialog.h
)
set (PPIC_QRC_FILES

View File

@ -32,7 +32,9 @@ SOURCES += \
graphicsscene.cpp \
navigatorview.cpp \
opacityhelper.cpp \
toolbutton.cpp
toolbutton.cpp \
settings.cpp \
settingsdialog.cpp
HEADERS += \
mainwindow.h \
@ -41,7 +43,9 @@ HEADERS += \
graphicsscene.h \
navigatorview.h \
opacityhelper.h \
toolbutton.h
toolbutton.h \
settings.h \
settingsdialog.h
TRANSLATIONS = \
languages/PineapplePictures.ts \
@ -56,5 +60,5 @@ RESOURCES += \
resources.qrc
# Generate fron svg:
# magick convert -background none ./app-icon.svg -define icon:auto-resize=64,48,32,16 app-icon.ico
# magick convert -background none app-icon.svg -define icon:auto-resize="16,32,48,64,128,256" app-icon.ico
RC_ICONS = icons/app-icon.ico

View File

@ -3,14 +3,14 @@ Yet another image viewer.
|CI|Build Status|
|---|---|
|Windows Build|[![Windows build status](https://ci.appveyor.com/api/projects/status/dbd8clww3cit6oa0/branch/master?svg=true)](https://ci.appveyor.com/project/BLumia/pineapplepictures/branch/master)|
|macOS Build|![macOS CI](https://github.com/BLumia/PineapplePictures/workflows/macOS%20CI/badge.svg)|
|Ubuntu 20.04 Build|![Ubuntu 20.04 CI](https://github.com/BLumia/PineapplePictures/workflows/Ubuntu%2020.04%20CI/badge.svg)|
|macOS Build|![macOS CI](https://github.com/BLumia/pineapple-pictures/workflows/macOS%20CI/badge.svg)|
|Ubuntu 20.04 Build|![Ubuntu 20.04 CI](https://github.com/BLumia/pineapple-pictures/workflows/Ubuntu%2020.04%20CI/badge.svg)|
![Pineapple Pictures - Main Window](https://repository-images.githubusercontent.com/211888654/21fb6300-269f-11ea-8e85-953e5d57da44)
## Get it!
- [GitHub Release Page](https://github.com/BLumia/PineapplePictures/releases)
- [GitHub Release Page](https://github.com/BLumia/pineapple-pictures/releases)
- Archlinux AUR: [pineapple-pictures-git](https://aur.archlinux.org/packages/pineapple-pictures-git/)
## Help Translation!

View File

@ -1,5 +1,6 @@
environment:
CMAKE_INSTALL_ROOT: C:\projects\cmake
ZLIB_ROOT: C:\projects\zlib
matrix:
- build_name: mingw73_32_qt5_12_6
QTPATH: C:\Qt\5.12.6\mingw73_32
@ -7,6 +8,7 @@ environment:
install:
- mkdir %CMAKE_INSTALL_ROOT%
- mkdir %ZLIB_ROOT%
- cd %APPVEYOR_BUILD_FOLDER%
- git submodule update --init --recursive
- set PATH=%PATH%;%CMAKE_INSTALL_ROOT%;%QTPATH%\bin;%MINGW32%\bin
@ -23,6 +25,22 @@ build_script:
- cmake --build .
- cmake --build . --target install
- cd %APPVEYOR_BUILD_FOLDER%
# download and install zlib for KArchive
- cd %ZLIB_ROOT%
- curl -fsS -o zlib128-dll.zip http://zlib.net/zlib128-dll.zip
- 7z e zlib128-dll.zip
- cd %APPVEYOR_BUILD_FOLDER%
# install KArchive for kra format support of KImageFormats
- cd 3rdparty
- git clone -q https://invent.kde.org/frameworks/karchive.git
- cd karchive
- mkdir build
- cd build
- cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%CMAKE_INSTALL_ROOT% -DCMAKE_CXX_FLAGS_RELEASE="-s" -DCMAKE_MAKE_PROGRAM=mingw32-make -DZLIB_ROOT=%ZLIB_ROOT%
# -DCMAKE_PREFIX_PATH=%CMAKE_INSTALL_ROOT%
- cmake --build . --config Release
- cmake --build . --config Release --target install
- cd %APPVEYOR_BUILD_FOLDER%
# install KImageFormats
- cd 3rdparty
- git clone -q https://invent.kde.org/frameworks/kimageformats.git
@ -41,6 +59,7 @@ build_script:
- mingw32-make install
# fixme: I don't know how to NOT make the binary installed to the ./bin/ folder...
- cd bin
- copy C:\projects\cmake\bin\libKF5Archive.dll .
- windeployqt --verbose=2 --no-quick-import --no-translations --no-opengl-sw --no-angle --no-system-d3d-compiler --release .\ppic.exe
# for debug..
- tree /f

View File

@ -142,12 +142,16 @@ void GraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRadio
applyTransformationModeByScaleFactor();
}
void GraphicsView::checkAndDoFitInView()
void GraphicsView::checkAndDoFitInView(bool markItOnAnyway)
{
if (!isThingSmallerThanWindowWith(transform())) {
m_enableFitInView = true;
fitInView(sceneRect(), Qt::KeepAspectRatio);
}
if (markItOnAnyway) {
m_enableFitInView = true;
}
}
void GraphicsView::toggleCheckerboard()

View File

@ -30,7 +30,7 @@ public:
void rotateView(qreal rotateAngel);
void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
void checkAndDoFitInView();
void checkAndDoFitInView(bool markItOnAnyway = true);
signals:
void navigatorViewRequired(bool required, qreal angle);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 212 KiB

View File

@ -12,7 +12,7 @@
<context>
<name>GraphicsView</name>
<message>
<location filename="../graphicsview.cpp" line="243"/>
<location filename="../graphicsview.cpp" line="247"/>
<source>File url list is empty</source>
<translation type="unfinished"></translation>
</message>
@ -22,12 +22,12 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphicsview.cpp" line="251"/>
<location filename="../graphicsview.cpp" line="255"/>
<source>Image data is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../graphicsview.cpp" line="258"/>
<location filename="../graphicsview.cpp" line="262"/>
<source>Not supported mimedata: %1</source>
<translation type="unfinished"></translation>
</message>
@ -35,78 +35,111 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="173"/>
<location filename="../mainwindow.cpp" line="174"/>
<source>File url list is empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="382"/>
<location filename="../mainwindow.cpp" line="396"/>
<source>&amp;Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="403"/>
<location filename="../mainwindow.cpp" line="417"/>
<source>Copy P&amp;ixmap</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="408"/>
<location filename="../mainwindow.cpp" line="422"/>
<source>Copy &amp;File Path</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="418"/>
<location filename="../mainwindow.cpp" line="432"/>
<source>&amp;Paste Image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="424"/>
<location filename="../mainwindow.cpp" line="438"/>
<source>&amp;Paste Image File</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="429"/>
<location filename="../mainwindow.cpp" line="448"/>
<location filename="../mainwindow.cpp" line="443"/>
<location filename="../mainwindow.cpp" line="471"/>
<source>Stay on top</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="435"/>
<location filename="../mainwindow.cpp" line="449"/>
<location filename="../mainwindow.cpp" line="450"/>
<location filename="../mainwindow.cpp" line="472"/>
<source>Protected mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="441"/>
<location filename="../mainwindow.cpp" line="457"/>
<source>Configure...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="464"/>
<source>Help</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="444"/>
<location filename="../mainwindow.cpp" line="467"/>
<source>Launch application with image file path as argument to load the file.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="445"/>
<location filename="../mainwindow.cpp" line="468"/>
<source>Drag and drop image file onto the window is also supported.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="447"/>
<location filename="../mainwindow.cpp" line="470"/>
<source>Context menu option explanation:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="448"/>
<location filename="../mainwindow.cpp" line="471"/>
<source>Make window stay on top of all other windows.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="449"/>
<location filename="../mainwindow.cpp" line="472"/>
<source>Avoid close window accidentally. (eg. by double clicking the window)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="18"/>
<source>Do nothing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="19"/>
<source>Close the window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="20"/>
<source>Toggle maximize</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="28"/>
<source>Stay on top when start-up</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="29"/>
<source>Double-click behavior</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>main</name>
<message>

View File

@ -12,7 +12,7 @@
<context>
<name>GraphicsView</name>
<message>
<location filename="../graphicsview.cpp" line="243"/>
<location filename="../graphicsview.cpp" line="247"/>
<source>File url list is empty</source>
<translation> URL </translation>
</message>
@ -22,12 +22,12 @@
<translation></translation>
</message>
<message>
<location filename="../graphicsview.cpp" line="251"/>
<location filename="../graphicsview.cpp" line="255"/>
<source>Image data is invalid</source>
<translation></translation>
</message>
<message>
<location filename="../graphicsview.cpp" line="258"/>
<location filename="../graphicsview.cpp" line="262"/>
<source>Not supported mimedata: %1</source>
<translation> MimeData %1</translation>
</message>
@ -35,12 +35,12 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="173"/>
<location filename="../mainwindow.cpp" line="174"/>
<source>File url list is empty</source>
<translation> URL </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="382"/>
<location filename="../mainwindow.cpp" line="396"/>
<source>&amp;Copy</source>
<translation>(&amp;C)</translation>
</message>
@ -49,68 +49,101 @@
<translation type="vanished">(&amp;P)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="403"/>
<location filename="../mainwindow.cpp" line="417"/>
<source>Copy P&amp;ixmap</source>
<translation>(&amp;I)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="408"/>
<location filename="../mainwindow.cpp" line="422"/>
<source>Copy &amp;File Path</source>
<translation>(&amp;F)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="418"/>
<location filename="../mainwindow.cpp" line="432"/>
<source>&amp;Paste Image</source>
<translation>(&amp;P)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="424"/>
<location filename="../mainwindow.cpp" line="438"/>
<source>&amp;Paste Image File</source>
<translation>(&amp;P)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="429"/>
<location filename="../mainwindow.cpp" line="448"/>
<location filename="../mainwindow.cpp" line="443"/>
<location filename="../mainwindow.cpp" line="471"/>
<source>Stay on top</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="435"/>
<location filename="../mainwindow.cpp" line="449"/>
<location filename="../mainwindow.cpp" line="450"/>
<location filename="../mainwindow.cpp" line="472"/>
<source>Protected mode</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="441"/>
<location filename="../mainwindow.cpp" line="457"/>
<source>Configure...</source>
<translation>...</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="464"/>
<source>Help</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="444"/>
<location filename="../mainwindow.cpp" line="467"/>
<source>Launch application with image file path as argument to load the file.</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="445"/>
<location filename="../mainwindow.cpp" line="468"/>
<source>Drag and drop image file onto the window is also supported.</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="447"/>
<location filename="../mainwindow.cpp" line="470"/>
<source>Context menu option explanation:</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="448"/>
<location filename="../mainwindow.cpp" line="471"/>
<source>Make window stay on top of all other windows.</source>
<translation>使</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="449"/>
<location filename="../mainwindow.cpp" line="472"/>
<source>Avoid close window accidentally. (eg. by double clicking the window)</source>
<translation></translation>
</message>
</context>
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="18"/>
<source>Do nothing</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="19"/>
<source>Close the window</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="20"/>
<source>Toggle maximize</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="28"/>
<source>Stay on top when start-up</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="29"/>
<source>Double-click behavior</source>
<translation></translation>
</message>
</context>
<context>
<name>main</name>
<message>

View File

@ -1,10 +1,12 @@
#include "mainwindow.h"
#include "settings.h"
#include "toolbutton.h"
#include "bottombuttongroup.h"
#include "graphicsview.h"
#include "navigatorview.h"
#include "graphicsscene.h"
#include "settingsdialog.h"
#include <QMouseEvent>
#include <QMovie>
@ -27,9 +29,14 @@
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
if (Settings::instance()->stayOnTop()) {
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
} else {
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
}
this->setAttribute(Qt::WA_TranslucentBackground, true);
this->setMinimumSize(710, 530);
this->setMinimumSize(350, 350);
this->setWindowIcon(QIcon(":/icons/app-icon.svg"));
this->setMouseTracking(true);
@ -101,13 +108,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(m_bottomButtonGroup, &BottomButtonGroup::resetToOriginalBtnClicked,
this, [ = ](){ m_graphicsView->resetScale(); });
connect(m_bottomButtonGroup, &BottomButtonGroup::toggleWindowMaximum,
this, [ = ](){
if (isMaximized()) {
showNormal();
} else {
showMaximized();
}
});
this, &MainWindow::toggleMaximize);
connect(m_bottomButtonGroup, &BottomButtonGroup::zoomInBtnClicked,
this, [ = ](){ m_graphicsView->zoomView(1.25); });
connect(m_bottomButtonGroup, &BottomButtonGroup::zoomOutBtnClicked,
@ -187,11 +188,11 @@ void MainWindow::adjustWindowSizeBySceneRect()
QSize screenSize = qApp->screenAt(QCursor::pos())->availableSize();
if (screenSize.expandedTo(sceneSize) == screenSize) {
// we can show the picture by increase the window size.
if (screenSize.expandedTo(sceneSizeWithMargins) == screenSize) {
this->resize(sceneSizeWithMargins);
} else {
this->resize(screenSize);
}
QSize finalSize = (screenSize.expandedTo(sceneSizeWithMargins) == screenSize) ?
sceneSizeWithMargins : screenSize;
// We have a very reasonable sizeHint() value ;P
this->resize(finalSize.expandedTo(this->sizeHint()));
// We're sure the window can display the whole thing with 1:1 scale.
// The old window size may cause fitInView call from resize() and the
// above resize() call won't reset the scale back to 1:1, so we
@ -325,7 +326,7 @@ void MainWindow::mousePressEvent(QMouseEvent *event)
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton && m_clickedOnWindow) {
if (event->buttons() & Qt::LeftButton && m_clickedOnWindow && !isMaximized()) {
move(event->globalPos() - m_oldMousePos);
event->accept();
}
@ -342,9 +343,22 @@ void MainWindow::mouseReleaseEvent(QMouseEvent *event)
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
quitAppAction();
switch (Settings::instance()->doubleClickBehavior()) {
case ActionCloseWindow:
quitAppAction();
event->accept();
break;
case ActionMaximizeWindow:
toggleMaximize();
event->accept();
break;
case ActionDoNothing:
break;
}
return QMainWindow::mouseDoubleClickEvent(event);
// blumia: don't call parent constructor here, seems it will cause mouse move
// event get called even if we set event->accept();
// return QMainWindow::mouseDoubleClickEvent(event);
}
void MainWindow::wheelEvent(QWheelEvent *event)
@ -432,12 +446,21 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
});
stayOnTopMode->setCheckable(true);
stayOnTopMode->setChecked(stayOnTop());
QAction * protectedMode = new QAction(tr("Protected mode"));
connect(protectedMode, &QAction::triggered, this, [ = ](){
toggleProtectedMode();
});
protectedMode->setCheckable(true);
protectedMode->setChecked(m_protectedMode);
QAction * toggleSettings = new QAction(tr("Configure..."));
connect(toggleSettings, &QAction::triggered, this, [ = ](){
SettingsDialog * sd = new SettingsDialog(this);
sd->exec();
sd->deleteLater();
});
QAction * helpAction = new QAction(tr("Help"));
connect(helpAction, &QAction::triggered, this, [ = ](){
QStringList sl {
@ -465,6 +488,7 @@ void MainWindow::contextMenuEvent(QContextMenuEvent *event)
menu->addAction(stayOnTopMode);
menu->addAction(protectedMode);
menu->addSeparator();
menu->addAction(toggleSettings);
menu->addAction(helpAction);
menu->exec(mapToGlobal(event->pos()));
menu->deleteLater();
@ -559,6 +583,11 @@ bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *r
#endif // _WIN32
}
QSize MainWindow::sizeHint() const
{
return QSize(710, 530);
}
void MainWindow::centerWindow()
{
this->setGeometry(
@ -626,3 +655,12 @@ void MainWindow::toggleFullscreen()
showFullScreen();
}
}
void MainWindow::toggleMaximize()
{
if (isMaximized()) {
showNormal();
} else {
showMaximized();
}
}

View File

@ -50,6 +50,8 @@ protected slots:
bool nativeEvent(const QByteArray& eventType, void* message, long* result) override;
QSize sizeHint() const override;
void centerWindow();
void closeWindow();
void updateWidgetsPosition();
@ -58,6 +60,7 @@ protected slots:
bool stayOnTop();
void quitAppAction(bool force = false);
void toggleFullscreen();
void toggleMaximize();
private:
QPoint m_oldMousePos;

84
settings.cpp Normal file
View File

@ -0,0 +1,84 @@
#include "settings.h"
#include <QApplication>
#include <QStandardPaths>
#include <QDebug>
#include <QDir>
Settings *Settings::m_settings_instance = nullptr;
Settings *Settings::instance()
{
if (!m_settings_instance) {
m_settings_instance = new Settings;
}
return m_settings_instance;
}
bool Settings::stayOnTop()
{
return m_qsettings->value("stay_on_top", true).toBool();
}
DoubleClickBehavior Settings::doubleClickBehavior()
{
QString result = m_qsettings->value("double_click_behavior", "close").toString().toLower();
return stringToDoubleClickBehavior(result);
}
void Settings::setStayOnTop(bool on)
{
m_qsettings->setValue("stay_on_top", on);
m_qsettings->sync();
}
void Settings::setDoubleClickBehavior(DoubleClickBehavior dcb)
{
m_qsettings->setValue("double_click_behavior", doubleClickBehaviorToString(dcb));
m_qsettings->sync();
}
QString Settings::doubleClickBehaviorToString(DoubleClickBehavior dcb)
{
static QMap<DoubleClickBehavior, QString> _map {
{ActionCloseWindow, "close"},
{ActionMaximizeWindow, "maximize"},
{ActionDoNothing, "ignore"}
};
return _map.value(dcb, "close");
}
DoubleClickBehavior Settings::stringToDoubleClickBehavior(QString str)
{
static QMap<QString, DoubleClickBehavior> _map {
{"close", ActionCloseWindow},
{"maximize", ActionMaximizeWindow},
{"ignore", ActionDoNothing}
};
return _map.value(str, ActionCloseWindow);
}
Settings::Settings()
: QObject(qApp)
{
QString configPath;
QString portableConfigDirPath = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath("data");
QFileInfo portableConfigDirInfo(portableConfigDirPath);
if (portableConfigDirInfo.exists() && portableConfigDirInfo.isDir() && portableConfigDirInfo.isWritable()) {
// we can use it.
configPath = portableConfigDirPath;
}
// %LOCALAPPDATA% under Windows.
if (configPath.isEmpty()) {
configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
}
m_qsettings = new QSettings(QDir(configPath).absoluteFilePath("config.ini"), QSettings::IniFormat, this);
}

41
settings.h Normal file
View File

@ -0,0 +1,41 @@
#pragma once
#include <QObject>
#include <QSettings>
enum DoubleClickBehavior {
ActionDoNothing,
ActionCloseWindow,
ActionMaximizeWindow,
ActionStart = ActionDoNothing,
ActionEnd = ActionMaximizeWindow
};
class Settings : public QObject
{
Q_OBJECT
public:
static Settings *instance();
bool stayOnTop();
DoubleClickBehavior doubleClickBehavior();
void setStayOnTop(bool on);
void setDoubleClickBehavior(DoubleClickBehavior dcb);
static QString doubleClickBehaviorToString(DoubleClickBehavior dcb);
static DoubleClickBehavior stringToDoubleClickBehavior(QString str);
private:
Settings();
static Settings *m_settings_instance;
QSettings *m_qsettings;
signals:
public slots:
};

50
settingsdialog.cpp Normal file
View File

@ -0,0 +1,50 @@
#include "settingsdialog.h"
#include "settings.h"
#include <QCheckBox>
#include <QComboBox>
#include <QFormLayout>
#include <QStringListModel>
SettingsDialog::SettingsDialog(QWidget *parent)
: QDialog(parent)
, m_stayOnTop(new QCheckBox)
, m_doubleClickBehavior(new QComboBox)
{
QFormLayout * settingsForm = new QFormLayout(this);
static QMap<DoubleClickBehavior, QString> _map {
{ ActionDoNothing, tr("Do nothing") },
{ ActionCloseWindow, tr("Close the window") },
{ ActionMaximizeWindow, tr("Toggle maximize") }
};
QStringList dropDown;
for (int dcb = ActionStart; dcb <= ActionEnd; dcb++) {
dropDown.append(_map.value(static_cast<DoubleClickBehavior>(dcb)));
}
settingsForm->addRow(tr("Stay on top when start-up"), m_stayOnTop);
settingsForm->addRow(tr("Double-click behavior"), m_doubleClickBehavior);
m_stayOnTop->setChecked(Settings::instance()->stayOnTop());
m_doubleClickBehavior->setModel(new QStringListModel(dropDown));
DoubleClickBehavior dcb = Settings::instance()->doubleClickBehavior();
m_doubleClickBehavior->setCurrentIndex(static_cast<int>(dcb));
connect(m_stayOnTop, &QCheckBox::stateChanged, this, [ = ](int state){
Settings::instance()->setStayOnTop(state == Qt::Checked);
});
connect(m_doubleClickBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setDoubleClickBehavior(static_cast<DoubleClickBehavior>(index));
});
this->setMinimumSize(300, 61); // not sure why it complain "Unable to set geometry"
}
SettingsDialog::~SettingsDialog()
{
}

26
settingsdialog.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QObject>
#include <QWidget>
#include <QDialog>
class QCheckBox;
class QComboBox;
class SettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit SettingsDialog(QWidget *parent = nullptr);
~SettingsDialog();
signals:
public slots:
private:
QCheckBox * m_stayOnTop = nullptr;
QComboBox * m_doubleClickBehavior = nullptr;
};
#endif // SETTINGSDIALOG_H