diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..4bdb1cb --- /dev/null +++ b/.clang-format @@ -0,0 +1,17 @@ +--- +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignEscapedNewlines: DontAlign +AlignTrailingComments: true +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterFunction: true +BreakConstructorInitializers: BeforeComma +ColumnLimit: 104 +FixNamespaceComments: true +IndentWidth: 4 +SortIncludes: false + +... diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1ac8491 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# EditorConfig configuration +# http://editorconfig.org + +# Top-most EditorConfig file +root = true + +# UTF-8 charset, set indent to spaces with width of four, +# with no trailing whitespaces and a newline ending every file. +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{html,json,md,yml,sh}] +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1d99851 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +# See https://help.github.com/en/articles/dealing-with-line-endings + +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.svgz binary diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..dab7e43 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,72 @@ +name: Build +on: + push: + branches: + - '*' + tags: + - '[0-9]*' + pull_request: + branches: + - '*' +defaults: + run: + shell: bash +env: + build_type: Release +jobs: + linux: + name: Linux + runs-on: ubuntu-latest + strategy: + matrix: + config: + - { name: "GCC", cc: gcc, cxx: g++ } + - { name: "clang", cc: clang, cxx: clang++ } + env: + cc: ${{ matrix.config.cc }} + cxx: ${{ matrix.config.cxx }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Checkout Qtilitools + uses: actions/checkout@v3 + with: + repository: qtilities/qtilitools + path: qtilitools + + - name: Update Packages + run: sudo apt-get update + + - name: Install Dependencies + run: | + packages=( + qtbase5-dev + qttools5-dev + ) + sudo apt-get install ${packages[@]} + + - name: Build and install Qtilitools + working-directory: ${{ github.workspace }}/qtilitools + run: | + options=( + -D CMAKE_INSTALL_PREFIX="/usr" + -D CMAKE_BUILD_TYPE=${{ env.build_type }} + -B build + ) + cmake ${options[@]} + sudo cmake --install build + + - name: Configure + run: | + options=( + -D CMAKE_INSTALL_PREFIX="/usr" + -D CMAKE_BUILD_TYPE=${{ env.build_type }} + -B build + ) + cmake ${options[@]} + + - name: Build + run: cmake --build build --config ${{ env.build_type }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f59c469 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build*/ +*.user +compile_commands.json +resources/about.md diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..5768f9c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,11 @@ +## Special Thanks to + +- Stefonarch (Standreas) and the translation team at . +- LXQt Developers, for all their software, here using their [build tools]. + +## Translators + +- **Italian**: Andrea Zanellato (author) + + +[build tools]: https://github.com/lxqt/lxqt-build-tools/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c0464e7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,133 @@ +cmake_minimum_required(VERSION 3.15) +project(Sqeleton + VERSION 0.1.1 + LANGUAGES CXX +) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +#=============================================================================== +# Qt +#=============================================================================== +option(PROJECT_TRANSLATIONS_UPDATE "Update source translations [default: OFF]" OFF) +set(PROJECT_QT_VERSION 5 CACHE STRING "Qt version to use [default: 5]") +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +find_package(QT NAMES Qt${PROJECT_QT_VERSION}) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED LinguistTools Widgets) +find_package(Qtilitools REQUIRED) +#=============================================================================== +# Project files +#=============================================================================== +set(PROJECT_SOURCES + src/application.hpp + src/application.cpp + src/litebutton.hpp + src/litebutton.cpp + src/dialogabout.hpp + src/dialogabout.cpp + src/dialogprefs.hpp + src/dialogprefs.cpp + src/mainwindow.hpp + src/mainwindow.cpp + src/qtilities.hpp + src/settings.hpp + src/settings.cpp +) +set(PROJECT_UI_FILES + src/dialogabout.ui + src/dialogprefs.ui + src/mainwindow.ui +) +set(PROJECT_OTHER_FILES + .github/workflows/build.yml + .clang-format + .editorconfig + .gitattributes + .gitignore + README.md +) +source_group("Other Files" FILES ${PROJECT_OTHER_FILES}) +source_group("UI Files" FILES ${PROJECT_UI_FILES}) +#=============================================================================== +# Resources +#=============================================================================== +include(Config.cmake) +include(QtAppResources) +#=============================================================================== +# Application executable +#=============================================================================== +set(PROJECT_ALL_FILES + ${PROJECT_DESKTOP_FILES} + ${PROJECT_RESOURCES} + ${PROJECT_SOURCES} + ${PROJECT_OTHER_FILES} + ${PROJECT_QM_FILES} + ${PROJECT_TRANSLATION_SOURCES} + ${PROJECT_UI_FILES} +) +if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(${PROJECT_NAME} MANUAL_FINALIZATION ${PROJECT_ALL_FILES}) +else() + if(ANDROID) + add_library(${PROJECT_NAME} SHARED ${PROJECT_ALL_FILES}) + else() + add_executable(${PROJECT_NAME} ${PROJECT_ALL_FILES}) + endif() +endif() + +target_link_libraries(${PROJECT_NAME} PRIVATE + Qt::Widgets +) +set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_ID}") + +target_compile_definitions(${PROJECT_NAME} PRIVATE + APPLICATION_NAME="${PROJECT_NAME}" + ORGANIZATION_NAME="${PROJECT_ORGANIZATION_NAME}" + ORGANIZATION_DOMAIN="${PROJECT_ORGANIZATION_URL}" + PROJECT_ID="${PROJECT_ID}" + PROJECT_DATA_DIR="${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_ID}" + PROJECT_ICON_NAME="${PROJECT_ICON_FILE_NAME}" + PROJECT_ICON_SYSTEM_PATH="${PROJECT_ICON_FILE_PATH}/${PROJECT_ICON_FILE_NAME}" +) +#=============================================================================== +# Install application +#=============================================================================== +if (UNIX AND NOT APPLE) + install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) +else() + set_target_properties(${PROJECT_NAME} PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER ${PROJECT_ORGANIZATION_URL} + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE + ) + install(TARGETS ${PROJECT_NAME} + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) +endif() +#=============================================================================== +# Project information +#=============================================================================== +message(STATUS " +Project name: ${PROJECT_NAME} +AppStream ID: ${PROJECT_APPSTREAM_ID} +Version: ${PROJECT_VERSION} +Qt version: ${QT_VERSION} +Build type: ${CMAKE_BUILD_TYPE} +Install prefix: ${CMAKE_INSTALL_PREFIX} +Update translations before build: ${PROJECT_TRANSLATIONS_UPDATE} + +CXX Debug flags: ${CMAKE_CXX_FLAGS_DEBUG} +CXX Release flags: ${CMAKE_CXX_FLAGS_RELEASE} +CXX MinSize flags: ${CMAKE_CXX_FLAGS_MINSIZEREL} +CXX RelWithDebInfo flags: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} +") + +if(QT_VERSION_MAJOR EQUAL 6) + qt_finalize_executable(${PROJECT_NAME}) +endif() diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..9d00415 --- /dev/null +++ b/COPYING @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-2023 Andrea Zanellato + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Config.cmake b/Config.cmake new file mode 100644 index 0000000..c4a620e --- /dev/null +++ b/Config.cmake @@ -0,0 +1,40 @@ +#=============================================================================== +# Editable project configuration +# +# Essential, non translatable application information (except DESCRIPTION). +# Translatable strings are passed via code. +#=============================================================================== +string(TOLOWER ${PROJECT_NAME} PROJECT_ID) # Might not be compatible with AppStream +list(APPEND PROJECT_CATEGORIES "Qt;Utility") # Freedesktop menu categories +list(APPEND PROJECT_KEYWORDS "application;project;template") +set(PROJECT_AUTHOR_NAME "Andrea Zanellato") +set(PROJECT_AUTHOR_EMAIL "redtid3@gmail.com") # Used also for organization email +set(PROJECT_COPYRIGHT_YEAR "2021-2023") # TODO: from git +set(PROJECT_DESCRIPTION "Qt application template") +set(PROJECT_ORGANIZATION_NAME "qtilities") # Might be equal to PROJECT_AUTHOR_NAME +set(PROJECT_ORGANIZATION_URL "${PROJECT_ORGANIZATION_NAME}.github.io") +set(PROJECT_HOMEPAGE_URL "https://${PROJECT_ORGANIZATION_URL}/${PROJECT_ID}") +set(PROJECT_REPOSITORY_URL "https://github.com/${PROJECT_ORGANIZATION_NAME}/${PROJECT_ID}") +set(PROJECT_REPOSITORY_BRANCH "master") +set(PROJECT_SPDX_ID "MIT") +set(PROJECT_TRANSLATIONS_DIR "resources/translations") +#=============================================================================== +# Appstream +#=============================================================================== +set(PROJECT_APPSTREAM_SPDX_ID "CC0-1.0") +include(AppStream) +to_appstream_id("io.github.${PROJECT_ORGANIZATION_NAME}.${PROJECT_NAME}" + PROJECT_APPSTREAM_ID) + +set(PROJECT_ICON_FORMAT "svg") +if(UNIX AND NOT APPLE) + set(PROJECT_ICON_FILE_NAME "${PROJECT_APPSTREAM_ID}.${PROJECT_ICON_FORMAT}") +elseif(APPLE) + # TODO: macOS and Windows +else() +endif() +#=============================================================================== +# Adapt to CMake variables +#=============================================================================== +set(${PROJECT_NAME}_DESCRIPTION "${PROJECT_DESCRIPTION}") +set(${PROJECT_NAME}_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}") diff --git a/README.md b/README.md new file mode 100644 index 0000000..68d9cb1 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# Sqeleton + +[![CI]](https://github.com/qtilities/sqeleton/actions/workflows/build.yml) + +## Overview + +Qt application template repository. + +See the related [website page] for further information. + +## Features + +- Resource management following the Freedesktop [Desktop Entry] Specification + file naming convention (icons, desktop and appdata files) +- [Appstream] metadata information +- Locale translations via [LXQt build tools] +- Install step + +## Dependencies + +Runtime: + +- Qt5/6 base + +Build: + +- CMake +- Qt Linguist Tools +- Git (optional, to pull latest VCS checkouts) + +## Build + +`CMAKE_BUILD_TYPE` is usually set to `Release`, though `None` might be a [valid alternative][2].
+`CMAKE_INSTALL_PREFIX` has to be set to `/usr` on most operating systems.
+Using `sudo make install` is discouraged, instead use the system package manager where possible. + +```bash +cmake -B build -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr -W no-dev +cmake --build build --verbose +DESTDIR="$(pwd)/package" cmake --install build +``` + +## Licenses + +- Sqeleton is licensed under the [MIT] license. +- Application icon is from [Openclipart], [CC0-1.0] license. + + +[Appstream]: https://freedesktop.org/software/appstream/docs/chap-Quickstart.html +[CC0-1.0]: https://creativecommons.org/publicdomain/zero/1.0/ +[CI]: https://github.com/qtilities/sqeleton/actions/workflows/build.yml/badge.svg +[Desktop Entry]: https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s02.html +[LXQt build tools]: https://github.com/lxqt/lxqt-build-tools +[MIT]: COPYING +[Openclipart]: https://openclipart.org/ +[website page]: https://qtilities.github.io/sqeleton/ diff --git a/resources/about.info.md.in b/resources/about.info.md.in new file mode 100644 index 0000000..2e1b5db --- /dev/null +++ b/resources/about.info.md.in @@ -0,0 +1,7 @@ +# @PROJECT_NAME@ v@PROJECT_VERSION@ + +@PROJECT_DESCRIPTION@ + +<@PROJECT_HOMEPAGE_URL@> + +__AUTHOR__: @PROJECT_AUTHOR_NAME@ diff --git a/resources/authors b/resources/authors new file mode 120000 index 0000000..9eadf71 --- /dev/null +++ b/resources/authors @@ -0,0 +1 @@ +../AUTHORS \ No newline at end of file diff --git a/resources/copying b/resources/copying new file mode 120000 index 0000000..012065c --- /dev/null +++ b/resources/copying @@ -0,0 +1 @@ +../COPYING \ No newline at end of file diff --git a/resources/freedesktop/application.appdata.xml.in b/resources/freedesktop/application.appdata.xml.in new file mode 100644 index 0000000..35807cc --- /dev/null +++ b/resources/freedesktop/application.appdata.xml.in @@ -0,0 +1,26 @@ + + + @PROJECT_APPSTREAM_ID@ + @PROJECT_APPSTREAM_SPDX_ID@ + @PROJECT_SPDX_ID@ + @PROJECT_NAME@ + @PROJECT_DESCRIPTION@ + +@PROJECT_DESCRIPTION_HTML@ + @PROJECT_ORGANIZATION_NAME@ + @PROJECT_AUTHOR_NAME@ + @PROJECT_AUTHOR_EMAIL@ + @PROJECT_HOMEPAGE_URL@ + + + Screenshot + @PROJECT_REPOSITORY_URL@/blob/@PROJECT_REPOSITORY_BRANCH@/resources/screenshot.png + + + + @PROJECT_ID@ + + @PROJECT_APPSTREAM_ID@.desktop +@PROJECT_KEYWORDS_HTML@ +@PROJECT_RELEASES_HTML@ + diff --git a/resources/freedesktop/application.desktop.in b/resources/freedesktop/application.desktop.in new file mode 100644 index 0000000..d9fcc2d --- /dev/null +++ b/resources/freedesktop/application.desktop.in @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Application +Exec=@PROJECT_ID@ +Icon=@PROJECT_APPSTREAM_ID@ +Categories=@PROJECT_CATEGORIES@; + diff --git a/resources/icons/COPYING b/resources/icons/COPYING new file mode 100644 index 0000000..045b62e --- /dev/null +++ b/resources/icons/COPYING @@ -0,0 +1,216 @@ +The Oxygen Icon Theme + Copyright (C) 2007 Nuno Pinheiro + Copyright (C) 2007 David Vignoni + Copyright (C) 2007 David Miller + Copyright (C) 2007 Johann Ollivier Lapeyre + Copyright (C) 2007 Kenneth Wimer + Copyright (C) 2007 Riccardo Iaconelli + + +and others + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . + +Clarification: + + The GNU Lesser General Public License or LGPL is written for + software libraries in the first place. We expressly want the LGPL to + be valid for this artwork library too. + + KDE Oxygen theme icons is a special kind of software library, it is an + artwork library, it's elements can be used in a Graphical User Interface, or + GUI. + + Source code, for this library means: + - where they exist, SVG; + - otherwise, if applicable, the multi-layered formats xcf or psd, or + otherwise png. + + The LGPL in some sections obliges you to make the files carry + notices. With images this is in some cases impossible or hardly useful. + + With this library a notice is placed at a prominent place in the directory + containing the elements. You may follow this practice. + + The exception in section 5 of the GNU Lesser General Public License covers + the use of elements of this art library in a GUI. + + kde-artists [at] kde.org + +----- + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/resources/icons/application-exit.svgz b/resources/icons/application-exit.svgz new file mode 100644 index 0000000..0ffd56b Binary files /dev/null and b/resources/icons/application-exit.svgz differ diff --git a/resources/icons/application.icon b/resources/icons/application.icon new file mode 100644 index 0000000..28d32fa --- /dev/null +++ b/resources/icons/application.icon @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + \ No newline at end of file diff --git a/resources/icons/help-about.svgz b/resources/icons/help-about.svgz new file mode 100644 index 0000000..001aa7f Binary files /dev/null and b/resources/icons/help-about.svgz differ diff --git a/resources/icons/preferences-system.svgz b/resources/icons/preferences-system.svgz new file mode 100644 index 0000000..b58b30e Binary files /dev/null and b/resources/icons/preferences-system.svgz differ diff --git a/resources/resources.qrc b/resources/resources.qrc new file mode 100644 index 0000000..ab4adae --- /dev/null +++ b/resources/resources.qrc @@ -0,0 +1,10 @@ + + + icons/application-exit.svgz + icons/help-about.svgz + icons/preferences-system.svgz + about.md + authors + copying + + diff --git a/resources/translations/sqeleton.desktop.yaml b/resources/translations/sqeleton.desktop.yaml new file mode 100644 index 0000000..74b1971 --- /dev/null +++ b/resources/translations/sqeleton.desktop.yaml @@ -0,0 +1,3 @@ +Desktop Entry/Name: "Sqeleton" +Desktop Entry/GenericName: "Application Template" +Desktop Entry/Comment: "Qt application template" diff --git a/resources/translations/sqeleton.ts b/resources/translations/sqeleton.ts new file mode 100644 index 0000000..6b30d92 --- /dev/null +++ b/resources/translations/sqeleton.ts @@ -0,0 +1,108 @@ + + + + + Qtilities::DialogAbout + + + Information + + + + + qrc:/about.html + + + + + Thanks + + + + + qrc:/thanks.html + + + + + License + + + + + qrc:/license.html + + + + + About + + + + + Author + + + + + Qtilities::DialogPrefs + + + Colors + + + + + Background + + + + + Text + + + + + Preferences + + + + + Qtilities::MainWindow + + + Hello! + + + + + &Edit + + + + + &Help + + + + + &File + + + + + Pr&eferences + + + + + About + + + + + E&xit + + + + diff --git a/resources/translations/sqeleton_it.desktop.yaml b/resources/translations/sqeleton_it.desktop.yaml new file mode 100644 index 0000000..874ee95 --- /dev/null +++ b/resources/translations/sqeleton_it.desktop.yaml @@ -0,0 +1,3 @@ +Desktop Entry/Name: "Sqeleton" +Desktop Entry/GenericName: "Modello Applicazione" +Desktop Entry/Comment: "Modello di applicazione in Qt" diff --git a/resources/translations/sqeleton_it.ts b/resources/translations/sqeleton_it.ts new file mode 100644 index 0000000..b256271 --- /dev/null +++ b/resources/translations/sqeleton_it.ts @@ -0,0 +1,108 @@ + + + + + Qtilities::DialogAbout + + + Information + Informazioni + + + + qrc:/about.html + qrc:/about.html + + + + Thanks + Ringraziamenti + + + + qrc:/thanks.html + qrc:/thanks.html + + + + License + Licenza + + + + qrc:/license.html + qrc:/license.html + + + + About + Informazioni + + + + Author + Autore + + + + Qtilities::DialogPrefs + + + Colors + Colori + + + + Text + Testo + + + + Background + Sfondo + + + + Preferences + Preferenze + + + + Qtilities::MainWindow + + + Hello! + Ciao! + + + + &Edit + &Modifica + + + + &Help + &Aiuto + + + + &File + &File + + + + Pr&eferences + Preferen&ze + + + + About + Informazioni + + + + E&xit + &Esci + + + diff --git a/resources/translations/sqeleton_ko.ts b/resources/translations/sqeleton_ko.ts new file mode 100644 index 0000000..144b15a --- /dev/null +++ b/resources/translations/sqeleton_ko.ts @@ -0,0 +1,108 @@ + + + + + Qtilities::DialogAbout + + + Information + 정보 + + + + qrc:/about.html + qrc:/about.html + + + + Thanks + 감사한 분들 + + + + qrc:/thanks.html + qrc:/thanks.html + + + + License + 라이선스 + + + + qrc:/license.html + qrc:/license.html + + + + About + 정보 + + + + Author + 작성자 + + + + Qtilities::DialogPrefs + + + Colors + 색상 + + + + Background + 배경 + + + + Text + 텍스트 + + + + Preferences + 환경설정 + + + + Qtilities::MainWindow + + + Hello! + 안녕하세요! + + + + &Edit + 편집(&E) + + + + &Help + 도움말(&H) + + + + &File + 파일(&F) + + + + Pr&eferences + 환경설정(&E) + + + + About + 정보 + + + + E&xit + 종료(&X) + + + diff --git a/src/application.cpp b/src/application.cpp new file mode 100755 index 0000000..b71c703 --- /dev/null +++ b/src/application.cpp @@ -0,0 +1,132 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#include "application.hpp" +#include "mainwindow.hpp" +#include "dialogabout.hpp" +#include "dialogprefs.hpp" + +#include +#include +#include +#include + +Qtilities::Application::Application(int argc, char *argv[]) + : QApplication(argc, argv) +{ + setApplicationName(PROJECT_ID); + setApplicationDisplayName(APPLICATION_NAME); + setOrganizationName(ORGANIZATION_NAME); + setOrganizationDomain(ORGANIZATION_DOMAIN); + + initLocale(); + initUi(); +} + +void Qtilities::Application::initLocale() +{ +#if 1 + QLocale locale = QLocale::system(); +#else + QLocale locale(QLocale("it")); + QLocale::setDefault(locale); +#endif + // Qt translations (buttons and the like) + QString translationsPath +#if QT_VERSION < 0x060000 + = QLibraryInfo::location(QLibraryInfo::TranslationsPath); +#else + = QLibraryInfo::path(QLibraryInfo::TranslationsPath); +#endif + QString translationsFileName = QStringLiteral("qt_") + locale.name(); + + if (qtTranslator_.load(translationsFileName, translationsPath)) + installTranslator(&qtTranslator_); + + // E.g. "_en" + translationsFileName = QCoreApplication::applicationName().toLower() + '_' + locale.name(); + + // Try first in the same binary directory, in case we are building, + // otherwise read from system data + translationsPath = QCoreApplication::applicationDirPath(); + + bool isLoaded = translator_.load(translationsFileName, translationsPath); + if (!isLoaded) { + // "/usr/share//translations + isLoaded = translator_.load(translationsFileName, + QStringLiteral(PROJECT_DATA_DIR) + QStringLiteral("/translations")); + } + if (isLoaded) + installTranslator(&translator_); +} + +void Qtilities::Application::initUi() +{ + // UseHighDpiPixmaps is default from Qt6 +#if QT_VERSION < 0x060000 + setAttribute(Qt::AA_UseHighDpiPixmaps, true); +#endif + settings_.load(); + + QString icoLocalPath + = QCoreApplication::applicationDirPath() + '/' + QStringLiteral(PROJECT_ICON_NAME); + QString icoSysPath = QStringLiteral(PROJECT_ICON_SYSTEM_PATH); + + // Try first to find the app icon in the current/build directory + appIcon_ = QIcon(icoLocalPath); + if (appIcon_.isNull()) + appIcon_ = QIcon(icoSysPath); + + mainWindow_ = new Qtilities::MainWindow; + mainWindow_->move(settings_.position()); + mainWindow_->resize(settings_.size()); + mainWindow_->setWindowIcon(appIcon_); + mainWindow_->setWindowTitle(applicationDisplayName()); + mainWindow_->show(); + + connect(this, &QApplication::aboutToQuit, mainWindow_, &QObject::deleteLater); + connect(this, &QApplication::aboutToQuit, this, [this]() { + mainWindow_->saveSettings(); + settings_.save(); + }); +} + +void Qtilities::Application::about() +{ + DialogAbout about(mainWindow_); + about.exec(); +} + +void Qtilities::Application::preferences() +{ + DialogPrefs prefs(mainWindow_); + connect(&prefs, &DialogPrefs::accepted, mainWindow_, &MainWindow::loadSettings); + prefs.loadSettings(); + prefs.exec(); +} + +int main(int argc, char *argv[]) +{ + Qtilities::Application app(argc, argv); + return app.exec(); +} diff --git a/src/application.hpp b/src/application.hpp new file mode 100644 index 0000000..59b016c --- /dev/null +++ b/src/application.hpp @@ -0,0 +1,59 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#pragma once + +#include "settings.hpp" + +#include +#include +#include + +class QMenu; + +namespace Qtilities { + +class MainWindow; +class Application : public QApplication +{ + Q_OBJECT + +public: + Application(int argc, char *argv[]); + void about(); + void preferences(); + QIcon icon() const { return appIcon_; } + Settings &settings() { return settings_; } + +private: + void initLocale(); + void initUi(); + + MainWindow *mainWindow_; + Settings settings_; + + QIcon appIcon_; + QTranslator qtTranslator_; + QTranslator translator_; +}; +} // namespace Qtilities diff --git a/src/dialogabout.cpp b/src/dialogabout.cpp new file mode 100644 index 0000000..742d001 --- /dev/null +++ b/src/dialogabout.cpp @@ -0,0 +1,65 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#include "dialogabout.hpp" +#include "ui_dialogabout.h" + +#include +#include +#include +#include + +Qtilities::DialogAbout::DialogAbout(QWidget *parent) + : QDialog(parent) + , ui(new Qtilities::Ui::DialogAbout) +{ + ui->setupUi(this); + ui->tabInfo->setLayout(ui->layTabInfo); + ui->tabAuthors->setLayout(ui->layTabAuthors); + ui->tabLicense->setLayout(ui->layTabLicense); + + QStringList list = {":/info", ":/authors", ":/license"}; + QStringList texts; + + for (const QString &item : list) { + QFile f(item); + if (!f.open(QFile::ReadOnly | QFile::Text)) { + qDebug() << "Error loading about file" << '\n'; + return; + } + QTextStream in(&f); + texts.append(in.readAll()); + f.close(); + } + QString toTranslate = texts.at(0); + ui->txtInfo->setMarkdown(toTranslate.replace("__AUTHOR__", tr("Author"))); + ui->txtAuthors->setMarkdown(texts.at(1)); + ui->txtLicense->setMarkdown(texts.at(2)); + + setWindowIcon(QIcon::fromTheme("help-about", QIcon(":/help-about"))); + setWindowTitle(tr("About")); + + connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &Qtilities::DialogAbout::close); +} + +Qtilities::DialogAbout::~DialogAbout() { delete ui; } diff --git a/src/dialogabout.hpp b/src/dialogabout.hpp new file mode 100644 index 0000000..5a3e1d8 --- /dev/null +++ b/src/dialogabout.hpp @@ -0,0 +1,43 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#pragma once + +#include + +namespace Qtilities { +namespace Ui { +class DialogAbout; +} +class DialogAbout : public QDialog +{ + Q_OBJECT + +public: + explicit DialogAbout(QWidget *parent = nullptr); + ~DialogAbout(); + +private: + Ui::DialogAbout *ui; +}; +} // namespace Qtilities diff --git a/src/dialogabout.ui b/src/dialogabout.ui new file mode 100644 index 0000000..e45484c --- /dev/null +++ b/src/dialogabout.ui @@ -0,0 +1,215 @@ + + + Qtilities::DialogAbout + + + + 0 + 0 + 480 + 320 + + + + + + + + 0 + 0 + + + + 0 + + + + Information + + + + + 10 + 10 + 441 + 221 + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + false + + + + qrc:/about.html + + + + + + + true + + + true + + + + + + + + + Thanks + + + + + 10 + 10 + 441 + 221 + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + false + + + + + + + qrc:/thanks.html + + + + + + + true + + + true + + + + + + + + + License + + + + + 10 + 10 + 441 + 221 + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + false + + + + + + + qrc:/license.html + + + + + + + true + + + true + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + diff --git a/src/dialogprefs.cpp b/src/dialogprefs.cpp new file mode 100644 index 0000000..5be97d8 --- /dev/null +++ b/src/dialogprefs.cpp @@ -0,0 +1,87 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#include "dialogprefs.hpp" +#include "ui_dialogprefs.h" +#include "application.hpp" +#include "litebutton.hpp" +#include "settings.hpp" + +#include +#include + +Qtilities::DialogPrefs::DialogPrefs(QWidget *parent) + : QDialog(parent) + , ui(new Qtilities::Ui::DialogPrefs) +{ + ui->setupUi(this); + + loadSettings(); + setWindowIcon(QIcon::fromTheme("preferences-system", QIcon(":/preferences-system"))); + setWindowTitle(tr("Preferences")); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &DialogPrefs::accept); + connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &DialogPrefs::reject); + + connect(ui->lbnBgColor, &LiteButton::clicked, this, [this]() { setButtonColor(ui->lbnBgColor); }); + connect(ui->lbnFgColor, &LiteButton::clicked, this, [this]() { setButtonColor(ui->lbnFgColor); }); +} + +Qtilities::DialogPrefs::~DialogPrefs() { delete ui; } + +void Qtilities::DialogPrefs::loadSettings() +{ + Settings &settings = static_cast(qApp)->settings(); + + QColor bgColor = settings.backgroundColor(); + QColor fgColor = settings.foregroundColor(); + + ui->lbnBgColor->setPalette(QPalette(bgColor)); + ui->lbnFgColor->setPalette(QPalette(fgColor)); + + ui->lbnBgColor->setText(bgColor.name()); + ui->lbnFgColor->setText(fgColor.name()); +} + +void Qtilities::DialogPrefs::accept() +{ + Settings &settings = static_cast(qApp)->settings(); + settings.setBackgroundColor(ui->lbnBgColor->palette().color(QPalette::Window)); + settings.setForegroundColor(ui->lbnFgColor->palette().color(QPalette::Window)); + QDialog::accept(); + hide(); +} + +void Qtilities::DialogPrefs::setButtonColor(LiteButton *button) +{ + Settings &settings = static_cast(qApp)->settings(); + QColor initialColor; + button == ui->lbnBgColor ? initialColor = settings.backgroundColor() + : initialColor = settings.foregroundColor(); + + const QColor color = QColorDialog::getColor(initialColor, this); + if (color.isValid()) { + button->setPalette(QPalette(color)); + button->setText(color.name()); + } +} diff --git a/src/dialogprefs.hpp b/src/dialogprefs.hpp new file mode 100644 index 0000000..13653b1 --- /dev/null +++ b/src/dialogprefs.hpp @@ -0,0 +1,49 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#pragma once + +#include + +namespace Qtilities { +namespace Ui { +class DialogPrefs; +} +class LiteButton; +class DialogPrefs : public QDialog +{ + Q_OBJECT + +public: + explicit DialogPrefs(QWidget *parent = nullptr); + ~DialogPrefs(); + + void loadSettings(); + +private: + void accept() override; + void setButtonColor(LiteButton *); + + Ui::DialogPrefs *ui; +}; +} // namespace Qtilities diff --git a/src/dialogprefs.ui b/src/dialogprefs.ui new file mode 100644 index 0000000..6afcb4b --- /dev/null +++ b/src/dialogprefs.ui @@ -0,0 +1,121 @@ + + + Qtilities::DialogPrefs + + + + 0 + 0 + 384 + 256 + + + + + + + 0 + + + + Colors + + + + + 10 + 10 + 341 + 141 + + + + + QLayout::SetNoConstraint + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Background + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Text + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + Qtilities::LiteButton + QLabel +
src/litebutton.hpp
+
+
+ + +
diff --git a/src/litebutton.cpp b/src/litebutton.cpp new file mode 100644 index 0000000..af63dae --- /dev/null +++ b/src/litebutton.cpp @@ -0,0 +1,45 @@ +/* + MIT License + + Copyright (c) 2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#include "litebutton.hpp" + +#include + +Qtilities::LiteButton::LiteButton(QWidget *parent) + : QLabel(parent) +{ + setAutoFillBackground(true); + setFocusPolicy(Qt::StrongFocus); + setFrameShadow(QFrame::Raised); + setFrameShape(QFrame::StyledPanel); +} + +void Qtilities::LiteButton::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Space) + emit clicked(); + + QLabel::keyPressEvent(event); +} + +void Qtilities::LiteButton::mousePressEvent(QMouseEvent *) { emit clicked(); } diff --git a/src/litebutton.hpp b/src/litebutton.hpp new file mode 100644 index 0000000..993b7eb --- /dev/null +++ b/src/litebutton.hpp @@ -0,0 +1,44 @@ +/* + MIT License + + Copyright (c) 2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#pragma once + +#include + +namespace Qtilities { + +class LiteButton : public QLabel +{ + Q_OBJECT + +public: + explicit LiteButton(QWidget *parent = nullptr); + +signals: + void clicked(); + +protected: + void keyPressEvent(QKeyEvent *) override; + void mousePressEvent(QMouseEvent *) override; +}; +} // namespace Qtilities diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 0000000..32d4621 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,65 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#include "mainwindow.hpp" +#include "ui_mainwindow.h" +#include "application.hpp" +#include "dialogabout.hpp" +#include "settings.hpp" + +Qtilities::MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Qtilities::Ui::MainWindow) +{ + ui->setupUi(this); + ui->centralwidget->setLayout(ui->layout); + loadSettings(); + + Application *theApp = static_cast(qApp); + connect(ui->actPrefs, &QAction::triggered, theApp, &Application::preferences); + connect(ui->actAbout, &QAction::triggered, theApp, &Application::about); + connect(ui->actExit, &QAction::triggered, QCoreApplication::instance(), &QCoreApplication::quit); +} + +Qtilities::MainWindow::~MainWindow() { delete ui; } + +void Qtilities::MainWindow::loadSettings() +{ + Settings &settings = static_cast(qApp)->settings(); + ui->centralwidget->setStyleSheet( + QString("background-color:rgb(%1,%2,%3);" + "color:rgb(%4,%5,%6)}") + .arg(settings.backgroundColor().red()) + .arg(settings.backgroundColor().green()) + .arg(settings.backgroundColor().blue()) + .arg(settings.foregroundColor().red()) + .arg(settings.foregroundColor().green()) + .arg(settings.foregroundColor().blue())); +} + +void Qtilities::MainWindow::saveSettings() +{ + Settings &settings = static_cast(qApp)->settings(); + settings.setPosition(pos()); + settings.setSize(size()); +} diff --git a/src/mainwindow.hpp b/src/mainwindow.hpp new file mode 100644 index 0000000..de402bf --- /dev/null +++ b/src/mainwindow.hpp @@ -0,0 +1,46 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#pragma once + +#include + +namespace Qtilities { +namespace Ui { +class MainWindow; +} +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + + void loadSettings(); + void saveSettings(); + +private: + Ui::MainWindow *ui; +}; +} // namespace Qtilities diff --git a/src/mainwindow.ui b/src/mainwindow.ui new file mode 100644 index 0000000..f74ee55 --- /dev/null +++ b/src/mainwindow.ui @@ -0,0 +1,134 @@ + + + Qtilities::MainWindow + + + + 0 + 0 + 256 + 128 + + + + + + + + + + 10 + 10 + 241 + 91 + + + + + 6 + + + 6 + + + 6 + + + 6 + + + + + Hello! + + + Qt::AlignCenter + + + Qt::NoTextInteraction + + + + + + + + + + 0 + 0 + 256 + 22 + + + + + &Edit + + + + + + &Help + + + + + + &File + + + + + + + + + + + .. + + + Pr&eferences + + + Ctrl+Alt+P + + + QAction::PreferencesRole + + + + + + .. + + + About + + + + + + QAction::AboutRole + + + + + + .. + + + E&xit + + + Ctrl+Q + + + QAction::QuitRole + + + + + + diff --git a/src/qtilities.hpp b/src/qtilities.hpp new file mode 100644 index 0000000..983a407 --- /dev/null +++ b/src/qtilities.hpp @@ -0,0 +1,77 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#pragma once + +#include +#include +#include +#include +#include +#include + +#ifndef QSL +#define QSL(x) QStringLiteral(x) +#endif + +namespace Qtilities { + +static QScreen *findScreenAt(const QPoint &pos) +{ + for (QScreen *screen : QGuiApplication::screens()) { + if (screen->geometry().contains(pos)) + return screen; + } + return nullptr; +} + +static void createAutostartFile() +{ + QDir configDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + QString appName = QApplication::applicationName(); + QString filePath = configDir.filePath("autostart/" + appName + ".desktop"); + QFile file(filePath); + + if (file.exists() || !file.open(QIODevice::WriteOnly | QIODevice::Text)) + return; + + QTextStream out(&file); + out << "[Desktop Entry]\n"; + out << "Name=" + QApplication::applicationDisplayName() + "\n"; + out << "Type=Application\n"; + out << "Exec=" + appName + "\n"; + out << "Terminal=false\n"; +} + +static void deleteAutostartFile() +{ + QDir configDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + QString filePath(configDir.filePath("autostart/" + QApplication::applicationName() + ".desktop")); + QFile file(filePath); + + if (!file.exists()) + return; + + file.remove(); +} +} // namespace Qtilities diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 0000000..4646263 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,64 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#include "settings.hpp" +#include "qtilities.hpp" + +#include +#include + +Qtilities::Settings::Settings() + : bgColor_(Default::backgroundColor) + , fgColor_(Default::foregroundColor) + , position_(Default::position) + , size_(Default::size) +{ +} + +void Qtilities::Settings::load() +{ + QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QApplication::organizationName(), + QApplication::applicationDisplayName()); + + settings.beginGroup("General"); + bgColor_ = settings.value(QSL("BackgroundColor"), Default::backgroundColor).value(); + fgColor_ = settings.value(QSL("ForegroundColor"), Default::foregroundColor).value(); + position_ = settings.value(QSL("Position"), Default::position).toPoint(); + size_ = settings.value(QSL("Size"), Default::size).toSize(); + settings.endGroup(); +} + +void Qtilities::Settings::save() +{ + QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QApplication::organizationName(), + QApplication::applicationDisplayName()); + + settings.beginGroup("General"); + settings.setValue(QSL("BackgroundColor"), bgColor_); + settings.setValue(QSL("ForegroundColor"), fgColor_); + settings.setValue(QSL("Position"), position_); + settings.setValue(QSL("Size"), size_); + settings.endGroup(); +} diff --git a/src/settings.hpp b/src/settings.hpp new file mode 100644 index 0000000..f490e17 --- /dev/null +++ b/src/settings.hpp @@ -0,0 +1,65 @@ +/* + MIT License + + Copyright (c) 2021-2023 Andrea Zanellato + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ +#pragma once + +#include +#include +#include + +namespace Qtilities { + +namespace Default { +static constexpr QColor backgroundColor = QColor(0x92, 0xd7, 0xff); +static constexpr QColor foregroundColor = QColor(0x94, 0x00, 0x80); +static constexpr QPoint position = QPoint(200, 200); +static constexpr QSize size = QSize(240, 120); +} // namespace Default + +class Settings +{ +public: + Settings(); + + void load(); + void save(); + + QColor backgroundColor() const { return bgColor_; } + void setBackgroundColor(const QColor &bgColor) { bgColor_ = bgColor; } + + QColor foregroundColor() const { return fgColor_; } + void setForegroundColor(const QColor &fgColor) { fgColor_ = fgColor; } + + QPoint position() const { return position_; } + void setPosition(const QPoint &position) { position_ = position; } + + QSize size() const { return size_; } + void setSize(const QSize &size) { size_ = size; } + +private: + QColor bgColor_; + QColor fgColor_; + QPoint position_; + QSize size_; +}; +} // namespace Qtilities