Compare commits

...

5 Commits

11 changed files with 247 additions and 22 deletions

83
.gitignore vendored Normal file
View File

@ -0,0 +1,83 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
*.qbs.user*
CMakeLists.txt.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
# Directories with generated files
.moc/
.obj/
.pch/
.rcc/
.uic/
/build*/
_build*/

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
set(TARGET_APP "GenericWidgets") set(TARGET_APP "GenericQtClient-Widgets")
project(${TARGET_APP} VERSION 0.0.1 LANGUAGES CXX) project(${TARGET_APP} VERSION 0.0.2 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
@ -28,27 +28,28 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
MANUAL_FINALIZATION MANUAL_FINALIZATION
${PROJECT_SOURCES} ${PROJECT_SOURCES}
utils/messagehandler.h utils/messagehandler.h
assets/icons.qrc
) )
# Define target properties for Android with Qt 6 as: # Define target properties for Android with Qt 6 as:
# set_property(TARGET ${TARGET_APP} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR # set_property(TARGET ${TARGET_APP} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android) # ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation # For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else() else()
if(ANDROID) if(ANDROID)
add_library(${TARGET_APP} SHARED add_library(${TARGET_APP} SHARED
${PROJECT_SOURCES} ${PROJECT_SOURCES}
) )
# Define properties for Android with Qt 5 after find_package() calls as: # Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") # set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else() else()
add_executable(${TARGET_APP} add_executable(${TARGET_APP}
${PROJECT_SOURCES} ${PROJECT_SOURCES}
) )
endif() endif()
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES}) qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif() endif()
target_link_libraries(${TARGET_APP} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) target_link_libraries(${TARGET_APP} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

BIN
assets/feature.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

7
assets/icons.qrc Normal file
View File

@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/">
<file>software-application.png</file>
<file>feature.png</file>
<file>no-picture-taking.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

5
assets/urls.txt Normal file
View File

@ -0,0 +1,5 @@
software-application.png:
https://www.flaticon.com/free-icon/software-application_5063917
feature.png:
https://www.flaticon.com/free-icon/feature_1085784

View File

@ -1,19 +1,108 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "./ui_mainwindow.h" #include "./ui_mainwindow.h"
#include "../../libs/GenericCore/genericcore.h" #include <QCloseEvent>
#include <QMessageBox>
#include "data/settingshandler.h"
#include "genericcore.h"
static QString updateTextClean = "Do you want to update the application now?";
static QString updateTextDirty = "Do you want to save the tasks & update the application now?";
MainWindow::MainWindow(QWidget* parent) MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::MainWindow) { , ui(new Ui::MainWindow) {
ui->setupUi(this); ui->setupUi(this);
m_core = std::make_shared<GenericCore>(); m_core = new GenericCore();
/// application icon
const QString iconString = "://feature.png";
#ifdef QT_DEBUG
QPixmap pixmap = QPixmap(iconString);
QTransform transform = QTransform();
transform.rotate(180);
QPixmap rotated = pixmap.transformed(transform);
setWindowIcon(QIcon(rotated));
#else
setWindowIcon(QIcon(iconString));
#endif
/// TODO restore window geometry and state (& save it in closeEvent)
const QVariantMap settings = SettingsHandler::getSettings("GUI");
restoreGeometry(settings.value("geometry").toByteArray());
restoreState(settings.value("windowState").toByteArray());
connect(m_core, &GenericCore::displayStatusMessage, this, &MainWindow::displayStatusMessage);
connect(this, &MainWindow::displayStatusMessage, this, &MainWindow::showStatusMessage);
connect(this, &MainWindow::checkForUpdates, this,
&MainWindow::on_actionCheck_for_update_triggered, Qt::QueuedConnection);
} }
MainWindow::~MainWindow() { delete ui; } MainWindow::~MainWindow() {
delete ui;
delete m_core;
}
void MainWindow::on_pushButton_clicked() { void MainWindow::on_pushButton_clicked() {
const QString prefix("Backend provided by: "); const QString prefix("Backend provided by: ");
ui->label->setText(prefix + m_core->toString()); ui->label->setText(prefix + m_core->toString());
} }
void MainWindow::showStatusMessage(const QString text) {
qInfo() << text;
ui->statusbar->showMessage(text);
}
void MainWindow::on_actionCheck_for_update_triggered() {
showStatusMessage("Checking for update...");
const bool updateAvailable = m_core->isApplicationUpdateAvailable();
if (updateAvailable) {
const QString text = isWindowModified() ? updateTextDirty : updateTextClean;
const QMessageBox::StandardButton clickedButton = QMessageBox::question(
this, tr("Update available."), text, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (clickedButton == QMessageBox::Yes) {
m_core->triggerApplicationUpdate();
close();
}
}
}
void MainWindow::closeEvent(QCloseEvent* event) {
if (isWindowModified()) {
QMessageBox msgBox;
msgBox.setWindowTitle(windowTitle() + " - Save dialog");
msgBox.setText("The document has been modified.");
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Save:
// TODO m_core->saveItems();
event->accept();
break;
case QMessageBox::Discard:
event->accept();
break;
case QMessageBox::Cancel:
event->ignore();
break;
default:
/// should never be reached
qCritical() << "unexpected switch case in closeEvent:" << ret;
event->ignore();
break;
}
} else {
event->accept();
}
if (event->isAccepted()) {
qInfo() << "Saving GUI settings...";
SettingsHandler::saveSettings({{"geometry", saveGeometry()}, {"windowState", saveState()}},
"GUI");
}
}

View File

@ -19,12 +19,22 @@ class MainWindow : public QMainWindow {
MainWindow(QWidget* parent = nullptr); MainWindow(QWidget* parent = nullptr);
~MainWindow(); ~MainWindow();
signals:
void displayStatusMessage(QString message);
void checkForUpdates();
protected:
void closeEvent(QCloseEvent* event) override;
private slots: private slots:
void showStatusMessage(const QString text);
void on_pushButton_clicked(); void on_pushButton_clicked();
void on_actionCheck_for_update_triggered();
private: private:
Ui::MainWindow* ui; Ui::MainWindow* ui;
std::shared_ptr<GenericCore> m_core; GenericCore* m_core;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>MainWindow</string> <string>GenericQtClient</string>
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@ -40,8 +40,38 @@
<height>25</height> <height>25</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
</widget>
<widget class="QMenu" name="menu_Edit">
<property name="title">
<string>&amp;Edit</string>
</property>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
<string>&amp;View</string>
</property>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="actionCheck_for_update"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Edit"/>
<addaction name="menu_View"/>
<addaction name="menu_Help"/>
</widget> </widget>
<widget class="QStatusBar" name="statusbar"/> <widget class="QStatusBar" name="statusbar"/>
<action name="actionCheck_for_update">
<property name="text">
<string>Check for &amp;update</string>
</property>
</action>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>