diff --git a/installer/config/appIcon.png b/installer/config/appIcon.png deleted file mode 100644 index f4aa610..0000000 Binary files a/installer/config/appIcon.png and /dev/null differ diff --git a/installer/config/config.xml b/installer/config/config.xml index 3343dfd..347a740 100644 --- a/installer/config/config.xml +++ b/installer/config/config.xml @@ -1,17 +1,10 @@ GenPassword - 1.0.0 + 2.0.0 GenPassword Installer CM0use https://github.com/CM0use/GenPassword - appIcon.png GenPassword @HomeDir@/GenPassword - - - appIcon.png - https://github.com/CM0use/GenPassword - - diff --git a/installer/packages/com.CM0use.GenPassword/meta/installscript.qs b/installer/packages/com.CM0use.GenPassword/meta/installscript.qs index 5142e00..26aed3e 100644 --- a/installer/packages/com.CM0use.GenPassword/meta/installscript.qs +++ b/installer/packages/com.CM0use.GenPassword/meta/installscript.qs @@ -1,21 +1,5 @@ -/** - ** This file is part of the GenPassword project. - ** Copyright 2023 CM0use dilanuzcs@gmail.com - ** URL: https://github.com/CM0use/GenPassword - ** - ** This program is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** 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 General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with this program. If not, see . - **/ +// GenPassword +// Copyright (c) 2023 CM0use function Component() { @@ -44,8 +28,8 @@ Component.prototype.createOperations = function() "iconPath=@TargetDir@/GenPassword.exe"); } else if (installer.value("os") === "x11") { component.addOperation("InstallIcons", "@TargetDir@/icons"); - var app_desktop = "Version=1.0.0\nName=GenPassword\nComment=A random and customizable password generator\nComment[zh_CN]=随机和可定制的密码生成器\nComment[hi]=एक यादृच्छिक और अनुकूलन योग्य पासवर्ड जनरेटर\nComment[es]=Un generador de contraseñas aleatorio y personalizable\nComment[pt_BR]=Um gerador de senhas aleatórias e personalizáveis\nExec=@TargetDir@/GenPassword\nTerminal=false\nType=Application\nIcon=GenPasswordIcon\nCategories=Utility;Security", - uninstall_desktop = "Version=1.0.0\nName=Uninstall\nExec=@TargetDir@/maintenancetool\nTerminal=false\nKeyword=GenPassword\nType=Application\nIcon=GenPasswordIcon\nCategories=Utility;Security"; + var app_desktop = "Version=2.0.0\nName=GenPassword\nComment=A random and customizable password generator\nComment[es]=Un generador de contraseñas aleatorio y personalizable\nExec=@TargetDir@/GenPassword\nTerminal=false\nType=Application\nIcon=GenPasswordIcon\nCategories=Utility;Security", + uninstall_desktop = "Version=2.0.0\nName=Uninstall\nExec=@TargetDir@/maintenancetool\nTerminal=false\nKeyword=GenPassword\nType=Application\nIcon=GenPasswordIcon\nCategories=Utility;Security"; component.addOperation("CreateDesktopEntry", "GenPassword.desktop", diff --git a/installer/packages/com.CM0use.GenPassword/meta/package.xml b/installer/packages/com.CM0use.GenPassword/meta/package.xml index 9e74d2c..4b091e8 100644 --- a/installer/packages/com.CM0use.GenPassword/meta/package.xml +++ b/installer/packages/com.CM0use.GenPassword/meta/package.xml @@ -1,8 +1,8 @@ GenPassword - 2023-09-16 - 1.0.0 + 2023-11-10 + 2.0.0 true A random and customizable password generator. diff --git a/src/GenPassword.pro b/src/GenPassword.pro index baa531a..17c2f0f 100644 --- a/src/GenPassword.pro +++ b/src/GenPassword.pro @@ -1,44 +1,34 @@ -# -# ** This file is part of the GenPassword project. -# ** Copyright 2023 CM0use dilanuzcs@gmail.com -# ** URL: https://github.com/CM0use/GenPassword -# ** -# ** This program is free software: you can redistribute it and/or modify -# ** it under the terms of the GNU General Public License as published by -# ** the Free Software Foundation, either version 3 of the License, or -# ** (at your option) any later version. -# ** -# ** 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 General Public License for more details. -# ** -# ** You should have received a copy of the GNU General Public License -# ** along with this program. If not, see . -# - QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -CONFIG += c++20 -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 +CONFIG += c++17 +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 +VERSION = 2.0.0 +QMAKE_TARGET_PRODUCT = GenPassword +QMAKE_TARGET_DESCRIPTION = "A free generator password" +QMAKE_TARGET_COPYRIGHT = CM0use + +win32: RC_ICONS = icons/appIcon.ico SOURCES += \ + framelesswindow.cpp \ main.cpp \ - passwordgeneratorapp.cpp + passwordgenerator.cpp \ + switchbutton.cpp \ + window.cpp HEADERS += \ - passwordgeneratorapp.h + framelesswindow.h \ + icons.h \ + passwordgenerator.h \ + switchbutton.h \ + window.h -# Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -win32: RC_ICONS = icon/appIcon.ico -macx: ICON = icon/appIcon.icns - RESOURCES += \ i18n.qrc \ icons.qrc \ diff --git a/src/framelesswindow.cpp b/src/framelesswindow.cpp new file mode 100644 index 0000000..98c623c --- /dev/null +++ b/src/framelesswindow.cpp @@ -0,0 +1,88 @@ +// GenPassword +// Copyright (c) 2023 CM0use + +#include "framelesswindow.h" + +#include +#include +#include + +FramelessWindow::FramelessWindow(QWidget *const parent) + : QMainWindow{ parent, Qt::FramelessWindowHint }, + m_titleBar{ nullptr } +{ } + +bool FramelessWindow::event(QEvent *const event) +{ + if (windowFlags() & Qt::FramelessWindowHint) { + static Qt::Edges edges{ Qt::Edges() }; + const int margin{ style()->pixelMetric(QStyle::PM_LayoutTopMargin) }; + switch (event->type()) { + case QEvent::MouseButtonPress: + updateCursor(edges); + if ((m_titleBar != nullptr) && m_titleBar->underMouse()) + windowHandle()->startSystemMove(); + else if (edges) + windowHandle()->startSystemResize(edges); + break; + case QEvent::MouseButtonRelease: + edges = Qt::Edges(); + updateCursor(edges); + setFocus(); + break; + case QEvent::HoverMove: { + edges = Qt::Edges(); + QPoint p{ static_cast(event)->position().toPoint() }; + + if (p.x() < margin) + edges |= Qt::LeftEdge; + if (p.x() > (width() - margin)) + edges |= Qt::RightEdge; + if (p.y() < margin) + edges |= Qt::TopEdge; + if (p.y() > (height() - margin)) + edges |= Qt::BottomEdge; + updateCursor(edges); + break; + } + default: + break; + } + } + return QMainWindow::event(event); +} + +void FramelessWindow::setTitleBar(QWidget *const widget) +{ + m_titleBar = widget; +} + +QWidget* FramelessWindow::getTitleBar() const +{ + return m_titleBar; +} + +void FramelessWindow::updateCursor(const Qt::Edges &edges) +{ + switch (edges) { + case 0: + setCursor(Qt::ArrowCursor); + break; + case Qt::LeftEdge: + case Qt::RightEdge: + setCursor(Qt::SizeHorCursor); + break; + case Qt::TopEdge: + case Qt::BottomEdge: + setCursor(Qt::SizeVerCursor); + break; + case Qt::LeftEdge | Qt::TopEdge: + case Qt::RightEdge | Qt::BottomEdge: + setCursor(Qt::SizeFDiagCursor); + break; + case Qt::RightEdge | Qt::TopEdge: + case Qt::LeftEdge | Qt::BottomEdge: + setCursor(Qt::SizeBDiagCursor); + break; + } +} diff --git a/src/framelesswindow.h b/src/framelesswindow.h new file mode 100644 index 0000000..42594ac --- /dev/null +++ b/src/framelesswindow.h @@ -0,0 +1,26 @@ +// GenPassword +// Copyright (c) 2023 CM0use + +#ifndef FRAMELESSWINDOW_H +#define FRAMELESSWINDOW_H + +#include + +class FramelessWindow: public QMainWindow +{ +public: + explicit FramelessWindow(QWidget *const parent = nullptr); + virtual ~FramelessWindow() = default; + +protected: + virtual bool event(QEvent *const event) override; + + void setTitleBar(QWidget *const widget); + QWidget* getTitleBar() const; + +private: + void updateCursor(const Qt::Edges &edges); + QWidget *m_titleBar; +}; + +#endif diff --git a/src/i18n.qrc b/src/i18n.qrc index 2b2ca2e..ca3b9f9 100644 --- a/src/i18n.qrc +++ b/src/i18n.qrc @@ -1,9 +1,5 @@ - - languages/en.qm - languages/es.qm - languages/hi.qm - languages/pt-BR.qm - languages/zh-CN.qm + + i18n/es.qm diff --git a/src/i18n/es.qm b/src/i18n/es.qm new file mode 100644 index 0000000..02ad783 Binary files /dev/null and b/src/i18n/es.qm differ diff --git a/src/i18n/es.ts b/src/i18n/es.ts new file mode 100644 index 0000000..078f95d --- /dev/null +++ b/src/i18n/es.ts @@ -0,0 +1,295 @@ + + + + + QObject + + + GenPassword is now running + GenPassword ya está en marcha + + + + The application is already running. +Another instance cannot be started. + La aplicación ya se está ejecutando. +No se puede iniciar otra instancia. + + + + Error + + + + + The theme index specified in the configuration file is invalid. +Please check the value and try again. + El índice del tema especificado en el archivo de configuración no es válido. +Compruebe el valor e inténtelo de nuevo. + + + + Numeric characters + Caracteres numéricos + + + + Symbols characters + Símbolos especiales + + + + Lowercase letters + Letras minúsculas + + + + Uppercase letters + Letras mayúsculas + + + + Your password will be generated here + Su contraseña se generará aquí + + + + Generate a new password + Generar una nueva contraseña + + + + Copy the password to the clipboard + Copiar la contraseña en el portapapeles + + + + Contain the numbers: 0-9 + Contiene los números: 0-9 + + + + Contain special symbols: +!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ + Contiene símbolos especiales: +!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ + + + + Contain lowercase letters: a-z + Contiene letras minúsculas: a-z + + + + Contain uppercase letters: A-Z + Contiene letras mayúsculas: A-Z + + + + Characters to add + Caracteres a añadir + + + + Characters to remove + Caracteres a eliminar + + + + Add + Añadir + + + + Remove + Eliminar + + + + Information + Información + + + + No characters have been selected for the password. +Please select at least one character. + No se ha seleccionado ningún carácter para la contraseña. +Por favor, seleccione al menos un carácter. + + + + Hide Password + Ocultar contraseña + + + + Show Password + Mostrar contraseña + + + + Window + + + &Languages + Idiomas + + + + &Themes + &Temas + + + + &Shortcuts + Atajos + + + + &Help + Ayuda + + + + [en] English + [en] Inglés + + + + [es] Español + + + + + Light + + + + + Dark + + + + + &Custom Title Bar + &Barra de título personalizada + + + + &About %1 + &Acerca de %1 + + + + &Credits + &Créditos + + + + About &Qt + Acerca de &Qt + + + + E&xit + Salir + + + + &Generate Password + &Generar contraseña + + + + Cut Password + Cortar contraseña + + + + &Copy Password + &Copiar contraseña + + + + Show %1 + Mostrar %1 + + + + New+Copy Password + Nueva+Copiar contraseña + + + + Restart Required + Reinicio necesario + + + + You will need to restart in order to use your new language setting +Your password will be lost if you do not save it before restarting. + Deberá reiniciar para poder utilizar la nueva configuración de idioma. +Su contraseña se perderá si no la guarda antes de reiniciar. + + + + Restart Now + Reiniciar ahora + + + + Restart Later + Reiniciar más tarde + + + + Error + + + + + Error: "enum QProcess::ProcessError" +Value error: %1 +The program can still be used +but cannot be restarted due to an error. + +Do you want copy this error in your clipboad? + Error: "enum QProcess::ProcessError" +Error de valor: %1 +El programa todavía se puede utilizar +pero no se puede reiniciar debido a un error. + +¿Quieres copiar este error en tu portapapeles? + + + + Copy to clipboard + Copiar al portapapeles + + + + No + + + + + <div style="text-align: center"><h1>%1</h1><p>Version: %2</p><p>%1 is a free password generator that helps you create random and customizable passwords. The program adds or removes characters in the following order:</p><ol><li>Numbers, Symbols, Lowercase letters, Uppercase letters</li><li>Adds the letters that the user has specified</li><li>Removes the letters that the user has specified</li></ol><p>For issues or contributions, visit the <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub repository</a></p><p>Copyright © 2023 - CM0use</p><p>This program comes with NO WARRANTY OF ANY KIND.<br>See the <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU General Public License</a> for details.</p></div> + <div style="text-align: center"><h1>%1</h1><p>Versión: %2</p><p>%1 es un generador de contraseñas gratuito que te ayuda a crear contraseñas aleatorias y personalizables. El programa añade o elimina caracteres en el siguiente orden:</p><ol><li>Números, Símbolos, Minúsculas, Mayúsculas</li><li>Añade las letras que el usuario ha especificado</li><li>Elimina las letras que el usuario ha especificado</li></ol><p>Para cuestiones o contribuciones, visite <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub repository</a></p><p>Copyright © 2023 - CM0use</p><p>Este programa no incluye GARANTÍA DE NINGÚN TIPO.<br>Véase el <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU General Public License</a> para más detalles.</p></div> + + + + About %1 + Acerca de %1 + + + + <div style="text-align: center"><h1>%1</h1><p>Created by <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p><p>Contributors:</p><ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Helper)</li><li><a href=https://fonts.google.com/icons style=color:#0097CF>Material Icons</a></li><li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> (Translator)</li></ul><p>Inspired by design: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> + <div style="text-align: center"><h1>%1</h1><p>Creado por <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p><p>Colaboradores:</p><ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Ayudante)</li><li><a href=https://fonts.google.com/icons style=color:#0097CF>Material Icons</a></li><li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> (Traductor)</li></ul><p>Inspirado en el diseño: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> + + + + Credits + Créditos + + + diff --git a/src/icon/appIcon.icns b/src/icon/appIcon.icns deleted file mode 100644 index de8ee7d..0000000 Binary files a/src/icon/appIcon.icns and /dev/null differ diff --git a/src/icon/appIcon.ico b/src/icon/appIcon.ico deleted file mode 100644 index db8a997..0000000 Binary files a/src/icon/appIcon.ico and /dev/null differ diff --git a/src/icon/appIcon.png b/src/icon/appIcon.png deleted file mode 100644 index f4aa610..0000000 Binary files a/src/icon/appIcon.png and /dev/null differ diff --git a/src/icon/clipboard.png b/src/icon/clipboard.png deleted file mode 100644 index cdd1c36..0000000 Binary files a/src/icon/clipboard.png and /dev/null differ diff --git a/src/icon/heart.png b/src/icon/heart.png deleted file mode 100644 index 8d5bba9..0000000 Binary files a/src/icon/heart.png and /dev/null differ diff --git a/src/icon/showPassword.png b/src/icon/showPassword.png deleted file mode 100644 index b667927..0000000 Binary files a/src/icon/showPassword.png and /dev/null differ diff --git a/src/icon/toggleoff.png b/src/icon/toggleoff.png deleted file mode 100644 index a21a368..0000000 Binary files a/src/icon/toggleoff.png and /dev/null differ diff --git a/src/icon/toggleon.png b/src/icon/toggleon.png deleted file mode 100644 index e3e36d4..0000000 Binary files a/src/icon/toggleon.png and /dev/null differ diff --git a/src/icons.h b/src/icons.h new file mode 100644 index 0000000..483248f --- /dev/null +++ b/src/icons.h @@ -0,0 +1,51 @@ +// GenPassword +// Copyright (c) 2023 CM0use + +#ifndef ICONS_H +#define ICONS_H + +#define QT_ICON (QIcon{ ":/icons/qt.svg" }) + +#define VISIBILITYOFF_ICON_LIGHT (QIcon(":/icons/light/visibility_off_white_24dp.svg")) +#define CHECK_ICON_LIGHT (QIcon(":/icons/light/check_circle_outline_white_24dp.svg")) +#define VISIBILITYON_ICON_LIGHT (QIcon(":/icons/light/visibility_white_24dp.svg")) +#define WARNING_ICON_LIGHT (QIcon(":/icons/light/warning_amber_white_24dp.svg")) +#define COPYRIGHT_ICON_LIGHT (QIcon(":/icons/light/copyright_white_24dp.svg")) +#define TRANSLATE_ICON_LIGHT (QIcon(":/icons/light/translate_white_24dp.svg")) +#define SHORTCUT_ICON_LIGHT (QIcon(":/icons/light/shortcut_white_24dp.svg")) +#define MINIMIZE_ICON_LIGHT (QIcon(":/icons/light/minimize_white_24dp.svg")) +#define COPY_ICON_LIGHT (QIcon(":/icons/light/content_copy_white_24dp.svg")) +#define HELP_ICON_LIGHT (QIcon(":/icons/light/help_outline_white_24dp.svg")) +#define OFF_ICON_LIGHT (QIcon(":/icons/light/highlight_off_white_24dp.svg")) +#define INFO_ICON_LIGHT (QIcon(":/icons/light/info_outline_white_24dp.svg")) +#define EXIT_ICON_LIGHT (QIcon(":/icons/light/exit_to_app_white_24dp.svg")) +#define APP_ICON_LIGHT (QIcon(":/icons/light/lock_outline_white_24dp.svg")) +#define PALETTE_ICON_LIGHT (QIcon(":/icons/light/palette_white_24dp.svg")) +#define REFRESH_ICON_LIGHT (QIcon(":/icons/light/refresh_white_24dp.svg")) +#define CUT_ICON_LIGHT (QIcon(":/icons/light/content_cut_white_24dp.svg")) +#define CLOSE_ICON_LIGHT (QIcon(":/icons/light/close_white_24dp.svg")) +#define MENU_ICON_LIGHT (QIcon(":/icons/light/menu_white_24dp.svg")) +#define DONE_ICON_LIGHT (QIcon(":/icons/light/done_white_24dp.svg")) + +#define DONE_ICON_DARK (QIcon(":/icons/dark/done_black_24dp.svg")) +#define MENU_ICON_DARK (QIcon(":/icons/dark/menu_black_24dp.svg")) +#define CLOSE_ICON_DARK (QIcon(":/icons/dark/close_black_24dp.svg")) +#define CUT_ICON_DARK (QIcon(":/icons/dark/content_cut_black_24dp.svg")) +#define REFRESH_ICON_DARK (QIcon(":/icons/dark/refresh_black_24dp.svg")) +#define PALETTE_ICON_DARK (QIcon(":/icons/dark/palette_black_24dp.svg")) +#define EXIT_ICON_DARK (QIcon(":/icons/dark/exit_to_app_black_24dp.svg")) +#define APP_ICON_DARK (QIcon(":/icons/dark/lock_outline_black_24dp.svg")) +#define COPY_ICON_DARK (QIcon(":/icons/dark/content_copy_black_24dp.svg")) +#define HELP_ICON_DARK (QIcon(":/icons/dark/help_outline_black_24dp.svg")) +#define OFF_ICON_DARK (QIcon(":/icons/dark/highlight_off_black_24dp.svg")) +#define INFO_ICON_DARK (QIcon(":/icons/dark/info_outline_black_24dp.svg")) +#define MINIMIZE_ICON_DARK (QIcon(":/icons/dark/minimize_black_24dp.svg")) +#define SHORTCUT_ICON_DARK (QIcon(":/icons/dark/shortcut_black_24dp.svg")) +#define COPYRIGHT_ICON_DARK (QIcon(":/icons/dark/copyright_black_24dp.svg")) +#define TRANSLATE_ICON_DARK (QIcon(":/icons/dark/translate_black_24dp.svg")) +#define WARNING_ICON_DARK (QIcon(":/icons/dark/warning_amber_black_24dp.svg")) +#define VISIBILITYON_ICON_DARK (QIcon(":/icons/dark/visibility_black_24dp.svg")) +#define CHECK_ICON_DARK (QIcon(":/icons/dark/check_circle_outline_black_24dp.svg")) +#define VISIBILITYOFF_ICON_DARK (QIcon(":/icons/dark/visibility_off_black_24dp.svg")) + +#endif // ICONS_H diff --git a/src/icons.qrc b/src/icons.qrc index aae19cf..4a9ec44 100644 --- a/src/icons.qrc +++ b/src/icons.qrc @@ -1,10 +1,47 @@ - - icon/heart.png - icon/toggleoff.png - icon/toggleon.png - icon/clipboard.png - icon/showPassword.png - icon/appIcon.png + + icons/appIcon.ico + icons/qt.svg + icons/dark/check_circle_outline_black_24dp.svg + icons/dark/close_black_24dp.svg + icons/dark/content_copy_black_24dp.svg + icons/dark/content_cut_black_24dp.svg + icons/dark/copyright_black_24dp.svg + icons/dark/done_black_24dp.svg + icons/dark/exit_to_app_black_24dp.svg + icons/dark/help_outline_black_24dp.svg + icons/dark/highlight_off_black_24dp.svg + icons/dark/info_outline_black_24dp.svg + icons/dark/lock_outline_black_24dp.svg + icons/dark/menu_black_24dp.svg + icons/dark/minimize_black_24dp.svg + icons/dark/palette_black_24dp.svg + icons/dark/refresh_black_24dp.svg + icons/dark/shortcut_black_24dp.svg + icons/dark/translate_black_24dp.svg + icons/dark/visibility_black_24dp.svg + icons/dark/visibility_off_black_24dp.svg + icons/dark/warning_amber_black_24dp.svg + icons/light/check_circle_outline_white_24dp.svg + icons/light/close_white_24dp.svg + icons/light/content_copy_white_24dp.svg + icons/light/content_cut_white_24dp.svg + icons/light/copyright_white_24dp.svg + icons/light/crop_square_white_24dp.svg + icons/light/done_white_24dp.svg + icons/light/exit_to_app_white_24dp.svg + icons/light/help_outline_white_24dp.svg + icons/light/highlight_off_white_24dp.svg + icons/light/info_outline_white_24dp.svg + icons/light/lock_outline_white_24dp.svg + icons/light/menu_white_24dp.svg + icons/light/minimize_white_24dp.svg + icons/light/palette_white_24dp.svg + icons/light/refresh_white_24dp.svg + icons/light/shortcut_white_24dp.svg + icons/light/translate_white_24dp.svg + icons/light/visibility_off_white_24dp.svg + icons/light/visibility_white_24dp.svg + icons/light/warning_amber_white_24dp.svg diff --git a/src/icons/appIcon.ico b/src/icons/appIcon.ico new file mode 100644 index 0000000..5965aed Binary files /dev/null and b/src/icons/appIcon.ico differ diff --git a/src/icons/dark/check_circle_outline_black_24dp.svg b/src/icons/dark/check_circle_outline_black_24dp.svg new file mode 100644 index 0000000..b2a9c1f --- /dev/null +++ b/src/icons/dark/check_circle_outline_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/close_black_24dp.svg b/src/icons/dark/close_black_24dp.svg new file mode 100644 index 0000000..b883aae --- /dev/null +++ b/src/icons/dark/close_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/content_copy_black_24dp.svg b/src/icons/dark/content_copy_black_24dp.svg new file mode 100644 index 0000000..0f9e858 --- /dev/null +++ b/src/icons/dark/content_copy_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/content_cut_black_24dp.svg b/src/icons/dark/content_cut_black_24dp.svg new file mode 100644 index 0000000..cce5bc8 --- /dev/null +++ b/src/icons/dark/content_cut_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/copyright_black_24dp.svg b/src/icons/dark/copyright_black_24dp.svg new file mode 100644 index 0000000..ee24e95 --- /dev/null +++ b/src/icons/dark/copyright_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/done_black_24dp.svg b/src/icons/dark/done_black_24dp.svg new file mode 100644 index 0000000..c5c8e5d --- /dev/null +++ b/src/icons/dark/done_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/exit_to_app_black_24dp.svg b/src/icons/dark/exit_to_app_black_24dp.svg new file mode 100644 index 0000000..abe0f0c --- /dev/null +++ b/src/icons/dark/exit_to_app_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/help_outline_black_24dp.svg b/src/icons/dark/help_outline_black_24dp.svg new file mode 100644 index 0000000..ca347f9 --- /dev/null +++ b/src/icons/dark/help_outline_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/highlight_off_black_24dp.svg b/src/icons/dark/highlight_off_black_24dp.svg new file mode 100644 index 0000000..c7737f8 --- /dev/null +++ b/src/icons/dark/highlight_off_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/info_outline_black_24dp.svg b/src/icons/dark/info_outline_black_24dp.svg new file mode 100644 index 0000000..4fb0e1d --- /dev/null +++ b/src/icons/dark/info_outline_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/lock_outline_black_24dp.svg b/src/icons/dark/lock_outline_black_24dp.svg new file mode 100644 index 0000000..0db04cf --- /dev/null +++ b/src/icons/dark/lock_outline_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/menu_black_24dp.svg b/src/icons/dark/menu_black_24dp.svg new file mode 100644 index 0000000..0429d34 --- /dev/null +++ b/src/icons/dark/menu_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/minimize_black_24dp.svg b/src/icons/dark/minimize_black_24dp.svg new file mode 100644 index 0000000..13db8d5 --- /dev/null +++ b/src/icons/dark/minimize_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/palette_black_24dp.svg b/src/icons/dark/palette_black_24dp.svg new file mode 100644 index 0000000..4064d0a --- /dev/null +++ b/src/icons/dark/palette_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/refresh_black_24dp.svg b/src/icons/dark/refresh_black_24dp.svg new file mode 100644 index 0000000..057126a --- /dev/null +++ b/src/icons/dark/refresh_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/shortcut_black_24dp.svg b/src/icons/dark/shortcut_black_24dp.svg new file mode 100644 index 0000000..2381247 --- /dev/null +++ b/src/icons/dark/shortcut_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/translate_black_24dp.svg b/src/icons/dark/translate_black_24dp.svg new file mode 100644 index 0000000..195b204 --- /dev/null +++ b/src/icons/dark/translate_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/visibility_black_24dp.svg b/src/icons/dark/visibility_black_24dp.svg new file mode 100644 index 0000000..8522d4e --- /dev/null +++ b/src/icons/dark/visibility_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/visibility_off_black_24dp.svg b/src/icons/dark/visibility_off_black_24dp.svg new file mode 100644 index 0000000..db69b3a --- /dev/null +++ b/src/icons/dark/visibility_off_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/dark/warning_amber_black_24dp.svg b/src/icons/dark/warning_amber_black_24dp.svg new file mode 100644 index 0000000..9e68b22 --- /dev/null +++ b/src/icons/dark/warning_amber_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/check_circle_outline_white_24dp.svg b/src/icons/light/check_circle_outline_white_24dp.svg new file mode 100644 index 0000000..b2c6f35 --- /dev/null +++ b/src/icons/light/check_circle_outline_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/close_white_24dp.svg b/src/icons/light/close_white_24dp.svg new file mode 100644 index 0000000..e591b38 --- /dev/null +++ b/src/icons/light/close_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/content_copy_white_24dp.svg b/src/icons/light/content_copy_white_24dp.svg new file mode 100644 index 0000000..1dfb153 --- /dev/null +++ b/src/icons/light/content_copy_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/content_cut_white_24dp.svg b/src/icons/light/content_cut_white_24dp.svg new file mode 100644 index 0000000..64c491c --- /dev/null +++ b/src/icons/light/content_cut_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/copyright_white_24dp.svg b/src/icons/light/copyright_white_24dp.svg new file mode 100644 index 0000000..6acdce4 --- /dev/null +++ b/src/icons/light/copyright_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/crop_square_white_24dp.svg b/src/icons/light/crop_square_white_24dp.svg new file mode 100644 index 0000000..a71050a --- /dev/null +++ b/src/icons/light/crop_square_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/done_white_24dp.svg b/src/icons/light/done_white_24dp.svg new file mode 100644 index 0000000..5dc1b19 --- /dev/null +++ b/src/icons/light/done_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/exit_to_app_white_24dp.svg b/src/icons/light/exit_to_app_white_24dp.svg new file mode 100644 index 0000000..e48f9e7 --- /dev/null +++ b/src/icons/light/exit_to_app_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/help_outline_white_24dp.svg b/src/icons/light/help_outline_white_24dp.svg new file mode 100644 index 0000000..222e755 --- /dev/null +++ b/src/icons/light/help_outline_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/highlight_off_white_24dp.svg b/src/icons/light/highlight_off_white_24dp.svg new file mode 100644 index 0000000..a9b1db8 --- /dev/null +++ b/src/icons/light/highlight_off_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/info_outline_white_24dp.svg b/src/icons/light/info_outline_white_24dp.svg new file mode 100644 index 0000000..ac6ed59 --- /dev/null +++ b/src/icons/light/info_outline_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/lock_outline_white_24dp.svg b/src/icons/light/lock_outline_white_24dp.svg new file mode 100644 index 0000000..61c48ea --- /dev/null +++ b/src/icons/light/lock_outline_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/menu_white_24dp.svg b/src/icons/light/menu_white_24dp.svg new file mode 100644 index 0000000..9e68d69 --- /dev/null +++ b/src/icons/light/menu_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/minimize_white_24dp.svg b/src/icons/light/minimize_white_24dp.svg new file mode 100644 index 0000000..c9ccc8e --- /dev/null +++ b/src/icons/light/minimize_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/palette_white_24dp.svg b/src/icons/light/palette_white_24dp.svg new file mode 100644 index 0000000..7dcbca4 --- /dev/null +++ b/src/icons/light/palette_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/refresh_white_24dp.svg b/src/icons/light/refresh_white_24dp.svg new file mode 100644 index 0000000..901e7d0 --- /dev/null +++ b/src/icons/light/refresh_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/shortcut_white_24dp.svg b/src/icons/light/shortcut_white_24dp.svg new file mode 100644 index 0000000..d7c8394 --- /dev/null +++ b/src/icons/light/shortcut_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/translate_white_24dp.svg b/src/icons/light/translate_white_24dp.svg new file mode 100644 index 0000000..9ca23a2 --- /dev/null +++ b/src/icons/light/translate_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/visibility_off_white_24dp.svg b/src/icons/light/visibility_off_white_24dp.svg new file mode 100644 index 0000000..dc3f29d --- /dev/null +++ b/src/icons/light/visibility_off_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/visibility_white_24dp.svg b/src/icons/light/visibility_white_24dp.svg new file mode 100644 index 0000000..7874ae2 --- /dev/null +++ b/src/icons/light/visibility_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/light/warning_amber_white_24dp.svg b/src/icons/light/warning_amber_white_24dp.svg new file mode 100644 index 0000000..3716e74 --- /dev/null +++ b/src/icons/light/warning_amber_white_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/qt.svg b/src/icons/qt.svg new file mode 100644 index 0000000..72c60ef --- /dev/null +++ b/src/icons/qt.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/languages/en.qm b/src/languages/en.qm deleted file mode 100644 index be651ee..0000000 --- a/src/languages/en.qm +++ /dev/null @@ -1 +0,0 @@ - - - - - PasswordGeneratorApp - - - E&xit - - - - - &Generate Password - - - - - Cut Password - - - - - &Copy Password - - - - - &Use the standard palette of the theme - - - - - &About %1 - - - - - &Credits - - - - - About &Qt - - - - - &File - - - - - &Edit - - - - - &View - - - - - &Help - - - - - &Languages - - - - - &Themes - - - - - Your password will be generated here - - - - - Copy the password to the clipboard - - - - - Contain the numbers: 0-9 - - - - - Contain special symbols: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - - - - - Contain lowercase letters: a-z - - - - - Contain uppercase letters: A-Z - - - - - Characters to add - - - - - Characters to remove - - - - - Generate Password - - - - - - Warning - - - - - This option is enabled. -When this option is enabled, you will need to reselect the theme you have chosen. This will ensure that the theme is applied correctly. - -This is because Qt does not currently support stylesheets for custom QStyle subclasses. This functionality will be implemented in a future release. - - - - - This option is disabled. -After disabling this option, it is recommended that you reselect the theme you have chosen, once this is done you will not need to reselect a theme twice for the theme to be applied correctly. - - - - - Password Length - - - - - Numeric characters - - - - - Symbols characters - - - - - Lowercase letters - - - - - Uppercase letters - - - - - Add - - - - - Remove - - - - - Version %1 - - - - - Information - - - - - No characters have been selected for the password. -Please select at least one character. - - - - - Show Password - - - - - Hide Password - - - - - Password copied! - - - - - The password is empty. Can't copy to clipboard. - - - - - Restart Required - - - - - You will need to restart in order to use your new language setting -Your password will be lost if you do not save it before restarting. - - - - - Restart Now - - - - - Restart Later - - - - - Error - - - - - Error: "enum QProcess::ProcessError" -Value error: %1 -The program can still be used -but cannot be restarted due to an error. - -Do you want copy this error in your clipboad? - - - - - Copy to clipboard - - - - - No - - - - - <div style="text-align: center"><h1>%1</h1> -<p>Version: %2</p> -<p>GenPassword is a free password generator that helps you create random and customizable passwords. The program adds or removes characters in the following order: -</p> -<ol><li>Numbers, Symbols, Lowercase letters, Uppercase letters</li> -<li>Adds the letters that the user has specified</li> -<li>Removes the letters that the user has specified</li> -</ol><p>For issues or contributions, visit the <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub repository</a></p> -<p>Copyright © 2023 - CM0use</p> -<p>This program comes with NO WARRANTY OF ANY KIND.<br> -See the <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU General Public License</a> for details.</p></div> - - - - - About %1 - - - - - <div style="text-align: center"><h1>%1</h1> -<p>Created by <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p> -<p>Contributors:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Helper)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (Icons)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> and <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (Translator)</li> -</ul><p>Inspired by design: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - - - - - Credits - - - - - QObject - - - GenPassword is now running - - - - - The application is already running. -Another instance cannot be started. - - - - - - Exit - - - - - Error - - - - - The theme index specified in the configuration file is invalid. -Please check the value and try again. - - - - diff --git a/src/languages/es.qm b/src/languages/es.qm deleted file mode 100644 index 2c316e7..0000000 Binary files a/src/languages/es.qm and /dev/null differ diff --git a/src/languages/es.ts b/src/languages/es.ts deleted file mode 100644 index 8f1f0a5..0000000 --- a/src/languages/es.ts +++ /dev/null @@ -1,357 +0,0 @@ - - - - - PasswordGeneratorApp - - - E&xit - &Salir - - - - &Generate Password - &Generar Contraseña - - - - Cut Password - Cortar contraseña - - - - &Copy Password - &Copiar Contraseña - - - - &Use the standard palette of the theme - &Utilizar la paleta estándar del tema - - - - &About %1 - &Acerca de %1 - - - - &Credits - &Créditos - - - - About &Qt - Acerca de &Qt - - - - &File - &Archivo - - - - &Edit - &Editar - - - - &View - &Ver - - - - &Help - &Ayuda - - - - &Languages - &Idiomas - - - - &Themes - &Temas - - - - Your password will be generated here - Su contraseña se generará aquí - - - - Copy the password to the clipboard - Copiar la contraseña en el portapapeles - - - - Contain the numbers: 0-9 - Contiene los números: 0-9 - - - - Contain special symbols: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - Contienen símbolos especiales: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - - - - Contain lowercase letters: a-z - Contienen letras minúsculas: a-z - - - - Contain uppercase letters: A-Z - Contienen letras mayúsculas: A-Z - - - - Characters to add - Caracteres a añadir - - - - Characters to remove - Caracteres a eliminar - - - - Generate Password - Generar contraseña - - - - - Warning - Advertencia - - - - This option is enabled. -When this option is enabled, you will need to reselect the theme you have chosen. This will ensure that the theme is applied correctly. - -This is because Qt does not currently support stylesheets for custom QStyle subclasses. This functionality will be implemented in a future release. - Esta opción está activada. -Cuando esta opción esté activada, deberá volver a seleccionar el tema que haya elegido. Esto asegurará que el tema se aplique correctamente. - -Esto se debe a que Qt no soporta actualmente hojas de estilo para subclases personalizadas de QStyle. Esta funcionalidad se implementará en una futura versión. - - - - This option is disabled. -After disabling this option, it is recommended that you reselect the theme you have chosen, once this is done you will not need to reselect a theme twice for the theme to be applied correctly. - Esta opción está desactivada. -Después de desactivar esta opción, se recomienda que vuelva a seleccionar el tema que ha elegido, una vez hecho esto no tendrá que volver a seleccionar un tema dos veces para que el tema se aplique correctamente. - - - - Password Length - Longitud de la contraseña - - - - Numeric characters - Caracteres numéricos - - - - Symbols characters - Símbolos caracteres - - - - Lowercase letters - Letras minúsculas - - - - Uppercase letters - Letras mayúsculas - - - - Add - Añadir - - - - Remove - Eliminar - - - - Version %1 - Versión %1 - - - - Information - Información - - - - No characters have been selected for the password. -Please select at least one character. - No se ha seleccionado ningún carácter para la contraseña. -Por favor, seleccione al menos un carácter. - - - - Show Password - Mostrar contraseña - - - - Hide Password - Ocultar contraseña - - - - Password copied! - ¡Contraseña copiada! - - - - The password is empty. Can't copy to clipboard. - La contraseña está vacía. No se puede copiar al portapapeles. - - - - Restart Required - Reinicio necesario - - - - You will need to restart in order to use your new language setting -Your password will be lost if you do not save it before restarting. - Deberá reiniciar para poder utilizar la nueva configuración de idioma. -Su contraseña se perderá si no la guarda antes de reiniciar. - - - - Restart Now - Reiniciar ahora - - - - Restart Later - Reiniciar más tarde - - - - Error - Error - - - - Error: "enum QProcess::ProcessError" -Value error: %1 -The program can still be used -but cannot be restarted due to an error. - -Do you want copy this error in your clipboad? - Error: "enum QProcess::ProcessError" -Error de valor: %1 -El programa todavía se puede utilizar -pero no se puede reiniciar debido a un error. - -¿Quieres copiar este error en tu portapapeles? - - - - Copy to clipboard - Copiar al portapapeles - - - - No - No - - - - <div style="text-align: center"><h1>%1</h1> -<p>Version: %2</p> -<p>GenPassword is a free password generator that helps you create random and customizable passwords. The program adds or removes characters in the following order: -</p> -<ol><li>Numbers, Symbols, Lowercase letters, Uppercase letters</li> -<li>Adds the letters that the user has specified</li> -<li>Removes the letters that the user has specified</li> -</ol><p>For issues or contributions, visit the <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub repository</a></p> -<p>Copyright © 2023 - CM0use</p> -<p>This program comes with NO WARRANTY OF ANY KIND.<br> -See the <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU General Public License</a> for details.</p></div> - <div style="text-align: center"><h1>%1</h1> -<p>Versión: %2</p> -<p>GenPassword es un generador de contraseñas gratuito que te ayuda a crear contraseñas aleatorias y personalizables. El programa añade o elimina caracteres en el siguiente orden: -</p> -<ol><li>Números, Símbolos, Minúsculas, Mayúsculas</li> -<li>Añade las letras que el usuario ha especificado</li> -<li>Elimina las letras que el usuario ha especificado</li> -</ol><p>Para cuestiones o contribuciones, visite el repositorio <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub</a>.</p> -<p>Copyright © 2023 - CM0use</p> -<p>Este programa no incluye GARANTÍA DE NINGÚN TIPO.<br> -Consulte la <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>Licencia Pública General de GNU</a> para más detalles.</p></div> - - - - About %1 - Acerca de %1 - - - - <div style="text-align: center"><h1>%1</h1> -<p>Created by <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p> -<p>Contributors:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Helper)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (Icons)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> and <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (Translator)</li> -</ul><p>Inspired by design: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - <div style="text-align: center"><h1>%1</h1> -<p>Creado por <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p> -<p>Colaboradores:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Ayudante)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (Iconos)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> y <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (Traductor)</li> -</ul><p>Inspirado en el diseño: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - - - - Credits - Créditos - - - - QObject - - - GenPassword is now running - GenPassword ya está en funcionamiento - - - - The application is already running. -Another instance cannot be started. - La aplicación ya se está ejecutando. -No se puede iniciar otra instancia. - - - - Error - Error - - - - The theme index specified in the configuration file is invalid. -Please check the value and try again. - El índice del tema especificado en el archivo de configuración no es válido. -Compruebe el valor e inténtelo de nuevo. - - - - - Exit - Salir - - - diff --git a/src/languages/hi.qm b/src/languages/hi.qm deleted file mode 100644 index 6d3e264..0000000 Binary files a/src/languages/hi.qm and /dev/null differ diff --git a/src/languages/hi.ts b/src/languages/hi.ts deleted file mode 100644 index aa62530..0000000 --- a/src/languages/hi.ts +++ /dev/null @@ -1,357 +0,0 @@ - - - - - PasswordGeneratorApp - - - E&xit - बाहर निकलना - - - - &Generate Password - पासवर्ड उत्पन्न करें - - - - Cut Password - पासवर्ड काटें - - - - &Copy Password - पासवर्ड कॉपी करें - - - - &Use the standard palette of the theme - थीम के मानक पैलेट का उपयोग करें - - - - &About %1 - लगभग %1 - - - - &Credits - क्रेडिट - - - - About &Qt - &Qt के बारे में - - - - &File - फ़ाइल - - - - &Edit - संपादन करना - - - - &View - देखना - - - - &Help - मदद - - - - &Languages - बोली - - - - &Themes - विषय-वस्तु - - - - Your password will be generated here - यहां आपका पासवर्ड जनरेट हो जाएगा - - - - Copy the password to the clipboard - पासवर्ड को क्लिपबोर्ड पर कॉपी करें - - - - Contain the numbers: 0-9 - संख्याएँ शामिल करें: 0-9 - - - - Contain special symbols: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - विशेष चिह्न शामिल करें: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - - - - Contain lowercase letters: a-z - छोटे अक्षर शामिल हैं: a-z - - - - Contain uppercase letters: A-Z - बड़े अक्षर शामिल हैं: A-Z - - - - Characters to add - जोड़ने के लिए अक्षर - - - - Characters to remove - हटाने योग्य अक्षर - - - - Generate Password - पासवर्ड उत्पन्न करें - - - - - Warning - चेतावनी - - - - This option is enabled. -When this option is enabled, you will need to reselect the theme you have chosen. This will ensure that the theme is applied correctly. - -This is because Qt does not currently support stylesheets for custom QStyle subclasses. This functionality will be implemented in a future release. - यह विकल्प सक्षम है. -जब यह विकल्प सक्षम हो जाता है, तो आपको अपने द्वारा चुनी गई थीम को फिर से चुनना होगा। इससे यह सुनिश्चित होगा कि विषयवस्तु सही ढंग से लागू की गई है।. - -ऐसा इसलिए है क्योंकि Qt वर्तमान में कस्टम QStyle उपवर्गों के लिए स्टाइलशीट का समर्थन नहीं करता है। यह कार्यक्षमता भविष्य के रिलीज़ में लागू की जाएगी।. - - - - This option is disabled. -After disabling this option, it is recommended that you reselect the theme you have chosen, once this is done you will not need to reselect a theme twice for the theme to be applied correctly. - यह विकल्प अक्षम है. -इस विकल्प को अक्षम करने के बाद, यह अनुशंसा की जाती है कि आप अपने द्वारा चुनी गई थीम को फिर से चुनें, एक बार ऐसा करने के बाद थीम को सही ढंग से लागू करने के लिए आपको किसी थीम को दो बार फिर से चुनने की आवश्यकता नहीं होगी।. - - - - Password Length - पारण शब्द लम्बाई - - - - Numeric characters - संख्यात्मक वर्ण - - - - Symbols characters - प्रतीक चिन्ह - - - - Lowercase letters - छोटे अक्षर - - - - Uppercase letters - बड़ी वर्तनी के अक्षर - - - - Add - जोड़ना - - - - Remove - निकालना - - - - Version %1 - संस्करण %1 - - - - Information - जानकारी - - - - No characters have been selected for the password. -Please select at least one character. - पासवर्ड के लिए कोई अक्षर नहीं चुना गया है. -कृपया कम से कम एक वर्ण चुनें. - - - - Show Password - पासवर्ड दिखाए - - - - Hide Password - पासवर्ड छिपाएं - - - - Password copied! - पासवर्ड कॉपी किया गया! - - - - The password is empty. Can't copy to clipboard. - पासवर्ड खाली है. क्लिपबोर्ड पर कॉपी नहीं किया जा सकता. - - - - Restart Required - पुनरारंभ करना आवश्यक है - - - - You will need to restart in order to use your new language setting -Your password will be lost if you do not save it before restarting. - अपनी नई भाषा सेटिंग का उपयोग करने के लिए आपको पुनः आरंभ करने की आवश्यकता होगी -यदि आप पुनः आरंभ करने से पहले इसे सहेजते नहीं हैं तो आपका पासवर्ड खो जाएगा।. - - - - Restart Now - अब पुनःचालू करें - - - - Restart Later - बाद में पुनः आरंभ करें - - - - Error - गलती - - - - Error: "enum QProcess::ProcessError" -Value error: %1 -The program can still be used -but cannot be restarted due to an error. - -Do you want copy this error in your clipboad? - त्रुटि: "enum QProcess::ProcessError" -मान त्रुटि: %1 -प्रोग्राम का अभी भी उपयोग किया जा सकता है -लेकिन किसी त्रुटि के कारण पुनः प्रारंभ नहीं किया जा सकता।. - -क्या आप इस त्रुटि को अपने क्लिपबोर्ड में कॉपी करना चाहते हैं? - - - - Copy to clipboard - क्लिपबोर्ड पर कॉपी करें - - - - No - नहीं - - - - <div style="text-align: center"><h1>%1</h1> -<p>Version: %2</p> -<p>GenPassword is a free password generator that helps you create random and customizable passwords. The program adds or removes characters in the following order: -</p> -<ol><li>Numbers, Symbols, Lowercase letters, Uppercase letters</li> -<li>Adds the letters that the user has specified</li> -<li>Removes the letters that the user has specified</li> -</ol><p>For issues or contributions, visit the <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub repository</a></p> -<p>Copyright © 2023 - CM0use</p> -<p>This program comes with NO WARRANTY OF ANY KIND.<br> -See the <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU General Public License</a> for details.</p></div> - <div style="text-align: center"><h1>%1</h1> -<p>संस्करण %2</p> -<p>GenPassword एक निःशुल्क पासवर्ड जनरेटर है जो आपको यादृच्छिक और अनुकूलन योग्य पासवर्ड बनाने में मदद करता है। प्रोग्राम निम्न क्रम में वर्ण जोड़ता या हटाता है: -</p> -<ol><li>संख्याएँ, चिह्न, छोटे अक्षर, बड़े अक्षर</li> -<li>उपयोगकर्ता द्वारा निर्दिष्ट अक्षरों को जोड़ता है</li> -<li>उपयोगकर्ता द्वारा निर्दिष्ट अक्षरों को हटा देता है</li> -</ol><p>मुद्दों या योगदान के लिए, <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub रिपॉजिटरी</a> पर जाएं</p> -<p>Copyright © 2023 - CM0use</p> -<p>यह प्रोग्राम किसी भी प्रकार की कोई वारंटी के साथ नहीं आता है।.<br> -विवरण के लिए <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU जनरल पब्लिक लाइसेंस</a> देखें।</p></div> - - - - About %1 - लगभग %1 - - - - <div style="text-align: center"><h1>%1</h1> -<p>Created by <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p> -<p>Contributors:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Helper)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (Icons)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> and <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (Translator)</li> -</ul><p>Inspired by design: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - <div style="text-align: center"><h1>%1</h1> -<p><a href=https://github.com/CM0use style=color:#0097CF>CM0use</a> द्वारा बनाया गया</p> -<p>योगदानकर्ताओं:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (सहायक)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (माउस)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> और <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (अनुवादक)</li> -</ul><p>डिज़ाइन से प्रेरित: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - - - - Credits - क्रेडिट - - - - QObject - - - GenPassword is now running - GenPassword अब चल रहा है - - - - The application is already running. -Another instance cannot be started. - आवेदन पहले से ही चल रहा है। -दूसरा उदाहरण प्रारंभ नहीं किया जा सकता. - - - - Error - गलती - - - - The theme index specified in the configuration file is invalid. -Please check the value and try again. - कॉन्फ़िगरेशन फ़ाइल में निर्दिष्ट थीम इंडेक्स अमान्य है. -कृपया मान जांचें और पुनः प्रयास करें।. - - - - - Exit - बाहर निकलना - - - diff --git a/src/languages/pt-BR.qm b/src/languages/pt-BR.qm deleted file mode 100644 index a896aea..0000000 Binary files a/src/languages/pt-BR.qm and /dev/null differ diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts deleted file mode 100644 index 3904d34..0000000 --- a/src/languages/pt-BR.ts +++ /dev/null @@ -1,357 +0,0 @@ - - - - - PasswordGeneratorApp - - - E&xit - &Sair - - - - &Generate Password - &Gerar senha - - - - Cut Password - Cortar senha - - - - &Copy Password - &Copiar senha - - - - &Use the standard palette of the theme - &Use a paleta padrão do tema - - - - &About %1 - &Sobre %1 - - - - &Credits - &Créditos - - - - About &Qt - Sobre o &Qt - - - - &File - &Arquivo - - - - &Edit - &Editar - - - - &View - &Ver - - - - &Help - Ajuda - - - - &Languages - &Idiomas - - - - &Themes - &Temas - - - - Your password will be generated here - Sua senha será gerada aqui - - - - Copy the password to the clipboard - Copiar a senha para a área de transferência - - - - Contain the numbers: 0-9 - Contém os números: 0-9 - - - - Contain special symbols: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - Contém símbolos especiais: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - - - - Contain lowercase letters: a-z - Contêm letras minúsculas: a-z - - - - Contain uppercase letters: A-Z - Contêm letras maiúsculas: A-Z - - - - Characters to add - Caracteres a serem adicionados - - - - Characters to remove - Caracteres a serem removidos - - - - Generate Password - Gerar senha - - - - - Warning - Advertência - - - - This option is enabled. -When this option is enabled, you will need to reselect the theme you have chosen. This will ensure that the theme is applied correctly. - -This is because Qt does not currently support stylesheets for custom QStyle subclasses. This functionality will be implemented in a future release. - Essa opção está ativada. -Quando essa opção estiver ativada, você precisará selecionar novamente o tema escolhido. Isso garantirá que o tema seja aplicado corretamente. - -Isso ocorre porque o Qt não suporta atualmente folhas de estilo para subclasses QStyle personalizadas. Essa funcionalidade será implementada em uma versão futura. - - - - This option is disabled. -After disabling this option, it is recommended that you reselect the theme you have chosen, once this is done you will not need to reselect a theme twice for the theme to be applied correctly. - Essa opção está desativada. -Depois de desativar essa opção, é recomendável que você selecione novamente o tema escolhido. Quando isso for feito, não será necessário selecionar novamente um tema duas vezes para que ele seja aplicado corretamente. - - - - Password Length - Comprimento da senha - - - - Numeric characters - Caracteres numéricos - - - - Symbols characters - Caracteres de símbolos - - - - Lowercase letters - Letras minúsculas - - - - Uppercase letters - Letras maiúsculas - - - - Add - Adicionar - - - - Remove - Remover - - - - Version %1 - Versão %1 - - - - Information - Informações - - - - No characters have been selected for the password. -Please select at least one character. - Nenhum caractere foi selecionado para a senha. -Selecione pelo menos um caractere. - - - - Show Password - Mostrar senha - - - - Hide Password - Ocultar senha - - - - Password copied! - Senha copiada! - - - - The password is empty. Can't copy to clipboard. - A senha está vazia. Não é possível copiar para a área de transferência. - - - - Restart Required - Reiniciar necessário - - - - You will need to restart in order to use your new language setting -Your password will be lost if you do not save it before restarting. - Será necessário reiniciar para usar a nova configuração de idioma -Sua senha será perdida se você não a salvar antes de reiniciar. - - - - Restart Now - Reiniciar agora - - - - Restart Later - Reiniciar mais tarde - - - - Error - Erro - - - - Error: "enum QProcess::ProcessError" -Value error: %1 -The program can still be used -but cannot be restarted due to an error. - -Do you want copy this error in your clipboad? - Erro: "enum QProcess::ProcessError" -Erro de valor: %1 -O programa ainda pode ser usado -mas não pode ser reiniciado devido a um erro. - -Deseja copiar esse erro em seu clipboad? - - - - Copy to clipboard - Copiar para a área de transferência - - - - No - Não - - - - <div style="text-align: center"><h1>%1</h1> -<p>Version: %2</p> -<p>GenPassword is a free password generator that helps you create random and customizable passwords. The program adds or removes characters in the following order: -</p> -<ol><li>Numbers, Symbols, Lowercase letters, Uppercase letters</li> -<li>Adds the letters that the user has specified</li> -<li>Removes the letters that the user has specified</li> -</ol><p>For issues or contributions, visit the <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub repository</a></p> -<p>Copyright © 2023 - CM0use</p> -<p>This program comes with NO WARRANTY OF ANY KIND.<br> -See the <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU General Public License</a> for details.</p></div> - <div style="text-align: center"><h1>%1</h1> -<p>Versão: %2</p> -<p>O GenPassword é um gerador de senhas gratuito que o ajuda a criar senhas aleatórias e personalizáveis. O programa adiciona ou remove caracteres na seguinte ordem: -</p> -<ol><li>Números, símbolos, letras minúsculas, letras maiúsculas</li> -<li>Adiciona as letras que o usuário especificou</li> -<li>Remove as letras que o usuário especificou</li> -</ol><p>Para problemas ou contribuições, visite o repositório <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub</a></p> -<p>Copyright © 2023 - CM0use</p> -<p>Este programa não oferece GARANTIA DE QUALQUER TIPO.<br> -Consulte a <a href=https://www.gnu.org/licenses/gpl-3.0.pt-br.html style=color:#0097CF>Licença Pública Geral GNU</a> para obter detalhes.</p></div> - - - - About %1 - Sobre %1 - - - - <div style="text-align: center"><h1>%1</h1> -<p>Created by <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p> -<p>Contributors:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Helper)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (Icons)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> and <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (Translator)</li> -</ul><p>Inspired by design: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - <div style="text-align: center"><h1>%1</h1> -<p>Criado por <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p> -<p>Contribuintes:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Ajudante)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (Ícones)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> e <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (Tradutor)</li> -</ul><p>Inspirado pelo design: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - - - - Credits - Créditos - - - - QObject - - - GenPassword is now running - O GenPassword está em execução - - - - The application is already running. -Another instance cannot be started. - O aplicativo já está em execução. -Outra instância não pode ser iniciada. - - - - Error - Erro - - - - The theme index specified in the configuration file is invalid. -Please check the value and try again. - O índice do tema especificado no arquivo de configuração é inválido. -Verifique o valor e tente novamente. - - - - - Exit - Sair - - - diff --git a/src/languages/zh-CN.qm b/src/languages/zh-CN.qm deleted file mode 100644 index 146c750..0000000 Binary files a/src/languages/zh-CN.qm and /dev/null differ diff --git a/src/languages/zh-CN.ts b/src/languages/zh-CN.ts deleted file mode 100644 index 5998e2a..0000000 --- a/src/languages/zh-CN.ts +++ /dev/null @@ -1,357 +0,0 @@ - - - - - PasswordGeneratorApp - - - E&xit - 退出 - - - - &Generate Password - 生成密码 - - - - Cut Password - 剪切密码 - - - - &Copy Password - 复制密码 - - - - &Use the standard palette of the theme - 使用主题的标准调色板 - - - - &About %1 - 关于 %1 - - - - &Credits - 荣誉 - - - - About &Qt - 关于 &Qt - - - - &File - 文件 - - - - &Edit - 编辑 - - - - &View - 查看 - - - - &Help - 帮助 - - - - &Languages - 语言 - - - - &Themes - 主题 - - - - Your password will be generated here - 您的密码将在此处生成 - - - - Copy the password to the clipboard - 将密码复制到剪贴板 - - - - Contain the numbers: 0-9 - 包含数字 0-9 - - - - Contain special symbols: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - 包含特殊符号: -!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ - - - - Contain lowercase letters: a-z - 包含小写字母:a-z - - - - Contain uppercase letters: A-Z - 包含大写字母: A-Z - - - - Characters to add - 要添加的字符 - - - - Characters to remove - 要删除的字符 - - - - Generate Password - 生成密码 - - - - - Warning - 警告 - - - - This option is enabled. -When this option is enabled, you will need to reselect the theme you have chosen. This will ensure that the theme is applied correctly. - -This is because Qt does not currently support stylesheets for custom QStyle subclasses. This functionality will be implemented in a future release. - 该选项已启用。 -启用该选项后,您需要重新选择所选主题。这将确保正确应用主题。 - -这是因为 Qt 目前不支持自定义 QStyle 子类的样式表。这一功能将在未来的版本中实现。 - - - - This option is disabled. -After disabling this option, it is recommended that you reselect the theme you have chosen, once this is done you will not need to reselect a theme twice for the theme to be applied correctly. - 此选项已禁用。 -禁用该选项后,建议您重新选择所选的主题,这样您就不需要为正确应用主题而重新选择两次了。 - - - - Password Length - 密码长度 - - - - Numeric characters - 数字字符 - - - - Symbols characters - 符号字符 - - - - Lowercase letters - 小写字母 - - - - Uppercase letters - 大写字母 - - - - Add - 添加 - - - - Remove - 移除 - - - - Version %1 - 版本 %1 - - - - Information - 信息 - - - - No characters have been selected for the password. -Please select at least one character. - 密码未选择任何字符。 -请至少选择一个字符。 - - - - Show Password - 显示密码 - - - - Hide Password - 隐藏密码 - - - - Password copied! - 密码已复制! - - - - The password is empty. Can't copy to clipboard. - 密码为空。无法复制到剪贴板。 - - - - Restart Required - 需要重新启动 - - - - You will need to restart in order to use your new language setting -Your password will be lost if you do not save it before restarting. - 您需要重新启动才能使用新的语言设置。 -如果重启前没有保存密码,密码将丢失。 - - - - Restart Now - 立即重启 - - - - Restart Later - 稍后重启 - - - - Error - 错误 - - - - Error: "enum QProcess::ProcessError" -Value error: %1 -The program can still be used -but cannot be restarted due to an error. - -Do you want copy this error in your clipboad? - 错误: "enum QProcess::ProcessError" -值错误:%1 -程序仍可使用 -但由于错误而无法重新启动。 - -你想把这个错误复制到你的剪贴板中吗? - - - - Copy to clipboard - 复制到剪贴板 - - - - No - 没有 - - - - <div style="text-align: center"><h1>%1</h1> -<p>Version: %2</p> -<p>GenPassword is a free password generator that helps you create random and customizable passwords. The program adds or removes characters in the following order: -</p> -<ol><li>Numbers, Symbols, Lowercase letters, Uppercase letters</li> -<li>Adds the letters that the user has specified</li> -<li>Removes the letters that the user has specified</li> -</ol><p>For issues or contributions, visit the <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub repository</a></p> -<p>Copyright © 2023 - CM0use</p> -<p>This program comes with NO WARRANTY OF ANY KIND.<br> -See the <a href=https://www.gnu.org/licenses/gpl-3.0.html style=color:#0097CF>GNU General Public License</a> for details.</p></div> - <div style="text-align: center"><h1>%1</h1> -<p>版本:%2</p> -<p>GenPassword 是一款免费的密码生成器,可帮助您创建随机和可定制的密码。程序按以下顺序添加或删除字符: -</p> -<ol><li>数字、符号、小写字母、大写字母</li> -<li>添加用户指定的字母</li> -<li>删除用户指定的字母</li> -</ol><p>有关问题或贡献,请访问 <a href=https://github.com/CM0use/GenPassword style=color:#0097CF>GitHub 软件源</a></p> -<p>Copyright © 2023 - CM0use</p> -<p>本程序不提供任何形式的担保。<br> -有关详情,请参阅 <a href=https://www.gnu.org/licenses/gpl-3.0.zh-cn.html style=color:#0097CF>GNU 通用公共许可证</a>。</p></div> - - - - About %1 - 关于 %1 - - - - <div style="text-align: center"><h1>%1</h1> -<p>Created by <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a></p> -<p>Contributors:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (Helper)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (Icons)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> and <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (Translator)</li> -</ul><p>Inspired by design: <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - <div style="text-align: center"><h1>%1</h1> -<p>由 <a href=https://github.com/CM0use style=color:#0097CF>CM0use</a> 创建</p> -<p>贡献者:</p> -<ul><li><a href=https://bard.google.com style=color:#0097CF>Google Bard</a> (助手)</li> -<li><a href=https://www.flaticon.com/authors/fr-media style=color:#0097CF>FR_Media - Flaticon</a> (图标)</li> -<li><a href=https://www.deepl.com/translator style=color:#0097CF>DeepL</a> 和 <a href=https://translate.google.com style=color:#0097CF>Google Translate</a> (翻译)</li> -</ul><p>设计的灵感 <a href=https://github.com/ChristopherNugent/Locksmith style=color:#0097CF>Locksmith</a></p></div> - - - - Credits - 荣誉 - - - - QObject - - - GenPassword is now running - GenPassword 正在运行 - - - - The application is already running. -Another instance cannot be started. - 应用程序已在运行。 -无法启动另一个实例。 - - - - Error - 错误 - - - - The theme index specified in the configuration file is invalid. -Please check the value and try again. - 配置文件中指定的主题索引无效。 -请检查该值并重试。 - - - - - Exit - 退出 - - - diff --git a/src/main.cpp b/src/main.cpp index bdac78f..eb82f7c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,41 +1,25 @@ -/** - ** This file is part of the GenPassword project. - ** Copyright 2023 CM0use dilanuzcs@gmail.com - ** URL: https://github.com/CM0use/GenPassword - ** - ** This program is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** 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 General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with this program. If not, see . - **/ +// GenPassword +// Copyright (c) 2023 CM0use + +#include "passwordgenerator.h" +#include "icons.h" #include -#include +#include +#include +#include #include +#include #include -#include -#include -#include #include -#include "passwordgeneratorapp.h" - -void initializeDefaultSettings(QSettings &settings); - int main(int argc, char *argv[]) { QApplication app{ argc, argv }; + app.setStyle(QStyleFactory::create("Fusion")); app.setApplicationName("GenPassword"); - app.setApplicationVersion("1.0.0"); - app.setWindowIcon(APPICON); + app.setWindowIcon(APP_ICON_LIGHT); + app.setApplicationVersion("2.0.0"); app.setOrganizationName("CM0use"); app.setOrganizationDomain("https://github.com/CM0use"); @@ -44,28 +28,36 @@ int main(int argc, char *argv[]) config.mkdir("config"); } - QSettings settings{ app.applicationDirPath() - + "/config/Settings.ini", + QSettings settings{ app.applicationDirPath() + "/config/Settings.ini", QSettings::Format::IniFormat }; - initializeDefaultSettings(settings); + if (!QFile::exists(settings.fileName())) { + settings.setValue("Settings/IndexLanguage", 0); + settings.setValue("Settings/IndexTheme", 0); + settings.setValue("Settings/HidePassword", true); + settings.setValue("Settings/Length", 32); + settings.setValue("Settings/Numeric", false); + settings.setValue("Settings/Symbols", false); + settings.setValue("Settings/Lowercase", false); + settings.setValue("Settings/Uppercase", false); + settings.setValue("Settings/Add", ""); + settings.setValue("Settings/Remove", ""); + } QTranslator translator; - const QStringList languages{ "en", "zh-CN", "hi", - "es", "pt-BR" }; + const QStringList languages{ "en.qm", "es.qm" }; int indexLanguage{ settings.value("Settings/IndexLanguage").toInt() }; if (indexLanguage >= 0 && indexLanguage < languages.size()) { - QString translationFile{ ":/i18n/languages/" + - languages[indexLanguage] }; - if (translator.load(translationFile)) + if (!indexLanguage); + else if (translator.load(":/i18n/" + languages[indexLanguage])) app.installTranslator(&translator); - else return QMessageBox::critical(nullptr, "Error", - "Could not load translation file.", - "Exit"); + else QMessageBox::warning(nullptr, "Warning", + "Could not load translation file.", + QMessageBox::StandardButton::Close); } else return QMessageBox::critical(nullptr, "Error", "The language index specified in the " "configuration file is invalid. \n" "Please check the value and try again.", - "Exit"); + QMessageBox::StandardButton::Abort); QSharedMemory sharedMemory(app.applicationName()); if (!sharedMemory.create(1)) { @@ -74,50 +66,25 @@ int main(int argc, char *argv[]) QObject::tr("The application is already " "running.\nAnother instance " "cannot be started."), - QObject::tr("Exit")); + QMessageBox::StandardButton::Abort); } - const QStringList themesNames{ QStyleFactory::keys() }; - int indexTheme { settings.value("Settings/IndexTheme").toInt() }; - if (indexTheme >= 0 && indexTheme < themesNames.size()) - app.setStyle(themesNames[indexTheme]); - else return QMessageBox::critical(nullptr, QObject::tr("Error"), + const QStringList themes{ "light.css", "dark.css" }; + int indexTheme{ settings.value("Settings/IndexTheme").toInt() }; + if (indexTheme >= 0 && indexTheme < themes.size()) { + QFile styleSheetFile{ ":/qss/" + themes[indexTheme] }; + styleSheetFile.open(QFile::ReadOnly); + app.setStyleSheet(styleSheetFile.readAll()); + } else return QMessageBox::critical(nullptr, QObject::tr("Error"), QObject::tr("The theme index specified " "in the configuration file " "is invalid. \nPlease check " "the value and try again."), - QObject::tr("Exit")); - - QFile styleSheetFile{ ":/style/qss/stylesheet.qss" }; - styleSheetFile.open(QFile::ReadOnly); - app.setStyleSheet(styleSheetFile.readAll()); + QMessageBox::StandardButton::Abort); - const std::uint16_t - WIDTH{ 400 }, - HEIGHT{ 300 }, - DPI_DEFAULT{ 96 }; - qreal screenDPI { app.primaryScreen()->logicalDotsPerInch() }; - QSize windowDimensions(WIDTH * screenDPI / DPI_DEFAULT, - HEIGHT * screenDPI / DPI_DEFAULT); - - PasswordGeneratorApp mainWindow; - mainWindow.setFixedHeight(windowDimensions.height()); + PasswordGenerator mainWindow; + mainWindow.setFixedHeight(mainWindow.sizeHint().height()); mainWindow.show(); - return app.exec(); -} -void initializeDefaultSettings(QSettings &settings) -{ - if (!QFile::exists(settings.fileName())) { - settings.setValue("Settings/IndexLanguage", 0); - settings.setValue("Settings/IndexTheme", 0); - settings.setValue("Settings/ShowPassword", false); - settings.setValue("Settings/Length", 16); - settings.setValue("Settings/Numeric", false); - settings.setValue("Settings/Symbols", false); - settings.setValue("Settings/lowercase", false); - settings.setValue("Settings/UpperCase", false); - settings.setValue("Settings/Add", ""); - settings.setValue("Settings/Remove", ""); - } + return app.exec(); } diff --git a/src/passwordgenerator.cpp b/src/passwordgenerator.cpp new file mode 100644 index 0000000..7223c16 --- /dev/null +++ b/src/passwordgenerator.cpp @@ -0,0 +1,292 @@ +// GenPassword +// Copyright (c) 2023 CM0use + +#include "passwordgenerator.h" +#include "switchbutton.h" +#include "icons.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PasswordGenerator::PasswordGenerator(QWidget *const parent) + : Window{ parent } +{ + createWidgets(); + configureWidgets(); + createUi(); + updateAllIcons(false); + connectSignals(); +} + +void PasswordGenerator::createWidgets() +{ + passwordLineEdit = new QLineEdit; + newPasswordButton = new QToolButton; + showPasswordButton = new QToolButton; + copyToClipBoardButton = new QToolButton; + + passwordLengthSlider = new QSlider(Qt::Horizontal); + passwordLengthSpinBox = new QSpinBox; + + const qsizetype currentIndexTheme{ getCurrentIndexTheme() }; + numericSwitch = new SwitchButton(QObject::tr("Numeric characters"), currentIndexTheme); + symbolsSwitch = new SwitchButton(QObject::tr("Symbols characters"), currentIndexTheme); + lowercaseSwitch = new SwitchButton(QObject::tr("Lowercase letters"), currentIndexTheme); + uppercaseSwitch = new SwitchButton(QObject::tr("Uppercase letters"), currentIndexTheme); + + addCharsLineEdit = new QLineEdit; + removeCharLineEdit = new QLineEdit; +} + +void PasswordGenerator::configureWidgets() +{ + passwordLineEdit->setReadOnly(true); + passwordLineEdit->setFocusPolicy(Qt::FocusPolicy::NoFocus); + passwordLineEdit->setPlaceholderText(QObject::tr("Your password will be generated here")); + + showPasswordButton->setAutoRaise(true); + showPasswordButton->setCheckable(true); + showPasswordButton->setChecked(userSettings->value("Settings/HidePassword").toBool()); + onShowPasswordButtonClicked(); + + newPasswordButton->setAutoRaise(true); + newPasswordButton->setToolTip(QObject::tr("Generate a new password")); + + copyToClipBoardButton->setAutoRaise(true); + copyToClipBoardButton->setToolTip(QObject::tr("Copy the password to the clipboard")); + + passwordLengthSlider->setRange(1, 512); + passwordLengthSlider->setValue(userSettings->value("Settings/Length").toInt()); + passwordLengthSpinBox->setRange(1, 512); + passwordLengthSpinBox->setValue(userSettings->value("Settings/Length").toInt()); + + numericSwitch->setLayoutDirection(Qt::RightToLeft); + numericSwitch->setChecked(userSettings->value("Settings/Numeric").toBool()); + numericSwitch->setToolTip(QObject::tr("Contain the numbers: 0-9")); + + symbolsSwitch->setLayoutDirection(Qt::RightToLeft); + symbolsSwitch->setChecked(userSettings->value("Settings/Symbols").toBool()); + symbolsSwitch->setToolTip(QObject::tr("Contain special symbols:\n!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")); + + lowercaseSwitch->setLayoutDirection(Qt::RightToLeft); + lowercaseSwitch->setChecked(userSettings->value("Settings/Lowercase").toBool()); + lowercaseSwitch->setToolTip(QObject::tr("Contain lowercase letters: a-z")); + + uppercaseSwitch->setLayoutDirection(Qt::RightToLeft); + uppercaseSwitch->setChecked(userSettings->value("Settings/Uppercase").toBool()); + uppercaseSwitch->setToolTip(QObject::tr("Contain uppercase letters: A-Z")); + + addCharsLineEdit->setPlaceholderText(QObject::tr("Characters to add")); + addCharsLineEdit->setText(userSettings->value("Settings/Add").toString()); + + removeCharLineEdit->setPlaceholderText(QObject::tr("Characters to remove")); + removeCharLineEdit->setText(userSettings->value("Settings/Remove").toString()); +} + +void PasswordGenerator::createUi() +{ + std::array horizontalLayout + { + new QHBoxLayout, + new QHBoxLayout, + new QHBoxLayout, + new QHBoxLayout, + new QHBoxLayout, + new QHBoxLayout + }; + + horizontalLayout[0]->addWidget(passwordLineEdit); + horizontalLayout[0]->addWidget(newPasswordButton); + horizontalLayout[0]->addWidget(showPasswordButton); + horizontalLayout[0]->addWidget(copyToClipBoardButton); + + horizontalLayout[1]->addWidget(passwordLengthSlider); + horizontalLayout[1]->addWidget(passwordLengthSpinBox); + + horizontalLayout[2]->addWidget(numericSwitch); + horizontalLayout[2]->addWidget(symbolsSwitch); + + horizontalLayout[3]->addWidget(lowercaseSwitch); + horizontalLayout[3]->addWidget(uppercaseSwitch); + + horizontalLayout[4]->addWidget(new QLabel(QObject::tr("Add")), 0, Qt::AlignCenter); + horizontalLayout[4]->addWidget(new QLabel(QObject::tr("Remove")), 0, Qt::AlignCenter); + + horizontalLayout[5]->addWidget(addCharsLineEdit); + horizontalLayout[5]->addWidget(removeCharLineEdit); + + QGridLayout *const mainGridLayout{ new QGridLayout }; + mainGridLayout->addWidget(getTitleBar()); + mainGridLayout->addLayout(horizontalLayout[0], 1, 0); + mainGridLayout->addLayout(horizontalLayout[1], 2, 0); + mainGridLayout->addLayout(horizontalLayout[2], 3, 0, Qt::AlignCenter); + mainGridLayout->addLayout(horizontalLayout[3], 4, 0, Qt::AlignCenter); + mainGridLayout->addLayout(horizontalLayout[4], 5, 0); + mainGridLayout->addLayout(horizontalLayout[5], 6, 0); + + QWidget *const mainWidget{ new QWidget }; + mainWidget->setLayout(mainGridLayout); + setCentralWidget(mainWidget); +} + +void PasswordGenerator::updateAllIcons(bool allIcons) +{ + const qsizetype currentIndexTheme{ getCurrentIndexTheme() }; + if (currentIndexTheme) { + newPasswordButton->setIcon(REFRESH_ICON_LIGHT); + showPasswordButton->setIcon(showPasswordButton->isChecked()? VISIBILITYOFF_ICON_LIGHT: VISIBILITYON_ICON_LIGHT); + copyToClipBoardButton->setIcon(COPY_ICON_LIGHT); + } else { + newPasswordButton->setIcon(REFRESH_ICON_DARK); + showPasswordButton->setIcon(showPasswordButton->isChecked()? VISIBILITYOFF_ICON_DARK: VISIBILITYON_ICON_DARK); + copyToClipBoardButton->setIcon(COPY_ICON_DARK); + } + + if(allIcons) { + if (currentIndexTheme) { + numericSwitch->setThemeDark(); + symbolsSwitch->setThemeDark(); + lowercaseSwitch->setThemeDark(); + uppercaseSwitch->setThemeDark(); + } else { + numericSwitch->setThemeLight(); + symbolsSwitch->setThemeLight(); + lowercaseSwitch->setThemeLight(); + uppercaseSwitch->setThemeLight(); + } + + Window::updateIcons(); + } +} + +void PasswordGenerator::connectSignals() +{ + connect(this, &Window::themeChanged, this, &PasswordGenerator::updateAllIcons); + connect(this, &Window::newPasswordSignal, this, &PasswordGenerator::generatePassword); + connect(this, &Window::cutPasswordSignal, this, &PasswordGenerator::copyPasswordToClipboard); + + connect(newPasswordButton, &QToolButton::clicked, this, &PasswordGenerator::generatePassword); + connect(showPasswordButton, &QToolButton::clicked, this, &PasswordGenerator::onShowPasswordButtonClicked); + connect(copyToClipBoardButton, &QToolButton::clicked, this, &PasswordGenerator::copyPasswordToClipboard); + + connect(passwordLengthSlider, &QSlider::valueChanged, + this, [this] (int value) { passwordLengthSpinBox->setValue(value); }); + connect(passwordLengthSpinBox, &QSpinBox::valueChanged, + this, [this] (int value) { passwordLengthSlider->setValue(value); }); + + connect(this, &Window::newAndCopyPassowrdSignal, + this, [this] { generatePassword(); copyPasswordToClipboard(false); }); + + connect(this, &Window::saveSettingsSignal, this, [this] { + userSettings->setValue("Settings/HidePassword", showPasswordButton->isChecked()); + userSettings->setValue("Settings/Length", passwordLengthSpinBox->value()); + userSettings->setValue("Settings/Numeric", numericSwitch->isChecked()); + userSettings->setValue("Settings/Symbols", symbolsSwitch->isChecked()); + userSettings->setValue("Settings/Lowercase", lowercaseSwitch->isChecked()); + userSettings->setValue("Settings/Uppercase", uppercaseSwitch->isChecked()); + userSettings->setValue("Settings/Add", addCharsLineEdit->text()); + userSettings->setValue("Settings/Remove", removeCharLineEdit->text()); + }); +} + +void PasswordGenerator::generatePassword() +{ + const std::array selectedCharacters + { + numericSwitch->isChecked(), + symbolsSwitch->isChecked(), + lowercaseSwitch->isChecked(), + uppercaseSwitch->isChecked() + }; + + bool hasAnyCharactersSelected + { + std::any_of(selectedCharacters.begin(), selectedCharacters.end(), + [] (bool valueSwitch) { return valueSwitch; }) + }, hasAdditionalCharactersToInclude{ !addCharsLineEdit->text().isEmpty() }; + + if (hasAnyCharactersSelected || hasAdditionalCharactersToInclude) { + const static std::array possibleCharacters + { + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + }; + + QString charactersToUse; + for(const QString &characters: possibleCharacters) + charactersToUse.append(characters); + + for(size_t index{0}; index < selectedCharacters.size(); ++index) + if (!selectedCharacters[index]) + charactersToUse.remove(possibleCharacters[index]); + + for(QChar &c: addCharsLineEdit->text()) + if (!charactersToUse.contains(c)) + charactersToUse.append(c); + + for(QChar &c: removeCharLineEdit->text()) + if (charactersToUse.contains(c)) + charactersToUse.remove(c); + + QString password{ passwordLengthSpinBox->value(), ' ' }; + + bool hasCharactersToUse{ !charactersToUse.isEmpty() }; + if (hasCharactersToUse) { + for(QChar &letter: password) + letter = charactersToUse[QRandomGenerator:: + global()->bounded(0, charactersToUse.size())]; + passwordLineEdit->setText(password); + return; + } + } + QMessageBox::information(this, QObject::tr("Information"), + QObject::tr("No characters have been " + "selected for the password. " + "\nPlease select at least one character.")); +} + +void PasswordGenerator::onShowPasswordButtonClicked() +{ + if (showPasswordButton->isChecked()) { + showPasswordButton->setIcon(getCurrentIndexTheme()? VISIBILITYOFF_ICON_LIGHT: VISIBILITYOFF_ICON_DARK); + passwordLineEdit->setEchoMode(QLineEdit::Password); + showPasswordButton->setToolTip(QObject::tr("Hide Password")); + } else { + showPasswordButton->setIcon(getCurrentIndexTheme()? VISIBILITYON_ICON_LIGHT: VISIBILITYON_ICON_DARK); + passwordLineEdit->setEchoMode(QLineEdit::Normal); + showPasswordButton->setToolTip(QObject::tr("Show Password")); + } +} + +void PasswordGenerator::copyPasswordToClipboard(bool isCutAction) +{ + QString password{ passwordLineEdit->text() }; + if (!password.isEmpty()) { + if (isCutAction) + passwordLineEdit->clear(); + QApplication::clipboard()->setText(password); + if (getCurrentIndexTheme()) { + copyToClipBoardButton->setIcon(DONE_ICON_LIGHT); + QTimer::singleShot(1000, this, [this] { + copyToClipBoardButton->setIcon(COPY_ICON_LIGHT); + }); + } else { + copyToClipBoardButton->setIcon(DONE_ICON_DARK); + QTimer::singleShot(1000, this, [this] { + copyToClipBoardButton->setIcon(COPY_ICON_DARK); + }); + } + } +} diff --git a/src/passwordgenerator.h b/src/passwordgenerator.h new file mode 100644 index 0000000..185b06a --- /dev/null +++ b/src/passwordgenerator.h @@ -0,0 +1,41 @@ +// GenPassword +// Copyright (c) 2023 CM0use + +#ifndef PASSWORDGENERATOR_H +#define PASSWORDGENERATOR_H + +#include "window.h" + +QT_BEGIN_NAMESPACE +class QLineEdit; +class QSlider; +class QSpinBox; +class SwitchButton; +QT_END_NAMESPACE + +class PasswordGenerator final: public Window +{ +public: + explicit PasswordGenerator(QWidget *const parent = nullptr); + virtual ~PasswordGenerator() = default; + +private: + void createWidgets(); + void configureWidgets(); + void createUi(); + void updateAllIcons(bool allIcons = true); + void connectSignals(); + + void generatePassword(); + void onShowPasswordButtonClicked(); + void copyPasswordToClipboard(bool isCutAction); + + QLineEdit *passwordLineEdit, + *addCharsLineEdit, *removeCharLineEdit; + QToolButton *newPasswordButton, *showPasswordButton, *copyToClipBoardButton; + QSlider *passwordLengthSlider; + QSpinBox *passwordLengthSpinBox; + SwitchButton *numericSwitch, *symbolsSwitch, + *lowercaseSwitch, *uppercaseSwitch; +}; +#endif // PASSWORDGENERATOR_H diff --git a/src/passwordgeneratorapp.cpp b/src/passwordgeneratorapp.cpp deleted file mode 100644 index 3daf0a8..0000000 --- a/src/passwordgeneratorapp.cpp +++ /dev/null @@ -1,659 +0,0 @@ -/** - ** This file is part of the GenPassword project. - ** Copyright 2023 CM0use dilanuzcs@gmail.com - ** URL: https://github.com/CM0use/GenPassword - ** - ** This program is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** 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 General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with this program. If not, see . - **/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "passwordgeneratorapp.h" - -PasswordGeneratorApp::PasswordGeneratorApp(QWidget *const parent) - : QMainWindow{ parent }, - userSettings{ new QSettings(QCoreApplication::applicationDirPath() - + "/config/Settings.ini", - QSettings::Format::IniFormat) }, - currentIndexLanguage{ userSettings-> - value("Settings/IndexLanguage").toInt() }, - currentIndexTheme{ userSettings-> - value("Settings/IndexTheme").toInt() }, - appVersion{ qApp->applicationVersion() }, appName{ qApp->applicationName() } -{ - createActions(); - configurateActions(); - createMenus(); - configurateMenus(); - createWidgets(); - configureWidgets(); - if (myTrayIcon->isSystemTrayAvailable()) { - createTrayIcon(); - configurateTrayIcon(); - } - connectSignals(); - createUi(); -} - -void PasswordGeneratorApp::createActions() -{ - exitAction = { new QAction(this) }; - - generatePasswordAction = { new QAction(this) }; - cutPasswordAction = { new QAction(this) }; - copyPasswordAction = { new QAction(this) }; - for(const QString &languageName: availableLanguages()) - languageActionList.append(new QAction{ languageName, this }); - - for(const QString &themeName: QStyleFactory::keys()) - themeActionList.append(new QAction{ themeName, this }); - - useStylePaletteAction = { new QAction }; - - aboutAction = { new QAction(this) }; - creditsAction = { new QAction(this) }; - aboutQtAction = { new QAction(this) }; -} - -void PasswordGeneratorApp::configurateActions() -{ - exitAction->setText(tr("E&xit")); - exitAction->setShortcut(QKeySequence("Ctrl+Q")); - exitAction->setShortcutVisibleInContextMenu(false); - - generatePasswordAction->setText(tr("&Generate Password")); - generatePasswordAction->setShortcut(QKeySequence::New); - generatePasswordAction->setShortcutVisibleInContextMenu(false); - - cutPasswordAction->setText(tr("Cut Password")); - cutPasswordAction->setObjectName("cut"); - cutPasswordAction->setShortcut(QKeySequence::Cut); - cutPasswordAction->setShortcutVisibleInContextMenu(false); - - copyPasswordAction->setText(tr("&Copy Password")); - copyPasswordAction->setShortcut(QKeySequence::Copy); - copyPasswordAction->setShortcutVisibleInContextMenu(false); - - for(qsizetype index{0}; const QString &statusTip: languagesStatusTip()) - languageActionList[index++]->setStatusTip(statusTip); - - languageActionList[currentIndexLanguage]-> - setIcon(style()->standardIcon(QStyle::SP_DialogApplyButton)); - - themeActionList[currentIndexTheme]-> - setIcon(style()->standardIcon(QStyle::SP_DialogApplyButton)); - - useStylePaletteAction->setText(tr - ("&Use the standard palette of the theme")); - useStylePaletteAction->setCheckable(true); - - aboutAction->setText(tr("&About %1").arg(appName)); - aboutAction->setIcon(style()-> - standardIcon(QStyle::SP_MessageBoxInformation)); - - creditsAction->setText(tr("&Credits")); - creditsAction->setIcon(QIcon{ ":/icons/icon/heart.png" }); - - aboutQtAction->setText(tr("About &Qt")); - aboutQtAction->setIcon(style()-> - standardIcon(QStyle::SP_TitleBarMenuButton)); -} - -void PasswordGeneratorApp::createMenus() -{ - fileMenu = { menuBar()->addMenu(tr("&File")) }; - editMenu = { menuBar()->addMenu(tr("&Edit")) }; - viewMenu = { menuBar()->addMenu(tr("&View")) }; - helpMenu = { menuBar()->addMenu(tr("&Help")) }; -} - -void PasswordGeneratorApp::configurateMenus() -{ - fileMenu->addAction(exitAction); - - editMenu->addAction(generatePasswordAction); - editMenu->addSeparator(); - editMenu->addAction(cutPasswordAction); - editMenu->addAction(copyPasswordAction); - editMenu->addSeparator(); - languagesMenu = { editMenu->addMenu(tr("&Languages")) }; - languagesMenu->addActions(languageActionList); - - themesMenu = { viewMenu->addMenu(tr("&Themes")) }; - themesMenu->addActions(themeActionList); - themesMenu->addSeparator(); - themesMenu->addAction(useStylePaletteAction); - - helpMenu->addAction(aboutAction); - helpMenu->addAction(creditsAction); - helpMenu->addAction(aboutQtAction); -} - -void PasswordGeneratorApp::createWidgets() -{ - passwordLineEdit = { new QLineEdit }; - copyToClipBoardButton = { new QPushButton }; - spinBoxPasswordLength = { new QSpinBox }; - showPasswordButton = { new QPushButton }; - checkBoxNumeric = { new QCheckBox }; - checkBoxSymbols = { new QCheckBox }; - lowercaseCheckBox = { new QCheckBox }; - upperCaseCheckBox = { new QCheckBox }; - addCharsLineEdit = { new QLineEdit }; - removeCharLineEdit = { new QLineEdit }; - buttonGeneratePassword = { new QPushButton }; -} - -void PasswordGeneratorApp::configureWidgets() -{ - passwordLineEdit->setPlaceholderText(tr("Your password will " - "be generated here")); - passwordLineEdit->setReadOnly(true); - passwordLineEdit->setFocusPolicy(Qt::FocusPolicy::NoFocus); - - showPasswordButton->setCheckable(true); - showPasswordButton->setChecked(userSettings->value("Settings/ShowPassword") - .toBool()); - showPasswordButton->setIcon(QIcon{ ":/icons/icon/showPassword.png" }); - onShowPasswordButtonClicked(); - - copyToClipBoardButton->setToolTip(tr("Copy the password to the clipboard")); - copyToClipBoardButton->setIcon(QIcon{ ":/icons/icon/clipboard.png" }); - - spinBoxPasswordLength->setMinimum(1); - spinBoxPasswordLength->setMaximum(256); - - spinBoxPasswordLength->setValue(userSettings-> - value("Settings/Length").toInt()); - checkBoxNumeric->setChecked(userSettings-> - value("Settings/Numeric").toBool()); - checkBoxNumeric->setToolTip(tr("Contain the numbers: 0-9")); - checkBoxSymbols->setChecked(userSettings-> - value("Settings/Symbols").toBool()); - checkBoxSymbols->setToolTip(tr("Contain special symbols:\n" - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")); - lowercaseCheckBox->setChecked(userSettings-> - value("Settings/lowercase").toBool()); - lowercaseCheckBox->setToolTip(tr("Contain lowercase letters: a-z")); - upperCaseCheckBox->setChecked(userSettings-> - value("Settings/UpperCase").toBool()); - upperCaseCheckBox->setToolTip(tr("Contain uppercase letters: A-Z")); - - addCharsLineEdit->setPlaceholderText(tr("Characters to add")); - addCharsLineEdit->setText(userSettings->value("Settings/Add").toString()); - - removeCharLineEdit->setPlaceholderText(tr("Characters to remove")); - removeCharLineEdit->setText(userSettings-> - value("Settings/Remove").toString()); - - buttonGeneratePassword->setText(tr("Generate Password")); -} - -void PasswordGeneratorApp::createTrayIcon() -{ - myTrayIconMenu = { new QMenu(this) }; - myTrayIcon = { new QSystemTrayIcon(APPICON, this) }; -} - -void PasswordGeneratorApp::configurateTrayIcon() -{ - myTrayIconMenu->addAction(generatePasswordAction); - myTrayIconMenu->addSeparator(); - myTrayIconMenu->addAction(cutPasswordAction); - myTrayIconMenu->addAction(copyPasswordAction); - myTrayIconMenu->addSeparator(); - myTrayIconMenu->addAction(exitAction); - - myTrayIcon->setContextMenu(myTrayIconMenu); - myTrayIcon->show(); - myTrayIcon->setToolTip(appName); - connect(myTrayIcon, &QSystemTrayIcon::activated, - this, &PasswordGeneratorApp::iconActivated); -} - -void PasswordGeneratorApp::iconActivated(QSystemTrayIcon:: - ActivationReason reason) -{ - if (reason == QSystemTrayIcon::Trigger) { - if (!isActiveWindow() || isHidden() || isMinimized()) { - activateWindow(); - showNormal(); - } - } -} - -void PasswordGeneratorApp::connectSignals() -{ - connect(exitAction, &QAction::triggered, this, - &PasswordGeneratorApp::close); - - connect(generatePasswordAction, &QAction::triggered, - this, &PasswordGeneratorApp::generatePassword); - - connect(cutPasswordAction, &QAction::triggered, - this, &PasswordGeneratorApp::copyPasswordToClipboard); - connect(copyPasswordAction, &QAction::triggered, - this, &PasswordGeneratorApp::copyPasswordToClipboard); - - for(const QAction *const languageAction: languageActionList) - connect(languageAction, &QAction::triggered, - this, &PasswordGeneratorApp::changeLanguage); - - for(const QAction *const themeAction: themeActionList) - connect(themeAction, &QAction::triggered, - this, &PasswordGeneratorApp::changeStyle); - - connect(useStylePaletteAction, &QAction::triggered, - this, &PasswordGeneratorApp::changePalette); - connect(useStylePaletteAction, &QAction::triggered, - this, [&](bool isEnabled) { - if (isEnabled) QMessageBox::warning(this, tr("Warning"), - tr("This option is enabled.\nWhen this" - " option is enabled, you will need " - "to reselect the theme you have " - "chosen. This will ensure that " - "the theme is applied correctly." - "\n\nThis is because Qt does " - "not currently support stylesheets " - "for custom QStyle subclasses. " - "This functionality will be " - "implemented in " - "a future release.")); - else QMessageBox::warning(this, tr("Warning"), - tr("This option is disabled.\n" - "After disabling this option, " - "it is recommended that you " - "reselect the theme you have " - "chosen, once this is done you " - "will not need to reselect a theme " - "twice for the theme " - "to be applied correctly.")); - }); - - connect(aboutAction, &QAction::triggered, - this, &PasswordGeneratorApp::about); - connect(creditsAction, &QAction::triggered, - this, &PasswordGeneratorApp::credits); - connect(aboutQtAction, &QAction::triggered, qApp, &QApplication::aboutQt); - - connect(showPasswordButton, &QPushButton::clicked, - this, &PasswordGeneratorApp::onShowPasswordButtonClicked); - - connect(copyToClipBoardButton, &QPushButton::clicked, - this, &PasswordGeneratorApp::copyPasswordToClipboard); - - connect(buttonGeneratePassword, &QPushButton::clicked, - this, &PasswordGeneratorApp::generatePassword); -} - -void PasswordGeneratorApp::createUi() -{ - QGridLayout *const mainGridLayout{ new QGridLayout }; - - std::array horizontalLayout - { - new QHBoxLayout, - new QHBoxLayout, - new QHBoxLayout, - new QHBoxLayout, - new QHBoxLayout, - new QHBoxLayout - }; - - horizontalLayout[0]->addWidget(passwordLineEdit); - horizontalLayout[0]->addWidget(showPasswordButton); - horizontalLayout[0]->addWidget(copyToClipBoardButton); - - horizontalLayout[1]->addWidget(new QLabel{ tr("Password Length") }); - horizontalLayout[1]->addWidget(spinBoxPasswordLength); - - horizontalLayout[2]->addWidget(new QLabel{ tr("Numeric characters") }); - horizontalLayout[2]->addWidget(checkBoxNumeric); - horizontalLayout[2]->addWidget(new QLabel{ tr("Symbols characters") }); - horizontalLayout[2]->addWidget(checkBoxSymbols); - - horizontalLayout[3]->addWidget(new QLabel{ tr("Lowercase letters") }); - horizontalLayout[3]->addWidget(lowercaseCheckBox); - horizontalLayout[3]->addWidget(new QLabel{ tr("Uppercase letters") }); - horizontalLayout[3]->addWidget(upperCaseCheckBox); - - horizontalLayout[4]->addWidget(new QLabel{ tr("Add") }, 0, Qt::AlignCenter); - horizontalLayout[4]->addWidget(new QLabel{ tr("Remove") }, 0, - Qt::AlignCenter); - - horizontalLayout[5]->addWidget(addCharsLineEdit); - horizontalLayout[5]->addWidget(removeCharLineEdit); - - mainGridLayout->addLayout(horizontalLayout[0], 0, 0); - mainGridLayout->addLayout(horizontalLayout[1], 1, 0, Qt::AlignCenter); - mainGridLayout->addLayout(horizontalLayout[2], 2, 0, Qt::AlignCenter); - mainGridLayout->addLayout(horizontalLayout[3], 3, 0, Qt::AlignCenter); - mainGridLayout->addLayout(horizontalLayout[4], 4, 0); - mainGridLayout->addLayout(horizontalLayout[5], 5, 0); - mainGridLayout->addWidget(buttonGeneratePassword, 6, 0); - - QWidget *const mainWidget{ new QWidget }; - mainWidget->setLayout(mainGridLayout); - setCentralWidget(mainWidget); - - statusBar()->showMessage(tr("Version %1").arg(appVersion), 5000); -} - -QStringList PasswordGeneratorApp::availableLanguages() -{ - return QStringList{ "[en] English", "[zh-CN] 简体中文", "[hi] हिंदी", - "[es] Español", "[pt-BR] Português" }; -} - -QStringList PasswordGeneratorApp::languagesStatusTip() -{ - return QStringList{ "Change to English", "更改为简体中文", "हिंदी में बदलें", - "Cambiar a Español", "Mudar para o português"}; -} - -void PasswordGeneratorApp::generatePassword() -{ - const std::array selectedCharacters - { - checkBoxNumeric->isChecked(), - checkBoxSymbols->isChecked(), - lowercaseCheckBox->isChecked(), - upperCaseCheckBox->isChecked() - }; - - bool hasAnyCharactersSelected - { - std::any_of(selectedCharacters.begin(), selectedCharacters.end(), - [](const bool &checkBoxValue) - { - return checkBoxValue; - }) - }, hasAdditionalCharactersToInclude - { !addCharsLineEdit->text().isEmpty() }; - - if (hasAnyCharactersSelected || hasAdditionalCharactersToInclude) { - const static std::array possibleCharacters - { - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - }; - - QString charactersToUse; - for(const QString &characters: possibleCharacters) - charactersToUse.append(characters); - - for(size_t index{0}; index < selectedCharacters.size(); ++index) - if (!selectedCharacters[index]) - charactersToUse.remove(possibleCharacters[index]); - - for(QChar &c: addCharsLineEdit->text()) - if (!charactersToUse.contains(c)) - charactersToUse.append(c); - - for(QChar &c: removeCharLineEdit->text()) - if (charactersToUse.contains(c)) - charactersToUse.remove(c); - - QString password{ spinBoxPasswordLength->value(), ' ' }; - - bool hasCharactersToUse{ !charactersToUse.isEmpty() }; - if (hasCharactersToUse) { - for(QChar &letter: password) - letter = { charactersToUse[QRandomGenerator::global()-> - bounded(0, charactersToUse.size())] }; - passwordLineEdit->setText(password); - return; - } - } - QMessageBox::information(this, tr("Information"), - tr("No characters have been " - "selected for the password. " - "\nPlease select at least one character.")); -} - -void PasswordGeneratorApp::onShowPasswordButtonClicked() -{ - passwordLineEdit->setEchoMode(showPasswordButton->isChecked()? - QLineEdit::Password: QLineEdit::Normal); - showPasswordButton->setToolTip(showPasswordButton->isChecked()? - tr("Show Password"): tr("Hide Password")); -} - -void PasswordGeneratorApp::copyPasswordToClipboard() -{ - QString password{ passwordLineEdit->text() }; - if (!password.isEmpty()) { - if (sender()->objectName() == "cut") - passwordLineEdit->clear(); - QApplication::clipboard()->setText(password); - statusBar()->showMessage(tr("Password copied!"), 3000); - - copyToClipBoardButton->setIcon( - style()->standardIcon(QStyle::SP_DialogApplyButton)); - - QTimer::singleShot(3000, this, [&]() { - copyToClipBoardButton-> - setIcon(QIcon{ ":/icons/icon/clipboard.png" }); - }); - } else - statusBar()->showMessage(tr("The password is empty. " - "Can't copy to clipboard."), 3000); -} - -void PasswordGeneratorApp::changeIcon(QList &list, qsizetype &index, - const qsizetype &newIndex, - const QIcon &icon) -{ - list[index]->setIcon(QIcon{}); - list[newIndex]->setIcon(icon); - index = { newIndex }; -} - -void PasswordGeneratorApp::changeLanguage() -{ - qsizetype languageActionIndex - { languageActionList.indexOf(sender()) }; - - const static qsizetype programLanguage{ currentIndexLanguage }; - - if (programLanguage != languageActionIndex) { - changeIcon(languageActionList, currentIndexLanguage, - languageActionIndex, - style()->standardIcon(QStyle::SP_MessageBoxWarning)); - restart(); - } else changeIcon(languageActionList, currentIndexLanguage, - languageActionIndex, - style()->standardIcon(QStyle::SP_DialogApplyButton)); -} - -void PasswordGeneratorApp::restart() -{ - QMessageBox question{ this }; - question.setWindowTitle(tr("Restart Required")); - question.setText(tr("You will need to restart in order to" - " use your new language setting\n" - "Your password will be lost if you do not " - "save it before restarting.")); - question.addButton(tr("Restart Now"), QMessageBox::YesRole); - question.buttons().at(0)-> - setIcon(style()->standardIcon(QStyle::SP_BrowserReload)); - question.addButton(tr("Restart Later"), QMessageBox::NoRole); - question.buttons().at(1)-> - setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton)); - bool isRestartNow{ !question.exec() }; - if (isRestartNow) { - QProcess process; - const QString program{ qApp->arguments()[0] }, - workingDirectory{ qApp->applicationDirPath() }; - QStringList arguments{ qApp->arguments() }; - arguments.removeAt(0); - bool processHasError - { !process.startDetached(program, arguments, workingDirectory) }; - if (processHasError) { - QProcess::ProcessError error{ process.error() }; - QMessageBox errorBox{ this }; - errorBox.setWindowTitle(tr("Error")); - errorBox.setText(tr("Error: \"enum QProcess::ProcessError\"\n" - "Value error: %1\n" - "The program can still be used\n" - "but cannot be restarted due to an error.\n\n" - "Do you want copy this error " - "in your clipboad?").arg(error)); - errorBox.addButton(tr("Copy to clipboard"), QMessageBox::YesRole); - errorBox.buttons().at(0)-> - setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton)); - errorBox.addButton(tr("No"), QMessageBox::NoRole); - errorBox.buttons().at(1)-> - setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton)); - bool userDecisionIsYes{ !errorBox.exec() }; - - if (userDecisionIsYes) - QApplication::clipboard()-> - setText(QString("enum QProcess::ProcessError: %1") - .arg(error)); - } else close(); - } -} - -void PasswordGeneratorApp::closeEvent(QCloseEvent *const event) -{ - saveSettings(); - if (myTrayIcon->isSystemTrayAvailable()) { - if (!event->spontaneous()) - QApplication::postEvent(qApp, new QEvent(QEvent::Quit)); - else { - hide(); - event->ignore(); - } - } - else event->accept(); -} - -void PasswordGeneratorApp::changeEvent(QEvent *const event) -{ - if (event->type() == QEvent::StyleChange) - changePalette(); -} - -void PasswordGeneratorApp::saveSettings() -{ - userSettings->setValue("Settings/IndexLanguage", currentIndexLanguage); - userSettings->setValue("Settings/IndexTheme", currentIndexTheme); - userSettings->setValue("Settings/ShowPassword", - showPasswordButton->isChecked()); - userSettings->setValue("Settings/Length", spinBoxPasswordLength->value()); - userSettings->setValue("Settings/Numeric", checkBoxNumeric->isChecked()); - userSettings->setValue("Settings/Symbols", checkBoxSymbols->isChecked()); - userSettings->setValue("Settings/lowercase", - lowercaseCheckBox->isChecked()); - userSettings->setValue("Settings/UpperCase", - upperCaseCheckBox->isChecked()); - userSettings->setValue("Settings/Add", addCharsLineEdit->text()); - userSettings->setValue("Settings/Remove", removeCharLineEdit->text()); -} - -void PasswordGeneratorApp::changeStyle() -{ - const QAction *const selectedAction{ qobject_cast(sender()) }; - qApp->setStyle(QStyleFactory::create(selectedAction->text())); - changeIcon(themeActionList, currentIndexTheme, themeActionList. - indexOf(selectedAction), - style()->standardIcon(QStyle::SP_DialogApplyButton)); -} - -void PasswordGeneratorApp::changePalette() -{ - qApp->setPalette(useStylePaletteAction->isChecked() ? - qApp->style()->standardPalette() : QPalette{}); -} - -void PasswordGeneratorApp::about() -{ - const static QString description - { - tr("
" - "

%1

\n" - "

Version: %2

\n" - "

GenPassword is a free password generator that helps you" - " create random and customizable passwords. " - "The program adds or removes characters in the " - "following order:\n

\n" - "
    " - "
  1. Numbers, Symbols, Lowercase letters, " - "Uppercase letters
  2. \n" - "
  3. Adds the letters that the user has specified
  4. \n" - "
  5. Removes the letters that the user has specified
  6. \n" - "
" - "

For issues or contributions, visit " - "the GitHub repository" - "

\n" - "

Copyright © 2023 - CM0use

\n" - "

This program comes with NO WARRANTY OF ANY KIND.
\n" - "See the GNU General Public License " - "for details.

" - "
").arg(appName, appVersion) - }; - - QMessageBox::about(this, tr("About %1").arg(appName), description); -} - -void PasswordGeneratorApp::credits() -{ - const static QString description - { - tr("
" - "

%1

\n" - "

Created by CM0use

\n" - "

Contributors:

\n" - "" - "

Inspired by design: " - "Locksmith

" - "
").arg(appName) - }; - - QMessageBox::about(this, tr("Credits"), description); -} diff --git a/src/passwordgeneratorapp.h b/src/passwordgeneratorapp.h deleted file mode 100644 index e0da282..0000000 --- a/src/passwordgeneratorapp.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - ** This file is part of the GenPassword project. - ** Copyright 2023 CM0use dilanuzcs@gmail.com - ** URL: https://github.com/CM0use/GenPassword - ** - ** This program is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** 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 General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with this program. If not, see . - **/ - -#ifndef PASSWORDGENERATORAPP_H -#define PASSWORDGENERATORAPP_H - -#include -#include - -#define APPICON QIcon{ ":/icons/icon/appIcon.png" } - -QT_BEGIN_NAMESPACE -class QSettings; -class QLineEdit; -class QPushButton; -class QSpinBox; -class QCheckBox; -QT_END_NAMESPACE - -class PasswordGeneratorApp final: public QMainWindow -{ - Q_OBJECT -public: - explicit PasswordGeneratorApp(QWidget *const parent = nullptr); - virtual ~PasswordGeneratorApp() = default; - -protected: - virtual void closeEvent(QCloseEvent *const event) override; - virtual void changeEvent(QEvent *const event) override; - -private: - void createActions(); - void configurateActions(); - void createMenus(); - void configurateMenus(); - void createWidgets(); - void configureWidgets(); - void createTrayIcon(); - void configurateTrayIcon(); - void iconActivated(QSystemTrayIcon::ActivationReason reason); - void connectSignals(); - void createUi(); - - QStringList languagesStatusTip(); - QStringList availableLanguages(); - - void generatePassword(); - void onShowPasswordButtonClicked(); - void copyPasswordToClipboard(); - - void changeIcon(QList &list, qsizetype &index, - const qsizetype &newIndex, const QIcon &icon); - void changeLanguage(); - void restart(); - void saveSettings(); - void changeStyle(); - void changePalette(); - - void about(); - void credits(); - - QSettings *const userSettings; - qsizetype currentIndexLanguage, currentIndexTheme; - const QString appVersion, appName; - QAction *exitAction, - *generatePasswordAction, *cutPasswordAction, *copyPasswordAction, - *useStylePaletteAction, - *aboutAction, *creditsAction, *aboutQtAction; - QList languageActionList, themeActionList; - QMenu *fileMenu, - *editMenu, *languagesMenu, - *viewMenu, *themesMenu, - *helpMenu, - *myTrayIconMenu; - QSystemTrayIcon *myTrayIcon; - QLineEdit *passwordLineEdit, - *addCharsLineEdit, *removeCharLineEdit; - QPushButton *showPasswordButton, *copyToClipBoardButton, - *buttonGeneratePassword; - QSpinBox *spinBoxPasswordLength; - QCheckBox *checkBoxNumeric, *checkBoxSymbols, - *lowercaseCheckBox, *upperCaseCheckBox; -}; - -#endif // PASSWORDGENERATORAPP_H diff --git a/src/qss.qrc b/src/qss.qrc index 735450f..1db5294 100644 --- a/src/qss.qrc +++ b/src/qss.qrc @@ -1,5 +1,6 @@ - - qss/stylesheet.qss + + qss/dark.css + qss/light.css diff --git a/src/qss/dark.css b/src/qss/dark.css new file mode 100644 index 0000000..244112c --- /dev/null +++ b/src/qss/dark.css @@ -0,0 +1,33 @@ +QWidget { + background-color: #292A2D; + color: #E8EAED; + selection-background-color: green; + selection-color: white; +} + +QMenu::item:selected { + background-color: #8AB4F8; + color: #202124; +} + +QLineEdit { + background-color: #202124; + padding: 9px 9px 9px 9px; + border-radius: 13px 13px 13px 13px; +} + +QSlider::handle:horizontal { + background-color: white; + border-radius: 7px; +} + +QSpinBox { + background-color: #202124; +} + +QToolTip { + background-color: #202124; + color: #E8EAED; + border: 1px solid white; + padding: 5px; +} diff --git a/src/qss/light.css b/src/qss/light.css new file mode 100644 index 0000000..adf7346 --- /dev/null +++ b/src/qss/light.css @@ -0,0 +1,33 @@ +QWidget { + background-color: white; + color: #202124; + selection-background-color: green; + selection-color: white; +} + +QMenu::item:selected { + background-color: #E8F0FE; + color: #1967D2; +} + +QLineEdit { + background-color: #F1F3F4; + padding: 9px 9px 9px 9px; + border-radius: 13px 13px 13px 13px; +} + +QSlider::handle:horizontal { + background-color: green; + border-radius: 7px; +} + +QSpinBox { + background-color: #F1F3F4; +} + +QToolTip { + background-color: white; + color: #202124; + border: 1px solid black; + padding: 5px; +} diff --git a/src/qss/stylesheet.qss b/src/qss/stylesheet.qss deleted file mode 100644 index 4617df1..0000000 --- a/src/qss/stylesheet.qss +++ /dev/null @@ -1,38 +0,0 @@ -/** - ** This file is part of the GenPassword project. - ** Copyright 2023 CM0use dilanuzcs@gmail.com - ** URL: https://github.com/CM0use/GenPassword - ** - ** This program is free software: you can redistribute it and/or modify - ** it under the terms of the GNU General Public License as published by - ** the Free Software Foundation, either version 3 of the License, or - ** (at your option) any later version. - ** - ** 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 General Public License for more details. - ** - ** You should have received a copy of the GNU General Public License - ** along with this program. If not, see . - **/ - -/*-----QCheckBox-----*/ -QCheckBox::indicator -{ - width: 45px; - height: 45px; - -} - -QCheckBox::indicator:checked -{ - image: url(:/icons/icon/toggleon.png); - -} - -QCheckBox::indicator:unchecked -{ - image: url(:/icons/icon/toggleoff.png); - -} diff --git a/src/switchbutton.cpp b/src/switchbutton.cpp new file mode 100644 index 0000000..0417f08 --- /dev/null +++ b/src/switchbutton.cpp @@ -0,0 +1,215 @@ +// SwitchButton +// Copyright (c) 2023 CM0use +// URL: https://github.com/CM0use/SwitchButton + +#include "switchbutton.h" + +#include +#include + +QPixmap drawShadowEllipse(const qreal &radius, const qreal &elevation, const QColor &color) +{ + QPixmap px{ qRound(radius * 2), qRound(radius * 2) }; + px.fill(Qt::transparent); + + QPainter p{ &px }; + + p.setBrush(color); + p.setPen(Qt::NoPen); + p.setRenderHint(QPainter::Antialiasing); + p.drawEllipse(QRectF(0, 0, px.size().width(), px.size().height()).center(), + radius - elevation, + radius - elevation); + p.end(); + + QImage tmp{ px.size(), QImage::Format_ARGB32_Premultiplied }; + tmp.setDevicePixelRatio(px.devicePixelRatioF()); + tmp.fill(0); + QImage blurred{ tmp }; + p.begin(&tmp); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawPixmap(QPointF(), px); + p.end(); + + p.begin(&blurred); + qt_blurImage(&p, tmp, elevation * 4, true, false); + p.end(); + + return QPixmap::fromImage(blurred); +} + +SwitchButton::SwitchButton(QWidget *const parent) + : QAbstractButton{ parent }, + CORNER_RADIUS{ 8.0 }, THUMB_RADIUS{ 14.5 }, SHADOW_ELEVATION{ 2.0 }, + height{ 36 }, indicatorMargin { 8, 8, 8, 8 }, + + trackDisabledColor{ Qt::black }, thumbDisabledColor{ Qt::gray }, + trackDisabledOpacity{ 0.25 }, disabledTextOpacity { 0.25 }, + + thumbPosAnimation{ new QPropertyAnimation(this, "thumbPosition", this) }, + _thumbPosition{ isChecked()? (indicatorMargin.left() + indicatorMargin.right() + 2): 0 }, + shadowPixmap{ drawShadowEllipse(THUMB_RADIUS, SHADOW_ELEVATION, QColor(0, 0, 0, 70)) } +{ + setCursor(Qt::PointingHandCursor); + setCheckable(true); + + thumbPosAnimation->setDuration(150); + thumbPosAnimation->setEasingCurve(QEasingCurve::OutQuad); +} + +SwitchButton::SwitchButton(const QString &text, QWidget *const parent) + : SwitchButton{ parent } +{ + setText(text); +} + +SwitchButton::SwitchButton(const QString &text, bool isThemeDark, QWidget *const parent) + : SwitchButton{ text, parent } +{ + if (isThemeDark) + setThemeDark(); + else setThemeLight(); +} + +void SwitchButton::setThemeLight() +{ + setTrackColor(TRACK_ON_COLOR_LIGHT, TRACK_OFF_COLOR_LIGHT); + setThumbColor(THUMB_ON_COLOR_LIGHT, THUMB_OFF_COLOR_LIGHT); +} + +void SwitchButton::setThemeDark() +{ + setTrackColor(TRACK_ON_COLOR_DARK, TRACK_OFF_COLOR_DARK); + setThumbColor(THUMB_ON_COLOR_DARK, THUMB_OFF_COLOR_DARK); +} + +void SwitchButton::setTrackColor(const QColor &trackOnColor, const QColor &trackOffColor) +{ + this->trackOnColor = trackOnColor; + this->trackOffColor = trackOffColor; +} + +void SwitchButton::setThumbColor(const QColor &thumbOnColor, const QColor &thumbOffColor) +{ + this->thumbOnColor = thumbOnColor; + this->thumbOffColor = thumbOffColor; +} + +QSize SwitchButton::sizeHint() const +{ + auto w{ indicatorMargin.left() + + height + + indicatorMargin.right() + + fontMetrics().horizontalAdvance(text()) }; + + return QSize{ w, height }; +} + +QRect SwitchButton::indicatorRect() +{ + const auto w{ indicatorMargin.left() + + height + + indicatorMargin.right() }; + + return isLeftToRight()? QRect(0, 0, w, height): QRect(width() - w, 0, w, height); +} + +QRect SwitchButton::textRect() +{ + const auto w{ indicatorMargin.left() + + height + + indicatorMargin.right() }; + + return isLeftToRight()? + rect().marginsRemoved(QMargins(w, 0, 0, 0)): + rect().marginsRemoved(QMargins(0, 0, w, 0)); +} + +void SwitchButton::paintEvent(QPaintEvent *const) +{ + QPainter p{ this }; + p.setPen(Qt::NoPen); + p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); + + QMargins trackMargin{ indicatorMargin }; + trackMargin.setTop(trackMargin.top() + 2); + trackMargin.setBottom(trackMargin.bottom() + 2); + + QRectF trackRect{ indicatorRect().marginsRemoved(trackMargin) }; + + if (isEnabled()) { + /* DRAW TRACK */ + p.setBrush(isChecked()? trackOnColor: trackOffColor); + p.drawRoundedRect(trackRect, CORNER_RADIUS, CORNER_RADIUS); + + /* DRAW THUMB */ + trackRect.setX(trackRect.x() - trackMargin.left() - trackMargin.right() - 2 + + thumbPosAnimation->currentValue().toInt()); + if (!shadowPixmap.isNull()) + p.drawPixmap(trackRect.center() - QPointF(THUMB_RADIUS, THUMB_RADIUS - 1.0), shadowPixmap); + p.setBrush(isChecked()? thumbOnColor: thumbOffColor); + p.drawEllipse(trackRect.center(), THUMB_RADIUS - SHADOW_ELEVATION - 1.0, THUMB_RADIUS - SHADOW_ELEVATION - 1.0); + + /* DRAW TEXT */ + if (!text().isEmpty()) { + p.setPen(palette().color(QPalette::Active, QPalette::ButtonText)); + p.drawText(textRect(), Qt::AlignLeft | Qt::AlignVCenter, text()); + } + } else { + /* DRAW TRACK */ + p.setBrush(trackDisabledColor); + p.setOpacity(trackDisabledOpacity); + p.drawRoundedRect(trackRect, CORNER_RADIUS, CORNER_RADIUS); + + /* DRAW THUMB */ + p.setOpacity(1.0); + if (isChecked()) + trackRect.setX(trackRect.x() + trackMargin.left() + trackMargin.right() + 2); + else trackRect.setX(trackRect.x() - trackMargin.left() - trackMargin.right() - 2); + if (!shadowPixmap.isNull()) + p.drawPixmap(trackRect.center() - QPointF(THUMB_RADIUS, THUMB_RADIUS - 1.0), shadowPixmap); + p.setBrush(thumbDisabledColor); + p.drawEllipse(trackRect.center(), THUMB_RADIUS - SHADOW_ELEVATION - 1.0, THUMB_RADIUS - SHADOW_ELEVATION - 1.0); + + /* DRAW TEXT */ + if (!text().isEmpty()) { + p.setOpacity(disabledTextOpacity); + p.setPen(palette().color(QPalette::Disabled, QPalette::ButtonText)); + p.drawText(textRect(), Qt::AlignLeft | Qt::AlignVCenter, text()); + } + } +} + +void SwitchButton::nextCheckState() +{ + QAbstractButton::nextCheckState(); + checkStateSet(); +} + +void SwitchButton::checkStateSet() +{ + const Qt::CheckState state{ isChecked()? Qt::Checked: Qt::Unchecked }; + toggle(state); + emit stateChanged(state); +} + +void SwitchButton::toggle(const Qt::CheckState &state) +{ + thumbPosAnimation->stop(); + if (state == Qt::Unchecked) + thumbPosAnimation->setEndValue(0); + else thumbPosAnimation->setEndValue((indicatorMargin.left() + indicatorMargin.right() + 2) * 2); + thumbPosAnimation->start(); +} + +void SwitchButton::setThumbPosition(const int &thumbPosition) +{ + this->_thumbPosition = thumbPosition; + update(); + emit thumbPositionChanged(); +} + +int SwitchButton::thumbPosition() +{ + return _thumbPosition; +} diff --git a/src/switchbutton.h b/src/switchbutton.h new file mode 100644 index 0000000..cf68d6b --- /dev/null +++ b/src/switchbutton.h @@ -0,0 +1,77 @@ +// SwitchButton +// Copyright (c) 2023 CM0use +// URL: https://github.com/CM0use/SwitchButton + +#ifndef SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include + +#define TRACK_OFF_COLOR_DARK (QColor(154, 160, 166)) +#define THUMB_OFF_COLOR_DARK (QColor(218, 220, 224)) +#define TRACK_ON_COLOR_DARK (QColor(138, 180, 248, 128)) +#define THUMB_ON_COLOR_DARK (QColor(138, 180, 255, 255)) + +#define TRACK_OFF_COLOR_LIGHT (QColor(189, 193, 198)) +#define THUMB_OFF_COLOR_LIGHT (QColor(255, 255, 255)) +#define TRACK_ON_COLOR_LIGHT (QColor(26, 115, 232, 128)) +#define THUMB_ON_COLOR_LIGHT (QColor(26, 115, 232, 255)) + +QT_BEGIN_NAMESPACE +class QPropertyAnimation; +extern Q_DECL_IMPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); +QT_END_NAMESPACE + +QPixmap drawShadowEllipse(const qreal &radius, const qreal &elevation, const QColor &color); + +class SwitchButton final: public QAbstractButton +{ + Q_OBJECT + Q_PROPERTY(int thumbPosition READ thumbPosition WRITE setThumbPosition NOTIFY thumbPositionChanged FINAL) +public: + explicit SwitchButton(QWidget *const parent = nullptr); + explicit SwitchButton(const QString &text, QWidget *const parent = nullptr); + explicit SwitchButton(const QString &text, bool isThemeDark, QWidget *const parent = nullptr); + virtual ~SwitchButton() = default; + + void setThemeLight(); + void setThemeDark(); + + void setTrackColor(const QColor &trackOnColor, const QColor &trackOffColor); + void setThumbColor(const QColor &thumbOnColor, const QColor &thumbOffColor); + + virtual QSize sizeHint() const override; + +signals: + void stateChanged(int); + void thumbPositionChanged(); + +protected: + QRect indicatorRect(); + QRect textRect(); + + virtual void paintEvent(QPaintEvent *const) override; + virtual void nextCheckState() override; + virtual void checkStateSet() override; + + void toggle(const Qt::CheckState &state); + +private: + void setThumbPosition(const int &thumbPosition); + int thumbPosition(); + + const qreal CORNER_RADIUS, THUMB_RADIUS, SHADOW_ELEVATION; + int height; + QMargins indicatorMargin; + + QColor trackOnColor, trackOffColor, + thumbOnColor, thumbOffColor, + trackDisabledColor, thumbDisabledColor; + qreal trackDisabledOpacity, disabledTextOpacity; + + QPropertyAnimation *const thumbPosAnimation; + int _thumbPosition; + QPixmap shadowPixmap; +}; + +#endif // SWITCHBUTTON_H diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..16dcda3 --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,463 @@ +// GenPassword +// Copyright (c) 2023 CM0use + +#include "window.h" +#include "icons.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Window::Window(QWidget *const parent) + : FramelessWindow{ parent }, + appName{ qApp->applicationName() }, + appVersion{ qApp->applicationVersion() } +{ + initializeMembers(); + + createTitleBar(); + createMenus(); + createActions(); + configurateActions(); + configurateMenus(); + configurateTitleBar(); + + if (QSystemTrayIcon::isSystemTrayAvailable()) { + createTrayIcon(); + configurateTrayIcon(); + } + + updateIcons(); + connectSignals(); +} + +void Window::closeEvent(QCloseEvent *const event) +{ + saveSettings(); + if (QSystemTrayIcon::isSystemTrayAvailable()) { + if (!event->spontaneous() && !sender()->isWidgetType()) + QApplication::postEvent(qApp, new QEvent(QEvent::Quit)); + else { + hide(); + event->ignore(); + } + } else event->accept(); +} + +qsizetype Window::getCurrentIndexTheme() +{ + return currentIndexTheme; +} + +void Window::updateIcons() +{ + if (currentIndexTheme) { + popUpButton->setIcon(MENU_ICON_LIGHT); + + languagesMenu->setIcon(TRANSLATE_ICON_LIGHT); + languageActionList[currentIndexLanguage]->setIcon(CHECK_ICON_LIGHT); + + themesMenu->setIcon(PALETTE_ICON_LIGHT); + themeActionList[currentIndexTheme]->setIcon(CHECK_ICON_LIGHT); + + shortCutsMenu->setIcon(SHORTCUT_ICON_LIGHT); + generatePasswordAction->setIcon(REFRESH_ICON_LIGHT); + cutPasswordAction->setIcon(CUT_ICON_LIGHT); + copyPasswordAction->setIcon(COPY_ICON_LIGHT); + + customTitleBarAction->setIcon(customTitleBarAction->isChecked()? DONE_ICON_LIGHT: QIcon()); + + helpMenu->setIcon(HELP_ICON_LIGHT); + aboutAction->setIcon(INFO_ICON_LIGHT); + creditsAction->setIcon(COPYRIGHT_ICON_LIGHT); + + exitAction->setIcon(EXIT_ICON_LIGHT); + + appIcon->setPixmap(APP_ICON_LIGHT.pixmap(35)); + + minimizeButton->setIcon(MINIMIZE_ICON_LIGHT); + closeButton->setIcon(CLOSE_ICON_LIGHT); + + if(QSystemTrayIcon::isSystemTrayAvailable()) { + showProgramAction->setIcon(APP_ICON_LIGHT); + newAndCopyPassowrdAction->setIcon(REFRESH_ICON_LIGHT); + } + } else { + popUpButton->setIcon(MENU_ICON_DARK); + + languagesMenu->setIcon(TRANSLATE_ICON_DARK); + languageActionList[currentIndexLanguage]->setIcon(CHECK_ICON_DARK); + + themesMenu->setIcon(PALETTE_ICON_DARK); + themeActionList[currentIndexTheme]->setIcon(CHECK_ICON_DARK); + + shortCutsMenu->setIcon(SHORTCUT_ICON_DARK); + generatePasswordAction->setIcon(REFRESH_ICON_DARK); + cutPasswordAction->setIcon(CUT_ICON_DARK); + copyPasswordAction->setIcon(COPY_ICON_DARK); + + customTitleBarAction->setIcon(customTitleBarAction->isChecked()? DONE_ICON_DARK: QIcon()); + + helpMenu->setIcon(HELP_ICON_DARK); + aboutAction->setIcon(INFO_ICON_DARK); + creditsAction->setIcon(COPYRIGHT_ICON_DARK); + + exitAction->setIcon(EXIT_ICON_DARK); + + appIcon->setPixmap(APP_ICON_DARK.pixmap(35)); + + minimizeButton->setIcon(MINIMIZE_ICON_DARK); + closeButton->setIcon(CLOSE_ICON_DARK); + + if(QSystemTrayIcon::isSystemTrayAvailable()) { + showProgramAction->setIcon(APP_ICON_DARK); + newAndCopyPassowrdAction->setIcon(REFRESH_ICON_DARK); + } + } +} + +void Window::initializeMembers() +{ + userSettings = new QSettings(QCoreApplication::applicationDirPath() + + "/config/Settings.ini", + QSettings::Format::IniFormat); + + currentIndexLanguage = userSettings->value("Settings/IndexLanguage").toInt(); + currentIndexTheme = userSettings->value("Settings/IndexTheme").toInt(); +} + +void Window::createTitleBar() +{ + titleBar = new QWidget(this); + + popUpButton = new QToolButton(titleBar), + appMenu = new QMenu(popUpButton); + + appIcon = new QLabel(titleBar); + appTitleName = new QLabel( appName, titleBar); + + minimizeButton = new QToolButton(titleBar); + closeButton = new QToolButton(titleBar); +} + +void Window::createMenus() +{ + languagesMenu = new QMenu(tr("&Languages"), appMenu); + themesMenu = new QMenu(tr("&Themes"), appMenu); + shortCutsMenu = new QMenu(tr("&Shortcuts"), appMenu); + helpMenu = new QMenu(tr("&Help"), appMenu); +} + +void Window::createActions() +{ + languageActionList ={ new QAction(tr("[en] English"), languagesMenu), + new QAction(tr("[es] Español"), languagesMenu) }; + + themeActionList ={ new QAction(tr("Light"), themesMenu), + new QAction(tr("Dark"), themesMenu) }; + + generatePasswordAction = new QAction(shortCutsMenu); + cutPasswordAction = new QAction(shortCutsMenu); + copyPasswordAction = new QAction(shortCutsMenu); + + customTitleBarAction = new QAction(tr("&Custom Title Bar"), appMenu); + + aboutAction = new QAction(tr("&About %1").arg(appName), helpMenu); + creditsAction = new QAction(tr("&Credits"), helpMenu); + aboutQtAction = new QAction(tr("About &Qt"), helpMenu); + + exitAction = new QAction(tr("E&xit"), appMenu); +} + +void Window::configurateActions() +{ + themeActionList[0]->setObjectName("light.css"); + themeActionList[1]->setObjectName("dark.css"); + + generatePasswordAction->setText(tr("&Generate Password")); + generatePasswordAction->setShortcut(QKeySequence::New); + + cutPasswordAction->setText(tr("Cut Password")); + cutPasswordAction->setObjectName("cut"); + cutPasswordAction->setShortcut(QKeySequence::Cut); + + copyPasswordAction->setText(tr("&Copy Password")); + copyPasswordAction->setShortcut(QKeySequence::Copy); + + customTitleBarAction->setCheckable(true); + customTitleBarAction->setChecked(true); + + aboutQtAction->setIcon(QT_ICON); + + exitAction->setShortcut(QKeySequence::Quit); +} + +void Window::configurateMenus() +{ + languagesMenu->addActions(languageActionList); + + themesMenu->addActions(themeActionList); + + shortCutsMenu->addAction(generatePasswordAction); + shortCutsMenu->addAction(cutPasswordAction); + shortCutsMenu->addAction(copyPasswordAction); + + helpMenu->addAction(aboutAction); + helpMenu->addAction(creditsAction); + helpMenu->addAction(aboutQtAction); +} + +void Window::configurateTitleBar() +{ + popUpButton->setPopupMode(QToolButton::InstantPopup); + popUpButton->setAutoRaise(true); + popUpButton->setMenu(appMenu); + + appMenu->addMenu(languagesMenu); + appMenu->addMenu(themesMenu); + appMenu->addMenu(shortCutsMenu); + appMenu->addAction(customTitleBarAction); + appMenu->addMenu(helpMenu); + appMenu->addSeparator(); + appMenu->addAction(exitAction); + + QHBoxLayout *const hLayoutBar{ new QHBoxLayout }; + hLayoutBar->setContentsMargins(0, 0, 0, 0); + + hLayoutBar->addWidget(popUpButton); + hLayoutBar->addStretch(); + hLayoutBar->addWidget(appIcon); + hLayoutBar->addWidget(appTitleName); + hLayoutBar->addStretch(); + + minimizeButton->setAutoRaise(true); + closeButton->setAutoRaise(true); + + QHBoxLayout *const buttonsHLayout{ new QHBoxLayout }; + buttonsHLayout->setContentsMargins(0, 0, 0, 0); + buttonsHLayout->setSpacing(0); + buttonsHLayout->addWidget(minimizeButton); + buttonsHLayout->addWidget(closeButton); + + hLayoutBar->addLayout(buttonsHLayout); + + titleBar->setLayout(hLayoutBar); + setTitleBar(titleBar); +} + +void Window::createTrayIcon() +{ + myTrayIcon = new QSystemTrayIcon(APP_ICON_LIGHT, this); + myTrayIconMenu = new QMenu(this); + showProgramAction = new QAction(tr("Show %1").arg(appName), myTrayIcon); + newAndCopyPassowrdAction = new QAction(tr("New+Copy Password"), myTrayIcon); +} + +void Window::configurateTrayIcon() +{ + myTrayIconMenu->addAction(showProgramAction); + myTrayIconMenu->addSeparator(); + myTrayIconMenu->addAction(newAndCopyPassowrdAction); + myTrayIconMenu->addSeparator(); + myTrayIconMenu->addAction(exitAction); + + myTrayIcon->setContextMenu(myTrayIconMenu); + myTrayIcon->show(); + myTrayIcon->setToolTip(appName); + + connect(myTrayIcon, &QSystemTrayIcon::activated, this, &Window::iconActivated); + connect(showProgramAction, &QAction::triggered, this, [this] { + if (!isActiveWindow() || isHidden() || isMinimized()) { + activateWindow(); + showNormal(); + } + }); + connect(newAndCopyPassowrdAction, &QAction::triggered, this, [this] { emit newAndCopyPassowrdSignal(); }); +} + +void Window::iconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if (reason == QSystemTrayIcon::Trigger) { + if (!isActiveWindow() || isHidden() || isMinimized()) { + activateWindow(); + showNormal(); + } + } +} + +void Window::connectSignals() +{ + for(const QAction *const languageAction: languageActionList) + connect(languageAction, &QAction::triggered, this, &Window::changeLanguage); + + for(const QAction *const themeAction: themeActionList) + connect(themeAction, &QAction::triggered, this, &Window::changeTheme); + + connect(generatePasswordAction, &QAction::triggered, this, [this] { emit newPasswordSignal(); }); + connect(cutPasswordAction, &QAction::triggered, this, [this] { emit cutPasswordSignal(true); }); + connect(copyPasswordAction, &QAction::triggered, this, [this] { emit cutPasswordSignal(false); }); + + connect(customTitleBarAction, &QAction::triggered, this, [this] (bool checked) { + setWindowFlag(Qt::FramelessWindowHint, checked); + setWindowFlag(Qt::WindowMaximizeButtonHint, checked); + + setTitleBar(checked? titleBar: nullptr); + appIcon->setVisible(checked); + appTitleName->setVisible(checked); + minimizeButton->setVisible(checked); + closeButton->setVisible(checked); + customTitleBarAction->setIcon(checked? currentIndexTheme? DONE_ICON_LIGHT: DONE_ICON_DARK + : QIcon()); + + showNormal(); + }); + + connect(aboutAction, &QAction::triggered, this, &Window::about); + connect(creditsAction, &QAction::triggered, this, &Window::credits); + connect(aboutQtAction, &QAction::triggered, qApp, &QApplication::aboutQt); + + connect(exitAction, &QAction::triggered, this, &Window::close); + + connect(minimizeButton, &QToolButton::clicked, + this, [this] { setWindowState(Qt::WindowMinimized); }); + connect(closeButton, &QToolButton::clicked, this, &Window::close); +} + +void Window::changeLanguage() +{ + const qsizetype senderLanguageIndex{ languageActionList.indexOf(static_cast(sender())) }; + + const static qsizetype programLanguage{ currentIndexLanguage }; + + if (programLanguage != senderLanguageIndex) { + languageActionList[currentIndexLanguage]->setIcon(QIcon()); + languageActionList[senderLanguageIndex] + ->setIcon(currentIndexTheme? WARNING_ICON_LIGHT: WARNING_ICON_DARK); + currentIndexLanguage = senderLanguageIndex; + restart(); + } else { + languageActionList[currentIndexLanguage]->setIcon(QIcon()); + languageActionList[senderLanguageIndex] + ->setIcon(currentIndexTheme? CHECK_ICON_LIGHT: CHECK_ICON_DARK); + currentIndexLanguage = senderLanguageIndex; + } +} + +void Window::restart() +{ + QMessageBox question{ this }; + question.setWindowTitle(tr("Restart Required")); + question.setText(tr("You will need to restart in order to" + " use your new language setting\n" + "Your password will be lost if you do not " + "save it before restarting.")); + question.addButton(tr("Restart Now"), QMessageBox::YesRole); + question.buttons().at(0)->setIcon(currentIndexTheme? REFRESH_ICON_LIGHT: REFRESH_ICON_DARK); + question.addButton(tr("Restart Later"), QMessageBox::NoRole); + question.buttons().at(1)->setIcon(currentIndexTheme? OFF_ICON_LIGHT: OFF_ICON_DARK); + const bool isRestartNow{ !question.exec() }; + if (isRestartNow) { + const QProcess process; + const QString program{ qApp->arguments()[0] }, + workingDirectory{ qApp->applicationDirPath() }; + QStringList arguments{ qApp->arguments() }; + arguments.removeAt(0); + const bool processHasError{ !process.startDetached(program, arguments, workingDirectory) }; + if (processHasError) { + const QProcess::ProcessError error{ process.error() }; + QMessageBox errorBox{ this }; + errorBox.setWindowTitle(tr("Error")); + errorBox.setText(tr("Error: \"enum QProcess::ProcessError\"\n" + "Value error: %1\n" + "The program can still be used\n" + "but cannot be restarted due to an error.\n\n" + "Do you want copy this error " + "in your clipboad?").arg(error)); + errorBox.addButton(tr("Copy to clipboard"), QMessageBox::YesRole); + errorBox.buttons().at(0)->setIcon(currentIndexTheme? COPY_ICON_LIGHT: COPY_ICON_DARK); + errorBox.addButton(tr("No"), QMessageBox::NoRole); + errorBox.buttons().at(1)->setIcon(currentIndexTheme? OFF_ICON_LIGHT: OFF_ICON_DARK); + bool userDecisionIsYes{ !errorBox.exec() }; + + if (userDecisionIsYes) + QApplication::clipboard()-> + setText(QString("enum QProcess::ProcessError: %1").arg(error)); + } else close(); + } +} + +void Window::saveSettings() +{ + userSettings->setValue("Settings/IndexLanguage", currentIndexLanguage); + userSettings->setValue("Settings/IndexTheme", currentIndexTheme); + emit saveSettingsSignal(); +} + +void Window::changeTheme() +{ + const qsizetype senderThemeIndex{ themeActionList.indexOf(static_cast(sender())) }; + if (senderThemeIndex != currentIndexTheme) { + QFile styleSheetFile{ ":/qss/" + themeActionList[senderThemeIndex]->objectName() }; + styleSheetFile.open(QFile::ReadOnly); + qApp->setStyleSheet(styleSheetFile.readAll()); + themeActionList[currentIndexTheme]->setIcon(QIcon()); + themeActionList[senderThemeIndex]->setIcon(currentIndexTheme? CHECK_ICON_LIGHT: CHECK_ICON_DARK); + currentIndexTheme = senderThemeIndex; + + emit themeChanged(true); + } +} + +void Window::about() +{ + const static QString description + { tr("
" + "

%1

" + "

Version: %2

" + "

%1 is a free password generator that helps you" + " create random and customizable passwords. " + "The program adds or removes characters in the " + "following order:

" + "
    " + "
  1. Numbers, Symbols, Lowercase letters, Uppercase letters
  2. " + "
  3. Adds the letters that the user has specified
  4. " + "
  5. Removes the letters that the user has specified
  6. " + "
" + "

For issues or contributions, visit the " + "" + "GitHub repository

" + "

Copyright © 2023 - CM0use

" + "

This program comes with NO WARRANTY OF ANY KIND.
" + "See the " + "GNU General Public License for details.

" + "
").arg(appName, appVersion) + }; + QMessageBox::about(this, tr("About %1").arg(appName), description); +} + +void Window::credits() +{ + const static QString description + { tr("
" + "

%1

" + "

Created by CM0use

" + "

Contributors:

" + "" + "

Inspired by design: " + "Locksmith

" + "
").arg(appName) + }; + QMessageBox::about(this, tr("Credits"), description); +} diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..af1dc53 --- /dev/null +++ b/src/window.h @@ -0,0 +1,88 @@ +// GenPassword +// Copyright (c) 2023 CM0use + +#ifndef WINDOW_H +#define WINDOW_H + +#include "framelesswindow.h" + +#include + +QT_BEGIN_NAMESPACE +class QSettings; +class QToolButton; +class QLabel; +QT_END_NAMESPACE + +class Window: public FramelessWindow +{ + Q_OBJECT +public: + explicit Window(QWidget *const parent = nullptr); + virtual ~Window() = default; + +signals: + void themeChanged(bool); + + void newPasswordSignal(); + void cutPasswordSignal(bool); + + void saveSettingsSignal(); + + void newAndCopyPassowrdSignal(); + +protected: + virtual void closeEvent(QCloseEvent *const event) override; + + qsizetype getCurrentIndexTheme(); + + void updateIcons(); + + QSettings *userSettings; + QSystemTrayIcon *myTrayIcon; + const QString appName, appVersion; + +private: + void initializeMembers(); + + void createTitleBar(); + void createMenus(); + void createActions(); + void configurateActions(); + void configurateMenus(); + void configurateTitleBar(); + + void createTrayIcon(); + void configurateTrayIcon(); + void iconActivated(QSystemTrayIcon::ActivationReason reason); + + void connectSignals(); + + void changeLanguage(); + void restart(); + void saveSettings(); + void changeTheme(); + + void about(); + void credits(); + + qsizetype currentIndexLanguage, currentIndexTheme; + + QWidget *titleBar; + QToolButton *popUpButton, *minimizeButton, *closeButton; + QLabel *appIcon, *appTitleName; + QMenu *appMenu, + *languagesMenu, + *themesMenu, + *shortCutsMenu, + *helpMenu, + *myTrayIconMenu; + QList languageActionList, themeActionList; + QAction *generatePasswordAction, *cutPasswordAction, *copyPasswordAction, + *customTitleBarAction, + *aboutAction, *creditsAction, *aboutQtAction, + *exitAction, + *showProgramAction, *newAndCopyPassowrdAction; +}; + +#endif // WINDOW_H