diff --git a/README.adoc b/README.adoc index 3ba3480..fd95ad6 100644 --- a/README.adoc +++ b/README.adoc @@ -16,7 +16,7 @@ :uri-dpkg: https://packages.qa.debian.org/dpkg :uri-rpm-build: http://www.rpm.org :uri-clang-tidy: https://clang.llvm.org/extra/clang-tidy/ -:uri-qt-install: https://doc.qt.io/qt-5/gettingstarted.html +:uri-qt: https://doc.qt.io/qt-5/gettingstarted.html *{project}* is a client for link:{uri-wp-fediverse}[Fediverse] servers. // It currently supports link:{uri-wp-mastodon}[Mastodon] and @@ -64,7 +64,7 @@ link:{uri-clang}[clang] 6/7) * link:{uri-cmake}[CMake] (at least: 3.9) * link:{uri-mastodonpp}[mastodonpp] (at least: 0.5) -* link:{uri-qt-install}[Qt] with QtQuick (at least: 5.10) +* link:{uri-qt}[Qt] (tested: 5.13) * Optional ** Library documentation: link:{uri-doxygen}[Doxygen] (tested: 1.8) ** Tests: link:{uri-catch}[Catch] (tested: 2.5 / 1.2) diff --git a/gui/FediPotato.qrc b/gui/FediPotato.qrc index e8d7abe..8df7545 100644 --- a/gui/FediPotato.qrc +++ b/gui/FediPotato.qrc @@ -1,8 +1,6 @@ - qml/mainwindow.qml - qml/DialogAbout.qml ../AUTHORS diff --git a/gui/qml/DialogAbout.qml b/gui/qml/DialogAbout.qml deleted file mode 100644 index bcdc4ba..0000000 --- a/gui/qml/DialogAbout.qml +++ /dev/null @@ -1,68 +0,0 @@ -import QtQuick 2.10 -import QtQuick.Controls 2.3 -import QtQuick.Window 2.2 -import QtQuick.Layouts 1.3 - -Window -{ - id: win_about - title: qsTr("About FediPotato") + " " + QMLBridge.get_version() - flags: Qt.Dialog - modality: Qt.NonModal - minimumWidth: label_description.width * 2 - minimumHeight: label_description.width - - TabBar - { - id: tabbar_about - width: parent.width - - TabButton - { - text: qsTr("About") - } - - TabButton - { - text: qsTr("Authors") - } - } - - StackLayout { - id: layout_about - anchors.top: tabbar_about.bottom - width: parent.width - currentIndex: tabbar_about.currentIndex - - ColumnLayout - { - width: parent.width - - Label - { - id: label_description - text: "" + qsTr("Client for Fediverse servers.") + "" - } - - Label - { - id: label_license - Layout.fillWidth: true - wrapMode: Text.WordWrap - onLinkActivated: Qt.openUrlExternally(link) - text: qsTr("License AGPL-3.0-only: " + - "GNU Affero GPL version 3.
" + - "This program comes with ABSOLUTELY NO WARRANTY. " + - "This is free software, and you are welcome to " + - "redistribute it under certain conditions.") - } - } - - Label - { - id: label_authors - text: QMLBridge.get_authors() - } - } -} diff --git a/gui/qml/mainwindow.qml b/gui/qml/mainwindow.qml deleted file mode 100644 index 3b90790..0000000 --- a/gui/qml/mainwindow.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.10 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.3 - -ApplicationWindow -{ - id: win_main - title: "FediPotato" - visible: true - width: 400 - height: 500 - - menuBar: MenuBar - { - Menu - { - title: "&FediPotato" - MenuItem - { - id: menu_exit - text: qsTr("Exit") - onTriggered: Qt.quit() - - Shortcut - { - sequence: "Ctrl+Q" - context: Qt.ApplicationShortcut - onActivated: menu_exit.clicked() - } - } - } - - Menu - { - title: qsTr("&Help") - MenuItem - { - text: qsTr("Website") - onTriggered: Qt.openUrlExternally("http://fedipotato.org/") - } - MenuItem - { - text: qsTr("About FediPotato") - onTriggered: win_about.show() - - DialogAbout { id: win_about } - } - } - } -} diff --git a/gui/src/CMakeLists.txt b/gui/src/CMakeLists.txt index 0b6b528..797c8c4 100644 --- a/gui/src/CMakeLists.txt +++ b/gui/src/CMakeLists.txt @@ -1,9 +1,10 @@ include(GNUInstallDirs) set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) -find_package(Qt5 5.10 COMPONENTS Core Gui Qml Quick CONFIG REQUIRED) +find_package(Qt5 COMPONENTS Core Gui Widgets CONFIG REQUIRED) add_executable(${PROJECT_NAME}GUI) @@ -16,7 +17,7 @@ target_sources(${PROJECT_NAME}GUI PRIVATE "${sources_gui}" "../${PROJECT_NAME}.qrc") target_link_libraries(${PROJECT_NAME}GUI - PRIVATE ${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Qml Qt5::Quick) + PRIVATE ${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Widgets) install(TARGETS ${PROJECT_NAME}GUI DESTINATION "${CMAKE_INSTALL_BINDIR}") diff --git a/gui/src/dialog_about.cpp b/gui/src/dialog_about.cpp new file mode 100644 index 0000000..7c30a31 --- /dev/null +++ b/gui/src/dialog_about.cpp @@ -0,0 +1,29 @@ +#include "dialog_about.hpp" + +#include + +namespace FediPotato +{ + +DialogAbout::DialogAbout(QDialog *parent) + : QDialog(parent) +{ + setupUi(this); + + display_authors(); +} + +void DialogAbout::display_authors() const +{ + QFile file(":/AUTHORS"); + if (file.open(QIODevice::ReadOnly)) + { + label_authors->setText(file.readAll()); + } + else + { + label_authors->setText(tr("Could not open :/AUTHORS.")); + } +} + +} // namespace FediPotato diff --git a/gui/src/dialog_about.hpp b/gui/src/dialog_about.hpp new file mode 100644 index 0000000..85beeb3 --- /dev/null +++ b/gui/src/dialog_about.hpp @@ -0,0 +1,41 @@ +#ifndef FEDIPOTATO_GUI_DIALOG_ABOUT_HPP +#define FEDIPOTATO_GUI_DIALOG_ABOUT_HPP + +#include "../ui/ui_dialog_about.h" + +#include +#include + +namespace FediPotato +{ + +class DialogAbout : public QDialog, private Ui::DialogAbout +{ +public: + //! Default constructor + explicit DialogAbout(QDialog *parent = nullptr); + + //! Copy constructor + DialogAbout(const DialogAbout &other) = delete; + + //! Move constructor + DialogAbout(DialogAbout &&other) noexcept = delete; + + //! Destructor + ~DialogAbout() noexcept override = default; + + //! Copy assignment operator + DialogAbout& operator=(const DialogAbout &other) = delete; + + //! Move assignment operator + DialogAbout& operator=(DialogAbout &&other) noexcept = delete; + +public: + +private: + void display_authors() const; +}; + +} // namespace FediPotato + +#endif // FEDIPOTATO_GUI_DIALOG_ABOUT_HPP diff --git a/gui/src/main.cpp b/gui/src/main.cpp index 9a8ce63..fb6b0ec 100644 --- a/gui/src/main.cpp +++ b/gui/src/main.cpp @@ -14,24 +14,31 @@ * along with this program. If not, see . */ -#include "qmlbridge.hpp" +#include "window_main.hpp" #include -#include -#include +#include +#include using namespace FediPotato; int main(int argc, char *argv[]) { - QGuiApplication app(argc, argv); + QApplication app(argc, argv); + QGuiApplication::setApplicationName("FediPotato"); - QMLBridge qmlbridge; + QTranslator qtTranslator; + qtTranslator.load("qt_" + QLocale::system().name(), + QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + QGuiApplication::installTranslator(&qtTranslator); - QQmlApplicationEngine engine; - // Make qmlbridge callable as QMLBridge in QML files. - engine.rootContext()->setContextProperty("QMLBridge", &qmlbridge); - engine.load(QUrl(QStringLiteral("qrc:/qml/mainwindow.qml"))); + QTranslator appTranslator; + appTranslator.load("FediPotato_" + QLocale::system().name(), + QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + QGuiApplication::installTranslator(&appTranslator); + + WindowMain win; + win.show(); return QGuiApplication::exec(); } diff --git a/gui/src/qmlbridge.hpp b/gui/src/qmlbridge.hpp deleted file mode 100644 index 9b56746..0000000 --- a/gui/src/qmlbridge.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is part of FediPotato. - * Copyright © 2020 tastytea - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef FEDIPOTATO_GUI_QMLBRIDGE_HPP -#define FEDIPOTATO_GUI_QMLBRIDGE_HPP - -#include -#include - -namespace FediPotato -{ - -class QMLBridge : public QObject -{ - Q_OBJECT - -public: - explicit QMLBridge(QObject *parent = nullptr); - - /*! - * @brief Return the version. - * - * @since 0.1.0 - */ - Q_INVOKABLE static QString get_version(); - - /*! - * @brief Return the authors listed in AUTHORS. - * - * @since 0.1.0 - */ - Q_INVOKABLE static QString get_authors(); -}; - -} // namespace FediPotato - -#endif // FEDIPOTATO_GUI_QMLBRIDGE_HPP diff --git a/gui/src/qmlbridge.cpp b/gui/src/window_main.cpp similarity index 65% rename from gui/src/qmlbridge.cpp rename to gui/src/window_main.cpp index a881552..2cc766a 100644 --- a/gui/src/qmlbridge.cpp +++ b/gui/src/window_main.cpp @@ -14,32 +14,31 @@ * along with this program. If not, see . */ -#include "qmlbridge.hpp" -#include "fedipotato.hpp" +#include "window_main.hpp" +#include "dialog_about.hpp" -#include +#include +#include namespace FediPotato { -QMLBridge::QMLBridge(QObject *parent) - : QObject(parent) -{} - -QString QMLBridge::get_version() +WindowMain::WindowMain(QMainWindow *parent) + : QMainWindow(parent) { - return FediPotato::get_version().data(); + setupUi(this); } -QString QMLBridge::get_authors() +void WindowMain::show_about() { - QFile file(":/AUTHORS"); - if (file.open(QIODevice::ReadOnly)) - { - return file.readAll(); - } - - return "Could not open :/AUTHORS."; + auto *dlg = new DialogAbout(); // NOLINT(cppcoreguidelines-owning-memory) + dlg->show(); } +void WindowMain::open_website() +{ + QDesktopServices::openUrl(QUrl("http://fedipotato.org/")); +} + + } // namespace FediPotato diff --git a/gui/src/window_main.hpp b/gui/src/window_main.hpp new file mode 100644 index 0000000..20f0056 --- /dev/null +++ b/gui/src/window_main.hpp @@ -0,0 +1,44 @@ +#ifndef FEDIPOTATO_GUI_WINDOW_MAIN_HPP +#define FEDIPOTATO_GUI_WINDOW_MAIN_HPP + +#include "../ui/ui_window_main.h" + +#include +#include + +namespace FediPotato +{ + +class WindowMain : public QMainWindow, private Ui::WindowMain +{ + Q_OBJECT + +public: + //! Default constructor + explicit WindowMain(QMainWindow *parent = nullptr); + + //! Copy constructor + WindowMain(const WindowMain &other) = delete; + + //! Move constructor + WindowMain(WindowMain &&other) noexcept = delete; + + //! Destructor + ~WindowMain() noexcept override = default; + + //! Copy assignment operator + WindowMain& operator=(const WindowMain &other) = delete; + + //! Move assignment operator + WindowMain& operator=(WindowMain &&other) noexcept = delete; + +public: + +private slots: + static void show_about(); + static void open_website(); +}; + +} // namespace FediPotato + +#endif // FEDIPOTATO_GUI_WINDOW_MAIN_HPP diff --git a/gui/ui/dialog_about.ui b/gui/ui/dialog_about.ui new file mode 100644 index 0000000..33251cf --- /dev/null +++ b/gui/ui/dialog_about.ui @@ -0,0 +1,134 @@ + + + DialogAbout + + + + 0 + 0 + 400 + 187 + + + + + 0 + 0 + + + + About FediPotato + + + + + + + 0 + 0 + + + + 0 + + + + About + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + <b>Client for Fediverse servers.</b> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + 0 + 0 + + + + License AGPL-3.0-only: <a href="https://www.gnu.org/licenses/agpl-3.0.txt"> GNU Affero GPL version 3</a>.<br> + This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse + + + + + + + + Authors + + + + QLayout::SetDefaultConstraint + + + + + true + + + + + 0 + 0 + 358 + 116 + + + + + + + + 0 + 0 + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + + + + + + + diff --git a/gui/ui/window_main.ui b/gui/ui/window_main.ui new file mode 100644 index 0000000..811179c --- /dev/null +++ b/gui/ui/window_main.ui @@ -0,0 +1,117 @@ + + + WindowMain + + + + 0 + 0 + 800 + 600 + + + + FediPotato + + + + + + 0 + 0 + 800 + 23 + + + + + &FediPotato + + + + + + &Help + + + + + + + + + + + Quit + + + Ctrl+Q + + + + + Website + + + + + About FediPotato + + + + + + + action_about + triggered() + WindowMain + show_about() + + + -1 + -1 + + + 399 + 299 + + + + + action_quit + triggered() + WindowMain + close() + + + -1 + -1 + + + 399 + 299 + + + + + action_website + triggered() + WindowMain + open_website() + + + -1 + -1 + + + 399 + 299 + + + + + + show_about() + open_website() + +