From 44636c588237dfedd265515de06e7938b50a0411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Mon, 11 Jun 2012 18:31:02 +0200 Subject: [PATCH 01/23] Change version from 0.3 to 0.4 --- README | 2 +- README.fr | 2 +- debian/changelog | 4 ++-- src/controller/KissCount.hpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README b/README index 83d3a2e..c6810da 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ KissCount is personnal account software delivered under GPL v3 licence terms. -Current version is 0.3 +Current version is 0.4 Qt4 (>= 4.7), libqt4-sql-sqlite and libofx (Linux only) are needed diff --git a/README.fr b/README.fr index 38111a6..5c924e1 100644 --- a/README.fr +++ b/README.fr @@ -1,6 +1,6 @@ KissCount est un logiciel de gestion de comptes personnels délivré sous licence GPL v3 -La version actuelle est 0.3 +La version actuelle est 0.4 Qt4 (>= 4.7), libqt4-sql-sqlite et libofx (Uniquement pour Linux) sont nécessaires diff --git a/debian/changelog b/debian/changelog index f2b592b..bdd737d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -kisscount (0.3-1) unstable; urgency=low +kisscount (0.4-1) unstable; urgency=low * Initial release - -- Grégory Soutadé Sun, 24 Aug 2011 13:13:52 +0100 + -- Grégory Soutadé Sun, 10 June 2012 13:13:52 +0100 diff --git a/src/controller/KissCount.hpp b/src/controller/KissCount.hpp index 7bec035..c206920 100644 --- a/src/controller/KissCount.hpp +++ b/src/controller/KissCount.hpp @@ -30,7 +30,7 @@ #include -#define APP_VERSION "0.3" +#define APP_VERSION "0.4" #define ESCAPE_CHARS(s) s = s.replace("\"", " "); // #define ESCAPE_CHARS(s) s = s.replace("\"", "\\\""); s = s.replace("\'", "\\\'"); From 1bbf7b3ae70291d357e012f642735f847054baf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 12 Jun 2012 16:10:18 +0200 Subject: [PATCH 02/23] Fix a bug in install rule of Makefile --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a2a5c7f..49e9e0e 100644 --- a/Makefile +++ b/Makefile @@ -94,11 +94,11 @@ install: mkdir -p $(BIN_DIR) $(SHARE_DIR) $(DOC_DIR) cp kc $(BIN_DIR) cp -rf ressources/* $(SHARE_DIR) - rm -rf $(SHARE_DIR)/ressources/po/* - cp -rf ressources/po/*.qm $(SHARE_DIR)/ressources/po/ + rm -rf $(SHARE_DIR)/po/* # Only copy qm files + cp -rf ressources/po/*.qm $(SHARE_DIR)/po/ cp -rf README* ChangeLog AUTHORS COPYING TODO $(DOC_DIR) remove: rm -rf $(LIB_DIR) $(SHARE_DIR) $(DOC_DIR) $(BIN_DIR)/kc -uninstall: remove \ No newline at end of file +uninstall: remove From 24cb1df7a50df41c696ee398a45f8230b422d058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 14 Jun 2012 20:27:58 +0200 Subject: [PATCH 03/23] Remove TODO from binary packaging --- tools/package.sh | 4 ++-- tools/package_win32.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/package.sh b/tools/package.sh index 165d7e3..e2a947d 100755 --- a/tools/package.sh +++ b/tools/package.sh @@ -20,7 +20,7 @@ if [ "$1" == "clean" ] ; then make clean fi make || (echo "Compilation failed" ; exit 1) -cp -r kc ressources TODO AUTHORS COPYING README* www install.sh "$DIR" +cp -r kc ressources AUTHORS COPYING README* www install.sh "$DIR" rm -rf "$DIR"/ressources/po/* cp -r ressources/po/*.qm "$DIR/ressources/po/" # Copy only QM files find "$DIR" -type f -executable -exec ${HOST}strip \{\} \; @@ -32,7 +32,7 @@ if [ -d "debian" ] ; then DEB_FILE="kisscount_${VERSION}-1_${ARCH}.deb" rm -rf "$DEB_DIR" "$DEB_FILE" mkdir "$DEB_DIR" -cp -r kc.1 kc debian README* ChangeLog TODO AUTHORS COPYING ressources "$DEB_DIR" +cp -r kc.1 kc debian README* ChangeLog AUTHORS COPYING ressources "$DEB_DIR" rm -rf "$DEB_DIR/ressources/po/*" cp -r ressources/po/*.qm "$DEB_DIR"/ressources/po/ # Copy only QM files cd "$DEB_DIR" diff --git a/tools/package_win32.sh b/tools/package_win32.sh index 14ff006..14bc90f 100755 --- a/tools/package_win32.sh +++ b/tools/package_win32.sh @@ -15,7 +15,7 @@ make || (echo "Compilation failed" ; exit 1) rm -rf "$DIR" mkdir -p "$DIR" cp -r lib/*.dll* "$DIR" -cp -r kc ressources TODO AUTHORS COPYING README README.fr www "$DIR" +cp -r kc ressources AUTHORS COPYING README README.fr www "$DIR" rm -rf "$DIR"/ressources/po/* cp -r ressources/po/*.qm "$DIR/ressources/po/" # Copy only QM files mv "$DIR"/kc "$DIR"/kc.exe From 1aa37d3110e4c2d0905d5d0fd0ca7f15c2723362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Fri, 15 Jun 2012 13:14:49 +0200 Subject: [PATCH 04/23] Remove TODO to Debian packages Remove french.po from git --- ressources/po/french.po | 1012 --------------------------------------- 1 file changed, 1012 deletions(-) delete mode 100644 ressources/po/french.po diff --git a/ressources/po/french.po b/ressources/po/french.po deleted file mode 100644 index 10eb213..0000000 --- a/ressources/po/french.po +++ /dev/null @@ -1,1012 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-10 17:06+0200\n" -"PO-Revision-Date: \n" -"Last-Translator: Soutadé \n" -"Language-Team: \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: French\n" -"X-Poedit-Country: FRANCE\n" -"X-Poedit-SourceCharset: utf-8\n" - -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#: src/view/StatsPanel.cpp:416 -msgid " - " -msgstr " - " - -#: src/view/PreferencesPanel.cpp:1164 -msgid " ?" -msgstr " ?" - -#: src/view/UsersDialog.cpp:123 -#: src/view/PreferencesPanel.cpp:868 -#: src/view/PreferencesPanel.cpp:878 -#: src/view/PreferencesPanel.cpp:901 -#: src/view/PreferencesPanel.cpp:1043 -#: src/view/PreferencesPanel.cpp:1065 -#: src/view/PreferencesPanel.cpp:1108 -msgid " already exists" -msgstr " existe déjà" - -#: src/view/ImportPanel.cpp:282 -msgid " and " -msgstr " et " - -#: src/view/SnapshotsDialog.cpp:133 -#: src/view/SnapshotsDialog.cpp:167 -msgid " does not exist" -msgstr " n'existe pas" - -#: src/view/SearchPanel.cpp:104 -#: src/view/ExportPanel.cpp:98 -msgid " entries found" -msgstr " entrées trouvées" - -#: src/view/ImportPanel.cpp:304 -#: src/view/ImportPanel.cpp:328 -msgid " must have a name" -msgstr " doit avoir un nom" - -#: src/model/Database.cpp:99 -msgid " not found, aborting" -msgstr " non trouvé, arrêt" - -#: src/view/AccountPanel.cpp:941 -msgid " operations ?" -msgstr " opérations ?" - -#: src/view/SnapshotsDialog.cpp:113 -msgid " successfully created" -msgstr " crée" - -#: src/view/SnapshotsDialog.cpp:146 -msgid " successfully removed" -msgstr " supprimé" - -#: src/view/ImportPanel.cpp:288 -msgid " will be created, is it ok ?" -msgstr " vont être créés, êtes vous d'accord ?" - -#: src/view/ImportPanel.cpp:281 -#, c-format -msgid "%d accounts" -msgstr "%d comptes" - -#: src/view/ImportPanel.cpp:286 -#, c-format -msgid "%d categories" -msgstr "%d catégories" - -#: src/view/StatsPanel.cpp:360 -msgid "0 line" -msgstr "Limite 0" - -#: src/view/SearchPanel.cpp:106 -#: src/view/ExportPanel.cpp:100 -msgid "1 entry found" -msgstr "1 entrée trouvée" - -#: src/model/Database.cpp:93 -msgid "A new database will be created, continue ?" -msgstr "Une nouvelle base de données va être crée, continuer ?" - -#: src/view/SearchBanner.cpp:98 -#: src/view/grid/GridAccount.cpp:73 -msgid "Account" -msgstr "Compte" - -#: src/view/ImportPanel.cpp:304 -#: src/view/PreferencesPanel.cpp:878 -#: src/view/PreferencesPanel.cpp:901 -msgid "Account " -msgstr "Le compte " - -#: src/controller/KissCount.cpp:341 -msgid "Account 1" -msgstr "Compte 1" - -#: src/view/PreferencesPanel.cpp:868 -msgid "Account must have a name" -msgstr "Le compte doit avoir un nom" - -#: src/view/ImportPanel.cpp:64 -#: src/view/AccountPanel.cpp:507 -msgid "Account name" -msgstr "Nom du compte" - -#: src/view/AccountPanel.cpp:506 -msgid "Account number" -msgstr "Numéro de compte" - -#: src/view/StatsPanel.cpp:359 -#: src/view/PreferencesPanel.cpp:47 -msgid "Accounts" -msgstr "Comptes" - -#: src/view/AccountPanel.cpp:1173 -msgid "Accounts updated until " -msgstr "Comptes mis à jours jusqu'à " - -#: src/view/StatsPanel.cpp:337 -msgid "Amount" -msgstr "Montant" - -#: src/view/SearchBanner.cpp:94 -msgid "Amount from" -msgstr "Montant min" - -#: src/view/SearchBanner.cpp:95 -msgid "Amount to" -msgstr "Montant max" - -#: src/view/AccountPanel.cpp:1178 -msgid "Any account updated !" -msgstr "Aucun compte mis à jour" - -#: src/view/ImportPanel.cpp:170 -#: src/view/ExportPanel.cpp:138 -msgid "Any engine can process this file !" -msgstr "Format de fichier non reconnu" - -#: src/view/SnapshotsDialog.cpp:171 -msgid "Are you sure want to come back to " -msgstr "êtes vous sûr de vouloir revenir à " - -#: src/view/SnapshotsDialog.cpp:137 -#: src/view/AccountPanel.cpp:936 -msgid "Are you sure want to delete " -msgstr "Etes vous sûr de vouloir supprimer " - -#: src/view/grid/GridAccount.cpp:793 -msgid "Are you sure want to delete : \n" -msgstr "Etes vous sûr de vouloir supprimer : \n" - -#: src/view/PreferencesPanel.cpp:1164 -msgid "Are you sure want to delete profil of " -msgstr "Etes vous sûr de vouloir supprimer le profil de " - -#: src/view/ImportPanel.cpp:376 -msgid "Are you sure want to integrate these operations ?" -msgstr "Etes vous sûr de vouloir intégreer ces opérations" - -#: src/view/PreferencesPanel.cpp:476 -msgid "Ascending" -msgstr "Croissant" - -#: src/view/SnapshotsDialog.cpp:43 -msgid "Back to this snapshot" -msgstr "Revenir à cette sauvegarde" - -#: src/view/PreferencesPanel.cpp:354 -msgid "Background color" -msgstr "Couleur d'arrière plan" - -#: src/view/AccountPanel.cpp:299 -msgid "Balance" -msgstr "Solde" - -#: src/view/PreferencesPanel.cpp:221 -msgid "Blocked" -msgstr "Bloqué" - -#: src/view/UsersDialog.cpp:50 -#: src/view/GenerateDialog.cpp:49 -#: src/view/PasswordDialog.cpp:50 -msgid "Cancel" -msgstr "Annuler" - -#: src/view/grid/GridAccount.cpp:1305 -#: src/view/grid/GridAccount.cpp:1318 -msgid "Cannot group these operations" -msgstr "Impossible de grouper ces opérations" - -#: src/view/grid/GridAccount.cpp:1449 -#: src/view/grid/GridAccount.cpp:1455 -msgid "Cannot ungroup these operations" -msgstr "Impossible de dégrouper ces opérations" - -#: src/model/DatabaseUpdate.cpp:94 -msgid "Cannot update database version 2 to version 3 because some columns needs to be deleted." -msgstr "Impossible de migrer d'une base de données en version 2 à une base de données en version 3 car certaines colones ont été supprimées" - -#: src/controller/KissCount.cpp:332 -msgid "Car" -msgstr "Voiture" - -#: src/view/PreferencesPanel.cpp:48 -msgid "Categories" -msgstr "Catégories" - -#: src/view/SearchBanner.cpp:96 -#: src/view/grid/GridAccount.cpp:73 -msgid "Category" -msgstr "Catégorie" - -#: src/view/ImportPanel.cpp:328 -#: src/view/PreferencesPanel.cpp:1043 -#: src/view/PreferencesPanel.cpp:1065 -msgid "Category " -msgstr "La catégorie " - -#: src/view/PreferencesPanel.cpp:1033 -msgid "Category must have a name" -msgstr "La catégorie doit avoir un nom" - -#: src/view/ImportPanel.cpp:71 -msgid "Category name" -msgstr "Catégorie" - -#: src/view/PreferencesPanel.cpp:65 -msgid "Change Name" -msgstr "Changer de nom" - -#: src/view/PreferencesPanel.cpp:66 -msgid "Change Password" -msgstr "Changer le mot de passe" - -#: src/view/SearchPanel.cpp:47 -msgid "Change account" -msgstr "Changer de compte" - -#: src/view/SearchPanel.cpp:48 -msgid "Change category" -msgstr "Changer la catégorie" - -#: src/view/PasswordDialog.cpp:30 -msgid "Change password" -msgstr "Changer le mot de passe" - -#: src/view/AccountPanel.cpp:160 -msgid "Check" -msgstr "Rapprochement" - -#: src/view/SearchBanner.cpp:77 -msgid "Checked" -msgstr "Rapprochée" - -#: src/view/ImportPanel.cpp:133 -msgid "Choose a database to open" -msgstr "Choisissez une base de données à ouvrir" - -#: src/view/SearchPanel.cpp:151 -msgid "Choose a new account" -msgstr "Nouveau compte" - -#: src/view/SearchPanel.cpp:191 -msgid "Choose a new category" -msgstr "Nouvelle catégorie" - -#: src/view/PasswordDialog.cpp:41 -msgid "Confirm password" -msgstr "Confirmer le mot de passe" - -#: src/view/StatsPanel.cpp:158 -#: src/view/AccountPanel.cpp:109 -msgid "Cost repartition" -msgstr "Répartition des coûts" - -#: src/view/SnapshotsDialog.cpp:41 -msgid "Create a snapshot" -msgstr "Faire une sauvegarde" - -#: src/view/ImportPanel.cpp:181 -#: src/view/ImportPanel.cpp:211 -#: src/view/ImportPanel.cpp:255 -#: src/view/ImportPanel.cpp:266 -#: src/view/ImportPanel.cpp:295 -#: src/view/ImportPanel.cpp:318 -msgid "Create one" -msgstr "En créer un" - -#: src/view/grid/GridAccount.cpp:73 -msgid "Credit" -msgstr "Crédit" - -#: src/view/AccountPanel.cpp:295 -msgid "Cur Credit" -msgstr "Cur Crédit" - -#: src/view/AccountPanel.cpp:296 -msgid "Cur Debit" -msgstr "Cur Débit" - -#: src/view/AccountPanel.cpp:509 -msgid "Current value" -msgstr "Valeur courante" - -#: src/view/grid/GridAccount.cpp:73 -msgid "Date" -msgstr "Date" - -#: src/view/SearchBanner.cpp:30 -msgid "Date from" -msgstr "Date min" - -#: src/view/SearchBanner.cpp:31 -msgid "Date to" -msgstr "Date max" - -#: src/view/StatsPanel.cpp:351 -msgid "Days" -msgstr "Jours" - -#: src/view/grid/GridAccount.cpp:73 -msgid "Debit" -msgstr "Débit" - -#: src/view/PreferencesPanel.cpp:219 -msgid "Default" -msgstr "Défaut" - -#: src/view/PreferencesPanel.cpp:674 -msgid "Default account cannot be hidden" -msgstr "Impossible de cacher le compte par défaut" - -#: src/view/PreferencesPanel.cpp:222 -#: src/view/PreferencesPanel.cpp:357 -#: src/view/AccountPanel.cpp:794 -msgid "Delete" -msgstr "Supprimer" - -#: src/view/SnapshotsDialog.cpp:42 -msgid "Delete a snapshot" -msgstr "Supprimer la sauvegarde" - -#: src/view/PreferencesPanel.cpp:477 -msgid "Descending" -msgstr "Décroissant" - -#: src/view/SearchBanner.cpp:93 -#: src/view/grid/GridAccount.cpp:73 -msgid "Description" -msgstr "Description" - -#: src/view/SearchPanel.cpp:228 -msgid "Enter a new description" -msgstr "Nouvelle description" - -#: src/view/StatsPanel.cpp:431 -#: src/view/UsersDialog.cpp:93 -#: src/view/UsersDialog.cpp:123 -#: src/view/SearchBanner.cpp:156 -#: src/view/SearchBanner.cpp:166 -#: src/view/SearchBanner.cpp:179 -#: src/view/SearchBanner.cpp:188 -#: src/view/SnapshotsDialog.cpp:117 -#: src/view/SnapshotsDialog.cpp:133 -#: src/view/SnapshotsDialog.cpp:142 -#: src/view/SnapshotsDialog.cpp:167 -#: src/view/SnapshotsDialog.cpp:176 -#: src/view/ImportPanel.cpp:170 -#: src/view/ImportPanel.cpp:304 -#: src/view/ImportPanel.cpp:328 -#: src/view/ExportPanel.cpp:125 -#: src/view/ExportPanel.cpp:138 -#: src/view/ExportPanel.cpp:145 -#: src/view/PreferencesPanel.cpp:601 -#: src/view/PreferencesPanel.cpp:674 -#: src/view/PreferencesPanel.cpp:868 -#: src/view/PreferencesPanel.cpp:878 -#: src/view/PreferencesPanel.cpp:901 -#: src/view/PreferencesPanel.cpp:1033 -#: src/view/PreferencesPanel.cpp:1043 -#: src/view/PreferencesPanel.cpp:1065 -#: src/view/PreferencesPanel.cpp:1102 -#: src/view/PreferencesPanel.cpp:1108 -#: src/view/PreferencesPanel.cpp:1150 -#: src/view/PasswordDialog.cpp:64 -#: src/view/PasswordDialog.cpp:70 -#: src/view/AccountPanel.cpp:932 -#: src/view/grid/GridAccount.cpp:1305 -#: src/view/grid/GridAccount.cpp:1318 -#: src/view/grid/GridAccount.cpp:1449 -#: src/view/grid/GridAccount.cpp:1455 -#: src/view/grid/FormulaDelegate.cpp:59 -#: src/model/Database.cpp:47 -#: src/model/Database.cpp:55 -#: src/model/Database.cpp:74 -#: src/model/Database.cpp:99 -#: src/model/Database.cpp:105 -#: src/model/Database.cpp:111 -#: src/model/Database.cpp:121 -#: src/model/Database.cpp:140 -#: src/model/Database.cpp:582 -#: src/model/Database.cpp:758 -#: src/model/Database.cpp:900 -#: src/model/Database.cpp:1720 -#: src/model/DatabaseUpdate.cpp:31 -#: src/model/DatabaseUpdate.cpp:164 -msgid "Error" -msgstr "Erreur" - -#: src/model/Database.cpp:140 -msgid "Error creating original database" -msgstr "Erreur durant la création de la base de données initiale" - -#: src/view/ExportPanel.cpp:47 -#: src/view/ExportPanel.cpp:81 -msgid "Export" -msgstr "Export" - -#: src/view/ExportPanel.cpp:145 -msgid "Failed to save operations" -msgstr "Erreur lors de la sauvegarde des opérations" - -#: src/view/ImportPanel.cpp:64 -msgid "File account" -msgstr "Compte du fichier" - -#: src/view/ImportPanel.cpp:71 -msgid "File category" -msgstr "Catégorie du fichier" - -#: src/view/AccountPanel.cpp:510 -msgid "Final value" -msgstr "Valeur finale" - -#: src/view/SearchBanner.cpp:73 -#: src/view/grid/GridAccount.cpp:360 -#: src/controller/KissCount.cpp:332 -msgid "Fix" -msgstr "Fixe" - -#: src/view/PreferencesPanel.cpp:356 -msgid "Font" -msgstr "Police" - -#: src/view/PreferencesPanel.cpp:355 -msgid "Foreground color" -msgstr "Couleur d'avant plan" - -#: src/view/StatsPanel.cpp:71 -msgid "From" -msgstr "De" - -#: src/view/GenerateDialog.cpp:36 -msgid "From " -msgstr "A partir de " - -#: src/view/GenerateDialog.cpp:33 -#: src/view/AccountPanel.cpp:791 -msgid "Generate month" -msgstr "Générer mois" - -#: src/model/import/GrisbiImportEngine.cpp:166 -msgid "Grisbi files (*.gsb)" -msgstr "Fichiers Grisbi (*.gsb)" - -#: src/controller/KissCount.cpp:332 -msgid "Groceries" -msgstr "Courses" - -#: src/view/AccountPanel.cpp:184 -msgid "Group" -msgstr "Grouper" - -#: src/view/PreferencesPanel.cpp:223 -msgid "Hidden" -msgstr "Caché" - -#: src/controller/KissCount.cpp:332 -msgid "Hobbies" -msgstr "Loisirs" - -#: src/view/ImportPanel.cpp:121 -msgid "Import" -msgstr "Import" - -#: src/view/AccountPanel.cpp:508 -msgid "Initial value" -msgstr "Valeur initiale" - -#: src/view/ImportPanel.cpp:47 -msgid "Integrate operations" -msgstr "Intégrer les opérations" - -#: src/view/ImportPanel.cpp:64 -msgid "Internal account" -msgstr "Compte interne" - -#: src/view/ImportPanel.cpp:71 -msgid "Internal category" -msgstr "Catégorie interne" - -#: src/view/SearchBanner.cpp:166 -msgid "Invalid amount from" -msgstr "Montant min invalide" - -#: src/view/SearchBanner.cpp:188 -msgid "Invalid amount range" -msgstr "Intervalle des montants invalide" - -#: src/view/SearchBanner.cpp:179 -msgid "Invalid amount to" -msgstr "Montant max invalide" - -#: src/view/SearchBanner.cpp:156 -msgid "Invalid date range" -msgstr "Intervalle de temps invalide" - -#: src/view/grid/FormulaDelegate.cpp:59 -msgid "Invalid formula !" -msgstr "Formule invalide !" - -#: src/view/PreferencesPanel.cpp:1102 -msgid "Invalid name !" -msgstr "Nom invalide !" - -#: src/view/PasswordDialog.cpp:64 -msgid "Invalid old password" -msgstr "Ancien mot de passe invalide" - -#: src/view/UsersDialog.cpp:93 -msgid "Invalid password" -msgstr "Mot de passe invalide" - -#: src/view/StatsPanel.cpp:431 -msgid "Invalide date range" -msgstr "Intervalle de temps invalide" - -#: src/view/PreferencesPanel.cpp:601 -msgid "It must be at least one account !" -msgstr "Il doit y avoir au moins un compte !" - -#: src/view/AccountPanel.cpp:932 -msgid "It must be at least one month !" -msgstr "Il doit rester au moins un mois" - -#: src/view/PreferencesPanel.cpp:67 -msgid "Kill me" -msgstr "Kill me" - -#: src/view/SearchPanel.cpp:104 -#: src/view/SearchPanel.cpp:106 -#: src/view/SearchPanel.cpp:109 -#: src/view/ExportPanel.cpp:98 -#: src/view/ExportPanel.cpp:100 -#: src/view/ExportPanel.cpp:103 -#: src/view/ExportPanel.cpp:143 -msgid "KissCount" -msgstr "KissCount" - -#: src/view/ExportPanel.cpp:151 -msgid "KissCount - Export" -msgstr "KissCount - Export" - -#: src/view/ImportPanel.cpp:126 -msgid "KissCount - Import" -msgstr "KissCount - Import" - -#: src/model/export/XMLExportEngine.cpp:34 -msgid "KissCount XML files (*.xml)" -msgstr "Fichiers KissCount xml (*.xml)" - -#: src/model/import/XMLImportEngine.cpp:32 -msgid "KissCount xml files (*.xml)" -msgstr "Fichiers KissCount xml (*.xml)" - -#: src/view/PreferencesPanel.cpp:49 -msgid "Language" -msgstr "Langue" - -#: src/view/PreferencesPanel.cpp:1150 -msgid "Language not changed" -msgstr "Langue non changée" - -#: src/view/PreferencesPanel.cpp:1147 -msgid "Language successfully changed, please go to another panel" -msgstr "Langue changée, allez sur un autre panneau pour rendre le changement effectif" - -#: src/view/wxUI.cpp:296 -msgid "Licenced under GNU GPL v3" -msgstr "Licence GNU GPL v3" - -#: src/view/ImportPanel.cpp:43 -msgid "Load operations" -msgstr "Charger les opérations" - -#: src/view/AccountPanel.cpp:156 -msgid "Mode" -msgstr "Mode" - -#: src/view/StatsPanel.cpp:348 -msgid "Months" -msgstr "Mois" - -#: src/view/PreferencesPanel.cpp:59 -#: src/view/PreferencesPanel.cpp:217 -#: src/view/PreferencesPanel.cpp:353 -msgid "Name" -msgstr "Nom" - -#: src/view/PreferencesPanel.cpp:1114 -msgid "Name changed" -msgstr "Nom changé" - -#: src/view/UsersDialog.cpp:51 -#: src/view/UsersDialog.cpp:114 -msgid "New User" -msgstr "Nouvel utilisateur" - -#: src/view/PasswordDialog.cpp:37 -msgid "New password" -msgstr "Nouveau mot de passe" - -#: src/view/SearchPanel.cpp:109 -#: src/view/ExportPanel.cpp:103 -msgid "No entry found" -msgstr "Pas d'entrée trouvée" - -#: src/view/ImportPanel.cpp:360 -msgid "No operation found into this file" -msgstr "Aucun opération trouvée dans ce fichier" - -#: src/view/ExportPanel.cpp:125 -msgid "No operation to save" -msgstr "Aucun opération à sauvegarder" - -#: src/view/StatsPanel.cpp:134 -#: src/view/SearchBanner.cpp:75 -#: src/view/AccountPanel.cpp:300 -msgid "Non fix" -msgstr "Courantes" - -#: src/view/SearchPanel.cpp:147 -#: src/view/SearchPanel.cpp:187 -#: src/view/PreferencesPanel.cpp:617 -#: src/view/PreferencesPanel.cpp:709 -msgid "None" -msgstr "Aucun" - -#: src/view/SearchBanner.cpp:79 -msgid "Not checked" -msgstr "Non rapprochée" - -#: src/view/PreferencesPanel.cpp:218 -msgid "Number" -msgstr "Numéro de compte" - -#: src/model/import/OFXImportEngine.cpp:144 -msgid "OFX files (*.ofx)" -msgstr "Fichiers OFX (*.ofx)" - -#: src/view/UsersDialog.cpp:49 -#: src/view/SnapshotsDialog.cpp:55 -#: src/view/GenerateDialog.cpp:48 -#: src/view/PasswordDialog.cpp:49 -msgid "OK" -msgstr "OK" - -#: src/view/PasswordDialog.cpp:33 -msgid "Old password" -msgstr "Ancien mot de passe" - -#: src/view/PreferencesPanel.cpp:50 -msgid "Operation order" -msgstr "Ordre des opérations" - -#: src/view/SearchBanner.cpp:97 -#: src/view/AccountPanel.cpp:254 -msgid "Operations" -msgstr "Opérations" - -#: src/view/ImportPanel.cpp:433 -msgid "Operations successfully imported" -msgstr "les opérations ont été importées avec succès" - -#: src/view/ExportPanel.cpp:143 -msgid "Operations successfuly saved" -msgstr "Opérations sauvegardées avec succès" - -#: src/controller/KissCount.cpp:333 -msgid "Other" -msgstr "Autres" - -#: src/view/UsersDialog.cpp:44 -msgid "Password " -msgstr "Mot de passe " - -#: src/view/PasswordDialog.cpp:76 -msgid "Password changed" -msgstr "Mot de passe changé" - -#: src/view/wxUI.cpp:296 -msgid "Personal accounting software" -msgstr "Logiciel de comptabilité personnelle" - -#: src/view/PasswordDialog.cpp:70 -msgid "Please retype new password" -msgstr "Re entrez le mot de passe" - -#: src/view/PreferencesPanel.cpp:203 -#: src/view/PreferencesPanel.cpp:1155 -msgid "Preferences" -msgstr "Préférences" - -#: src/view/wxUI.cpp:301 -msgid "Quit KissCount ?" -msgstr "Quitter KissCount ?" - -#: src/view/AccountPanel.cpp:159 -msgid "Real" -msgstr "Réel" - -#: src/view/SearchPanel.cpp:49 -msgid "Rename" -msgstr "Renommer" - -#: src/view/ExportPanel.cpp:129 -msgid "Save as" -msgstr "Sauvegarder sous" - -#: src/view/ImportPanel.cpp:51 -msgid "Save import patterns" -msgstr "Sauvegarder les motifs d'import" - -#: src/view/SearchPanel.cpp:34 -#: src/view/SearchPanel.cpp:87 -#: src/view/SearchPanel.cpp:238 -#: src/view/ExportPanel.cpp:34 -msgid "Search" -msgstr "Chercher" - -#: src/view/PreferencesPanel.cpp:51 -msgid "Shared with" -msgstr "Partagé avec" - -#: src/view/SnapshotsDialog.cpp:32 -#: src/view/AccountPanel.cpp:187 -msgid "Snapshots" -msgstr "Sauvegardes" - -#: src/view/StatsPanel.cpp:215 -#: src/view/StatsPanel.cpp:416 -msgid "Statistics" -msgstr "Statistiques" - -#: src/view/StatsPanel.cpp:76 -msgid "To" -msgstr "A" - -#: src/view/AccountPanel.cpp:274 -#: src/view/AccountPanel.cpp:297 -msgid "Total Credit" -msgstr "Total Crédit" - -#: src/view/AccountPanel.cpp:275 -#: src/view/AccountPanel.cpp:298 -msgid "Total Debit" -msgstr "Total Débit" - -#: src/view/AccountPanel.cpp:185 -msgid "UnGroup" -msgstr "Dégrouper" - -#: src/model/Database.cpp:105 -#: src/model/Database.cpp:111 -msgid "Unable to Create " -msgstr "Impossible de créer " - -#: src/view/SnapshotsDialog.cpp:117 -msgid "Unable to create " -msgstr "Impossible de créer " - -#: src/model/Database.cpp:121 -msgid "Unable to open Database" -msgstr "Impossible d'ouvrir la base de données" - -#: src/model/Database.cpp:47 -#: src/model/Database.cpp:55 -#: src/model/Database.cpp:74 -#: src/model/Database.cpp:1720 -msgid "Unable to open database" -msgstr "Impossible d'ouvrir la base de données" - -#: src/view/SnapshotsDialog.cpp:142 -#: src/view/SnapshotsDialog.cpp:176 -msgid "Unable to remove " -msgstr "Impossible de supprimer " - -#: src/model/DatabaseUpdate.cpp:164 -msgid "Unable to upgrade Database" -msgstr "Impossible de mettre à jour la base de données" - -#: src/controller/KissCount.cpp:333 -msgid "Unexpected" -msgstr "Exceptionnel" - -#: src/view/SearchBanner.cpp:63 -#: src/view/SearchBanner.cpp:84 -#: src/view/AccountPanel.cpp:658 -#: src/model/User.cpp:65 -#: src/model/User.cpp:83 -#: src/model/User.cpp:161 -msgid "Unknown" -msgstr "Inconnu" - -#: src/view/ImportPanel.cpp:32 -msgid "Unresolved accounts" -msgstr "Comptes non résolus" - -#: src/view/ImportPanel.cpp:33 -msgid "Unresolved categories" -msgstr "Catégories non résolues" - -#: src/model/Database.cpp:582 -#: src/model/Database.cpp:758 -#: src/model/Database.cpp:900 -msgid "Update failed !\n" -msgstr "La mise à jour à échouée !\n" - -#: src/view/AccountPanel.cpp:186 -msgid "Update next months" -msgstr "Mettre à jour mois suivants" - -#: src/view/PreferencesPanel.cpp:46 -msgid "User" -msgstr "Utilisateur" - -#: src/view/UsersDialog.cpp:40 -#: src/view/UsersDialog.cpp:123 -#: src/view/PreferencesPanel.cpp:1108 -msgid "User " -msgstr "Utilisateur " - -#: src/view/UsersDialog.cpp:35 -msgid "Users" -msgstr "Utilisateurs" - -#: src/view/PreferencesPanel.cpp:220 -#: src/view/AccountPanel.cpp:158 -msgid "Virtual" -msgstr "Virtuel" - -#: src/view/grid/GridAccount.cpp:1111 -msgid "Warning" -msgstr "Attention" - -#: src/view/SnapshotsDialog.cpp:193 -#: src/view/SnapshotsDialog.cpp:203 -msgid "Welcome back to " -msgstr "Bienvenue sur " - -#: src/view/PreferencesPanel.cpp:622 -msgid "Wich account will replace this one ?" -msgstr "Quel compte va remplacer celui-ci ?" - -#: src/view/PreferencesPanel.cpp:715 -msgid "Wich category will replace this one ?" -msgstr "Quelle catégorie va remplacer celle-ci" - -#: src/view/grid/GridAccount.cpp:1111 -msgid "You made a debit on a blocked account" -msgstr "Vous avez effectué une opération de débit sur un compte bloqué" - -#: src/view/wxUI.cpp:158 -msgid "april" -msgstr "avril" - -#: src/view/wxUI.cpp:162 -msgid "august" -msgstr "août" - -#: src/view/wxUI.cpp:166 -msgid "december" -msgstr "décembre" - -#: src/view/wxUI.cpp:156 -msgid "february" -msgstr "février" - -#: src/view/wxUI.cpp:155 -msgid "january" -msgstr "janvier" - -#: src/view/wxUI.cpp:161 -msgid "july" -msgstr "juillet" - -#: src/view/wxUI.cpp:160 -msgid "june" -msgstr "juin" - -#: src/view/wxUI.cpp:157 -msgid "march" -msgstr "mars" - -#: src/view/wxUI.cpp:159 -msgid "may" -msgstr "mai" - -#: src/view/wxUI.cpp:165 -msgid "november" -msgstr "novembre" - -#: src/view/wxUI.cpp:164 -msgid "october" -msgstr "octobre" - -#: src/view/wxUI.cpp:163 -msgid "september" -msgstr "septembre" - -#~ msgid "" -#~ "Personal accounting software\n" -#~ "\n" -#~ "http://indefero.soutade.fr/p/kisscount/\n" -#~ "\n" -#~ "Licenced under GNU GPL v3\n" -#~ "\n" -#~ "Copyright (C) 2010-2012 Grégory Soutadé" -#~ msgstr "" -#~ "Logiciel de comptabilité personnelle\n" -#~ "\n" -#~ "http://indefero.soutade.fr/p/kisscount/\n" -#~ "\n" -#~ "Licence GNU GPL v3\n" -#~ "\n" -#~ "Copyright (C) 2010-2012 Grégory Soutadé" - -#~ msgid " profil ?" -#~ msgstr " profil ?" - -#~ msgid "" -#~ "!! Warning !! If there was a bug, the old database will be suppressed !" -#~ msgstr "" -#~ "!! Attention !! S'il y a eu un bug, l'ancienne base de donnée va être " -#~ "supprimée !" - -#~ msgid "" -#~ "No database found, would you like to create a new one ?\n" -#~ "\n" -#~ msgstr "" -#~ "Aucune base de données trouvée, voulez vous en créer une nouvelle ?\n" -#~ "\n" - -#~ msgid "Serie 1" -#~ msgstr "Série 1" - -#~ msgid "To " -#~ msgstr "Vers " - -#~ msgid "XML files (*.xml)|*.xml" -#~ msgstr "Fichiers XML (*.xml)|*.xml" - -#~ msgid "Remains" -#~ msgstr "Restant" - -#~ msgid "Operating expense" -#~ msgstr "Fonctionnement" - -#~ msgid "Check mode" -#~ msgstr "Mode rapprochement" - -#~ msgid "Query failed !\n" -#~ msgstr "La requête a échouée !\n" - -#~ msgid "About" -#~ msgstr "A propos" - -#~ msgid "Change user" -#~ msgstr "Changer d'utilisateur" - -#~ msgid "Quit" -#~ msgstr "Quitter" - -#~ msgid "Both" -#~ msgstr "Les deux" - -#~ msgid "Color" -#~ msgstr "Couleur" - -#~ msgid "Fixe" -#~ msgstr "Fixe" From 51e348ef7b2d3c969ca4e4a2eae7dfa0c1a3f102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Fri, 29 Jun 2012 20:33:33 +0200 Subject: [PATCH 05/23] Add primitive support of low resolutions --- ChangeLog | 8 ++++++++ src/view/AccountPanel.cpp | 22 +++++++--------------- src/view/AccountPanel.hpp | 8 ++++---- src/view/ExportPanel.cpp | 20 ++++++-------------- src/view/ExportPanel.hpp | 3 +-- src/view/ImportPanel.cpp | 20 ++++++-------------- src/view/ImportPanel.hpp | 3 +-- src/view/PreferencesPanel.cpp | 19 +++++-------------- src/view/PreferencesPanel.hpp | 3 +-- src/view/SearchPanel.cpp | 20 ++++++-------------- src/view/SearchPanel.hpp | 3 +-- src/view/StatsPanel.cpp | 20 ++++++-------------- src/view/StatsPanel.hpp | 3 +-- src/view/view.hpp | 11 +++++++++++ src/view/wxUI.cpp | 35 ++++++++++++++++++++++++----------- src/view/wxUI.hpp | 24 ++++++++++++++++++++++-- 16 files changed, 110 insertions(+), 112 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f3c0ac..f53b387 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +v0.4 (29/06/2012) +** User ** + Add icons for low resolution + +** Dev ** + Primitive handle of low resolutions + + v0.3 (31/05/2012) ** User ** New interface in Qt4 diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp index 84af2f8..8dd08b9 100644 --- a/src/view/AccountPanel.cpp +++ b/src/view/AccountPanel.cpp @@ -33,12 +33,13 @@ enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, BALANCE, STATS_ROW, CATS enum {VIRTUAL_MODE=0, REAL_MODE, CHECK_MODE}; -AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _curMonth(-1), _curYear(-1), _inModification(false) +AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : + KissPanel(kiss, parent, lowResolution), _curMonth(-1), _curYear(-1), _inModification(false) { Init(kiss, parent, 0); } -AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent, int month=-1, int year=-1, int mode=VIRTUAL_MODE) : KissPanel(kiss, parent), _curMonth(month), _curYear(year), _inModification(false) +AccountPanel::AccountPanel(KissCount* kiss, wxUI *parent, bool lowResolution, int month=-1, int year=-1, int mode=VIRTUAL_MODE) : KissPanel(kiss, parent, lowResolution), _curMonth(month), _curYear(year), _inModification(false) { Init(kiss, parent, mode); } @@ -57,6 +58,9 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode) std::vector::iterator categoryIt; int nbCategories; + _icons[KissPanel::LOW_RES_ICON] = USER_LOW_ICON; + _icons[KissPanel::HIGH_RES_ICON] = USER_ICON; + setLayout(hbox); _tree = new QTreeWidget(this); @@ -234,19 +238,7 @@ KissPanel* AccountPanel::CreatePanel() else if (_real->isChecked()) mode = REAL_MODE; else if (_check->isChecked()) mode = CHECK_MODE; - return new AccountPanel(_kiss, _wxUI, _curMonth, _curYear, mode); -} - -QPushButton* AccountPanel::GetButton() -{ - if (!_KissButton) - { - _KissButton = new QPushButton(QIcon(USER_ICON), "", this); - _KissButton->setFixedSize(128, 128); - _KissButton->setIconSize(QSize(128, 128)); - } - - return _KissButton; + return new AccountPanel(_kiss, _wxUI, _lowResolution, _curMonth, _curYear, mode); } QString AccountPanel::GetToolTip() diff --git a/src/view/AccountPanel.hpp b/src/view/AccountPanel.hpp index c128bfd..aa54a04 100644 --- a/src/view/AccountPanel.hpp +++ b/src/view/AccountPanel.hpp @@ -39,13 +39,13 @@ class AccountPanel: public KissPanel Q_OBJECT; public: - AccountPanel(KissCount* kiss, wxUI *parent); - AccountPanel(KissCount* kiss, wxUI *parent, int month, int year, int mode); - void Init(KissCount* kiss, wxUI *parent, int curMode); + AccountPanel(KissCount* kiss, wxUI *parent, bool lowResolution); + AccountPanel(KissCount* kiss, wxUI *parent, bool lowResolution, int month, int year, int mode); ~AccountPanel(); + void Init(KissCount* kiss, wxUI *parent, int curMode); + KissPanel* CreatePanel(); - QPushButton* GetButton(); QString GetToolTip(); void OnShow(); diff --git a/src/view/ExportPanel.cpp b/src/view/ExportPanel.cpp index 4ce40c6..20c8dc9 100644 --- a/src/view/ExportPanel.cpp +++ b/src/view/ExportPanel.cpp @@ -19,7 +19,8 @@ #include "ExportPanel.hpp" -ExportPanel::ExportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _operations(0) +ExportPanel::ExportPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : + KissPanel(kiss, parent, lowResolution), _operations(0) { DEFAULT_FONT(font); std::vector::iterator accountIt; @@ -29,6 +30,9 @@ ExportPanel::ExportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent QVBoxLayout *vbox2 = new QVBoxLayout; QHBoxLayout *hbox = new QHBoxLayout; + _icons[KissPanel::LOW_RES_ICON] = EXPORT_LOW_ICON; + _icons[KissPanel::HIGH_RES_ICON] = EXPORT_ICON; + setLayout(vbox); _searchButton = new QPushButton(_("Search")); @@ -61,19 +65,7 @@ ExportPanel::~ExportPanel() KissPanel* ExportPanel::CreatePanel() { - return new ExportPanel(_kiss, _wxUI); -} - -QPushButton* ExportPanel::GetButton() -{ - if (!_KissButton) - { - _KissButton = new QPushButton(QIcon(EXPORT_ICON), "", this); - _KissButton->setFixedSize(128, 128); - _KissButton->setIconSize(QSize(128, 128)); - } - - return _KissButton; + return new ExportPanel(_kiss, _wxUI, _lowResolution); } QString ExportPanel::GetToolTip() diff --git a/src/view/ExportPanel.hpp b/src/view/ExportPanel.hpp index f27ed5c..0f17f8e 100644 --- a/src/view/ExportPanel.hpp +++ b/src/view/ExportPanel.hpp @@ -38,11 +38,10 @@ class ExportPanel: public KissPanel Q_OBJECT; public: - ExportPanel(KissCount* kiss, wxUI *parent); + ExportPanel(KissCount* kiss, wxUI *parent, bool lowResolution); ~ExportPanel(); KissPanel* CreatePanel(); - QPushButton* GetButton(); QString GetToolTip(); void OnShow(); diff --git a/src/view/ImportPanel.cpp b/src/view/ImportPanel.cpp index ac7ceae..6a4251b 100644 --- a/src/view/ImportPanel.cpp +++ b/src/view/ImportPanel.cpp @@ -22,7 +22,8 @@ #include "ImportPanel.hpp" #include "grid/ChoiceDelegate.hpp" -ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent) +ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : + KissPanel(kiss, parent, lowResolution) { QVBoxLayout *vbox = new QVBoxLayout; QVBoxLayout *vbox2 = new QVBoxLayout; @@ -32,6 +33,9 @@ ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent QGroupBox* staticAccount = new QGroupBox(_("Unresolved accounts")); QGroupBox* staticCategory = new QGroupBox(_("Unresolved categories")); + _icons[KissPanel::LOW_RES_ICON] = IMPORT_LOW_ICON; + _icons[KissPanel::HIGH_RES_ICON] = IMPORT_ICON; + setLayout(vbox); _fileTxt = new QLineEdit; @@ -101,19 +105,7 @@ ImportPanel::ImportPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent KissPanel* ImportPanel::CreatePanel() { - return new ImportPanel(_kiss, _wxUI); -} - -QPushButton* ImportPanel::GetButton() -{ - if (!_KissButton) - { - _KissButton = new QPushButton(QIcon(IMPORT_ICON), "", this); - _KissButton->setFixedSize(128, 128); - _KissButton->setIconSize(QSize(128, 128)); - } - - return _KissButton; + return new ImportPanel(_kiss, _wxUI, _lowResolution); } QString ImportPanel::GetToolTip() diff --git a/src/view/ImportPanel.hpp b/src/view/ImportPanel.hpp index a41a79f..f9ba797 100644 --- a/src/view/ImportPanel.hpp +++ b/src/view/ImportPanel.hpp @@ -33,10 +33,9 @@ class ImportPanel: public KissPanel Q_OBJECT; public: - ImportPanel(KissCount* kiss, wxUI *parent); + ImportPanel(KissCount* kiss, wxUI *parent, bool lowResolution); KissPanel* CreatePanel(); - QPushButton* GetButton(); QString GetToolTip(); void OnShow(); diff --git a/src/view/PreferencesPanel.cpp b/src/view/PreferencesPanel.cpp index 6ca86c7..7dd2fe8 100644 --- a/src/view/PreferencesPanel.cpp +++ b/src/view/PreferencesPanel.cpp @@ -26,7 +26,7 @@ enum {ACCOUNT_NAME, ACCOUNT_NUMBER, ACCOUNT_DEFAULT, ACCOUNT_VIRTUAL, ACCOUNT_BLOCKED, ACCOUNT_DELETE, ACCOUNT_HIDDEN, NUMBER_COLS_ACCOUNT}; enum {CATEGORY_NAME, CATEGORY_BACKGROUND_COLOR, CATEGORY_FOREGROUND_COLOR, CATEGORY_FONT, CATEGORY_DELETE, NUMBER_COLS_CATEGORY}; -PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _sharedWith(0), _curAccountRow(-1), _defaultSignalMapper(this), _virtualSignalMapper(this), _blockedSignalMapper(this), _deleteAccountSignalMapper(this), _deleteCategorySignalMapper(this), _backgroundColorSignalMapper(this), _foregroundColorSignalMapper(this), _fontSignalMapper(this), _inModification(false) +PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : KissPanel(kiss, parent, lowResolution), _sharedWith(0), _curAccountRow(-1), _defaultSignalMapper(this), _virtualSignalMapper(this), _blockedSignalMapper(this), _deleteAccountSignalMapper(this), _deleteCategorySignalMapper(this), _backgroundColorSignalMapper(this), _foregroundColorSignalMapper(this), _fontSignalMapper(this), _inModification(false) { QVBoxLayout *vbox = new QVBoxLayout; QHBoxLayout *hbox1 = new QHBoxLayout; @@ -41,6 +41,9 @@ PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : KissPanel(ki std::list users; std::list::iterator it; + _icons[KissPanel::LOW_RES_ICON] = PREFS_LOW_ICON; + _icons[KissPanel::HIGH_RES_ICON] = PREFS_ICON; + setLayout(vbox); staticUser = new QGroupBox(_("User")); @@ -183,19 +186,7 @@ PreferencesPanel::PreferencesPanel(KissCount* kiss, wxUI *parent) : KissPanel(ki KissPanel* PreferencesPanel::CreatePanel() { - return new PreferencesPanel(_kiss, _wxUI); -} - -QPushButton* PreferencesPanel::GetButton() -{ - if (!_KissButton) - { - _KissButton = new QPushButton(QIcon(PREFS_ICON), "", this); - _KissButton->setFixedSize(128, 128); - _KissButton->setIconSize(QSize(128, 128)); - } - - return _KissButton; + return new PreferencesPanel(_kiss, _wxUI, _lowResolution); } QString PreferencesPanel::GetToolTip() diff --git a/src/view/PreferencesPanel.hpp b/src/view/PreferencesPanel.hpp index 81fd351..3a25569 100644 --- a/src/view/PreferencesPanel.hpp +++ b/src/view/PreferencesPanel.hpp @@ -31,10 +31,9 @@ class PreferencesPanel: public KissPanel Q_OBJECT; public: - PreferencesPanel(KissCount* kiss, wxUI *parent); + PreferencesPanel(KissCount* kiss, wxUI *parent, bool lowResolution); KissPanel* CreatePanel(); - QPushButton* GetButton(); QString GetToolTip(); void OnShow(); diff --git a/src/view/SearchPanel.cpp b/src/view/SearchPanel.cpp index bd0ad24..ca9033b 100644 --- a/src/view/SearchPanel.cpp +++ b/src/view/SearchPanel.cpp @@ -19,7 +19,8 @@ #include "SearchPanel.hpp" -SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _operations(0) +SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : + KissPanel(kiss, parent, lowResolution), _operations(0) { DEFAULT_FONT(font); std::vector::iterator accountIt; @@ -29,6 +30,9 @@ SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent QVBoxLayout *vbox2 = new QVBoxLayout; QHBoxLayout *hbox = new QHBoxLayout; + _icons[KissPanel::LOW_RES_ICON] = SEARCH_LOW_ICON; + _icons[KissPanel::HIGH_RES_ICON] = SEARCH_ICON; + setLayout(vbox); _searchButton = new QPushButton(_("Search")); @@ -67,19 +71,7 @@ SearchPanel::~SearchPanel() KissPanel* SearchPanel::CreatePanel() { - return new SearchPanel(_kiss, _wxUI); -} - -QPushButton* SearchPanel::GetButton() -{ - if (!_KissButton) - { - _KissButton = new QPushButton(QIcon(SEARCH_ICON), "", this); - _KissButton->setFixedSize(128, 128); - _KissButton->setIconSize(QSize(128, 128)); - } - - return _KissButton; + return new SearchPanel(_kiss, _wxUI, _lowResolution); } QString SearchPanel::GetToolTip() diff --git a/src/view/SearchPanel.hpp b/src/view/SearchPanel.hpp index 73df426..b7bd531 100644 --- a/src/view/SearchPanel.hpp +++ b/src/view/SearchPanel.hpp @@ -36,11 +36,10 @@ class SearchPanel: public KissPanel Q_OBJECT; public: - SearchPanel(KissCount* kiss, wxUI *parent); + SearchPanel(KissCount* kiss, wxUI *parent, bool lowResolution); ~SearchPanel(); KissPanel* CreatePanel(); - QPushButton* GetButton(); QString GetToolTip(); void OnShow(); diff --git a/src/view/StatsPanel.cpp b/src/view/StatsPanel.cpp index a3a27f5..a9b3dae 100644 --- a/src/view/StatsPanel.cpp +++ b/src/view/StatsPanel.cpp @@ -25,7 +25,8 @@ #include "StatsPanel.hpp" -StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), _plot(0) +StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : + KissPanel(kiss, parent, lowResolution), _plot(0) { QHBoxLayout *hbox = new QHBoxLayout(); QVBoxLayout *vbox = new QVBoxLayout(); @@ -41,6 +42,9 @@ StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), int nbCategories; QListWidgetItem* item; + _icons[KissPanel::LOW_RES_ICON] = STATS_LOW_ICON; + _icons[KissPanel::HIGH_RES_ICON] = STATS_ICON; + setLayout(vbox); _monthFrom = new QComboBox(parent); @@ -195,19 +199,7 @@ StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent), KissPanel* StatsPanel::CreatePanel() { - return new StatsPanel(_kiss, _wxUI); -} - -QPushButton* StatsPanel::GetButton() -{ - if (!_KissButton) - { - _KissButton = new QPushButton(QIcon(STATS_ICON), "", this); - _KissButton->setFixedSize(128, 128); - _KissButton->setIconSize(QSize(128, 128)); - } - - return _KissButton; + return new StatsPanel(_kiss, _wxUI, _lowResolution); } QString StatsPanel::GetToolTip() diff --git a/src/view/StatsPanel.hpp b/src/view/StatsPanel.hpp index 8a7b03f..ffa418b 100644 --- a/src/view/StatsPanel.hpp +++ b/src/view/StatsPanel.hpp @@ -31,10 +31,9 @@ class StatsPanel: public KissPanel Q_OBJECT; public: - StatsPanel(KissCount* kiss, wxUI *parent); + StatsPanel(KissCount* kiss, wxUI *parent, bool lowResolution); KissPanel* CreatePanel(); - QPushButton* GetButton(); QString GetToolTip(); void OnShow(); diff --git a/src/view/view.hpp b/src/view/view.hpp index 24d0ff6..b59dd70 100644 --- a/src/view/view.hpp +++ b/src/view/view.hpp @@ -34,6 +34,7 @@ namespace view { #define DELETE_ICON RESSOURCES_ROOT "icons/delete.png" #define CHECKED_ICON RESSOURCES_ROOT "icons/check.png" + #define USER_ICON RESSOURCES_ROOT "icons/user.png" #define STATS_ICON RESSOURCES_ROOT "icons/charts.png" #define SEARCH_ICON RESSOURCES_ROOT "icons/search.png" @@ -44,6 +45,16 @@ namespace view { #define ABOUT_ICON RESSOURCES_ROOT "icons/about.png" #define QUIT_ICON RESSOURCES_ROOT "icons/exit.png" +#define USER_LOW_ICON RESSOURCES_ROOT "icons/user_low.png" +#define STATS_LOW_ICON RESSOURCES_ROOT "icons/charts_low.png" +#define SEARCH_LOW_ICON RESSOURCES_ROOT "icons/search_low.png" +#define PREFS_LOW_ICON RESSOURCES_ROOT "icons/preferences_low.png" +#define IMPORT_LOW_ICON RESSOURCES_ROOT "icons/import_low.png" +#define EXPORT_LOW_ICON RESSOURCES_ROOT "icons/export_low.png" +#define CHANGE_USER_LOW_ICON RESSOURCES_ROOT "icons/switch_user_low.png" +#define ABOUT_LOW_ICON RESSOURCES_ROOT "icons/about_low.png" +#define QUIT_LOW_ICON RESSOURCES_ROOT "icons/exit_low.png" + #define LANG_ROOT RESSOURCES_ROOT "po/" #endif diff --git a/src/view/wxUI.cpp b/src/view/wxUI.cpp index 2d50647..41ff229 100644 --- a/src/view/wxUI.cpp +++ b/src/view/wxUI.cpp @@ -31,6 +31,8 @@ #include "UsersDialog.hpp" +#include + QString wxUI::months[12] ; QColor wxUI::categoryColors[MAX_CATEGORY] = {QColor(0x00, 0x45, 0x86), QColor(0xFF, 0x3E, 0x0E), @@ -51,6 +53,11 @@ wxUI::wxUI(KissCount* kiss, const QString& title) _needReload(false) { QPushButton* button; + QDesktopWidget desk; + bool lowRes; + int w; + + lowRes = (desk.availableGeometry().width() <= 1024); SetLanguage(""); @@ -61,21 +68,23 @@ wxUI::wxUI(KissCount* kiss, const QString& title) _vbox = new QVBoxLayout; _buttonsBox = new QHBoxLayout; - button = new QPushButton(QIcon(CHANGE_USER_ICON), "", this); - button->setFixedSize(128, 128); - button->setIconSize(QSize(128, 128)); + w = (lowRes) ? 64 : 128; + + button = new QPushButton(QIcon(lowRes ? CHANGE_USER_LOW_ICON : CHANGE_USER_ICON), "", this); + button->setFixedSize(w, w); + button->setIconSize(QSize(w, w)); connect(button, SIGNAL(clicked()), this, SLOT(OnButtonChangeUser())); _buttonsBox->addWidget(button); - button = new QPushButton(QIcon(ABOUT_ICON), "", this); - button->setFixedSize(128, 128); - button->setIconSize(QSize(128, 128)); + button = new QPushButton(QIcon(lowRes ? ABOUT_LOW_ICON : ABOUT_ICON), "", this); + button->setFixedSize(w, w); + button->setIconSize(QSize(w, w)); connect(button, SIGNAL(clicked()), this, SLOT(OnButtonAbout())); _buttonsBox->addWidget(button); - button = new QPushButton(QIcon(QUIT_ICON), "", this); - button->setFixedSize(128, 128); - button->setIconSize(QSize(128, 128)); + button = new QPushButton(QIcon(lowRes ? QUIT_LOW_ICON : QUIT_ICON), "", this); + button->setFixedSize(w, w); + button->setIconSize(QSize(w, w)); connect(button, SIGNAL(clicked()), this, SLOT(OnButtonQuit())); _buttonsBox->addWidget(button); @@ -169,14 +178,14 @@ bool wxUI::SetLanguage(QString language) } #define ADD_PANEL(panelName) \ - panel = new panelName(_kiss, this); \ + panel = new panelName(_kiss, this, lowRes); \ button = panel->GetButton(); \ button->setToolTip(panel->GetToolTip()); \ _buttonsBox->insertWidget(id, button); \ _buttons.insert(_buttons.begin()+id, button); \ _panels.push_back(panel); \ _signalMapper.setMapping(button, id); \ - connect(button, SIGNAL(clicked()), &_signalMapper, SLOT(map())); \ + connect(button, SIGNAL(clicked()), &_signalMapper, SLOT(map())); \ id++; void wxUI::InitPanels() @@ -185,6 +194,10 @@ void wxUI::InitPanels() QPushButton* button; _panels.clear(); int id=0; + QDesktopWidget desk; + bool lowRes; + + lowRes = (desk.availableGeometry().width() <= 1024); ADD_PANEL(AccountPanel); ADD_PANEL(StatsPanel); diff --git a/src/view/wxUI.hpp b/src/view/wxUI.hpp index 1b77956..609c290 100644 --- a/src/view/wxUI.hpp +++ b/src/view/wxUI.hpp @@ -105,7 +105,7 @@ private: class KissPanel: public QFrame { public: - KissPanel(KissCount* kiss, wxUI* parent) : + KissPanel(KissCount* kiss, wxUI* parent, bool lowResolution=false) : QFrame(static_cast(parent)), _kiss(kiss), _wxUI(parent), @@ -114,17 +114,37 @@ public: DEFAULT_FONT(font); hide(); setFont(font); + _lowResolution = lowResolution; } virtual void OnShow()=0; virtual KissPanel* CreatePanel()=0; - virtual QPushButton* GetButton() {return 0;} + virtual QPushButton* GetButton() {return createButton();} virtual QString GetToolTip() {return "";} protected: KissCount* _kiss; wxUI* _wxUI; QPushButton* _KissButton; + bool _lowResolution; + enum {LOW_RES_ICON=0, HIGH_RES_ICON, NB_ICONS}; + QString _icons[NB_ICONS]; + + QPushButton* createButton() + { + int w; + + if (!_KissButton) + { + w = (_lowResolution) ? 64 : 128; + _KissButton = new QPushButton(QIcon(_icons[(_lowResolution) ? LOW_RES_ICON : HIGH_RES_ICON]), "", this); + _KissButton->setFixedSize(w, w); + _KissButton->setIconSize(QSize(w, w)); + } + + return _KissButton; + } + }; #endif From 5b8b17cbea2ed68ca6a2cfda20df556c06f61e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Fri, 29 Jun 2012 20:34:06 +0200 Subject: [PATCH 06/23] Add low icons --- ressources/icons/about_low.png | Bin 0 -> 4774 bytes ressources/icons/charts_low.png | Bin 0 -> 5145 bytes ressources/icons/exit_low.png | Bin 0 -> 4953 bytes ressources/icons/export_low.png | Bin 0 -> 6727 bytes ressources/icons/import_low.png | Bin 0 -> 6020 bytes ressources/icons/preferences_low.png | Bin 0 -> 6959 bytes ressources/icons/search_low.png | Bin 0 -> 5434 bytes ressources/icons/switch_user_low.png | Bin 0 -> 4558 bytes ressources/icons/user_low.png | Bin 0 -> 3984 bytes 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 ressources/icons/about_low.png create mode 100644 ressources/icons/charts_low.png create mode 100644 ressources/icons/exit_low.png create mode 100644 ressources/icons/export_low.png create mode 100644 ressources/icons/import_low.png create mode 100644 ressources/icons/preferences_low.png create mode 100644 ressources/icons/search_low.png create mode 100644 ressources/icons/switch_user_low.png create mode 100644 ressources/icons/user_low.png diff --git a/ressources/icons/about_low.png b/ressources/icons/about_low.png new file mode 100644 index 0000000000000000000000000000000000000000..cab7bab585be30f839ac63100565722703c18f38 GIT binary patch literal 4774 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 Hu0mjfPs=UG literal 0 HcmV?d00001 diff --git a/ressources/icons/exit_low.png b/ressources/icons/exit_low.png new file mode 100644 index 0000000000000000000000000000000000000000..5fbcbe74c6b9677254619d36bca7637f4a80ab1e GIT binary patch literal 4953 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 X0vFem$98|J00000NkvXXu0mjf+J#`d literal 0 HcmV?d00001 diff --git a/ressources/icons/export_low.png b/ressources/icons/export_low.png new file mode 100644 index 0000000000000000000000000000000000000000..e70346ed48ad52ff0b6c1bd009fb532088f4b879 GIT binary patch literal 6727 zcmWky2O!j696#%9PDy9a~d++=Gtak~R+q$ewJWLP>gjHWp8w;M*{yrF>;I~iDOKtE(<%8AL zgjA36eFy(QZExvnL(cx*i#uMVgDZ@ldJlad5Z;=<4=PKZG(K>V-dEr7CjA#E|2ZbX zpO%IG5C}I>UmIoY^mRQbD1&c0ovJ`XWAtKHAbUI=YMl zdG-D8cEOWsUDDFmwlH6R`E#`PMDfJ2k4gmW?v(Gee;9dlFJ#aEF~gbOY-ZPX_I@V2 z)eTy$TPJ^LRBpGE_b6xZV%fGGqtvL-zG5$tgU34+W}T##-Rz6+91EY23nMzn#iZch zcQ8*5eYQgOnpc{=-7Bi$LxPWFyV4ugw$!(nJ9f#3ab&&CL*zk!n*4!3k(}|#OdykY z^JMVsG=>nk_m!+eobRMT!H>V!1ba9AuxQFtMbuT?h+3+Vb^ZA@l9lWp= zMy*P@Ioo)!d0d(Dim)OXz{(!l*N3f$4Lj&&ds0}V_fD`K4EEZ6(Y2R|+Pz0o|Fy|S zI{HlsT`I-o>7daJ!V)ZWy%@~gcCF8jhRy)P$k-?FG=>3cW(zy9Qq$~XK) z(Wzq5kuVJj2;xE+26hfc?R07&obj}bR!XINqY9z1FNWOgIvu!MQ}art@XzhNV5&$pg+!&KEXv=s)F&Sb(pR$D{AQP|88gtqD<7)Qu$2KlL{?bHy)=WaL7 zeD1xP@;Y-A5EEgm_8Q35!TZ3xCDJj#-%be?7Cy*FwCoT`2Dp3tux{vMBUg3&jcB%cv-Bi=Z=FbD3 z8RIiVX57QsH%)Fun3cwboq6a_D#T;nmdVW*Qsx!{zTVmmJZUS~xu%}ZXJuldA(A$q ziC%f!xv9Pu@b!XpEgG#4fu-dCPC7ef={zA9mhk#nr5HG}*}MeI?KiW|v^Au=^i|nK z$P=a@u?VSas?My6cq}QTiKz9U1oDMRr^ud7GiRU&^w1S~8+RngdzqAgB2PZYGRqn= zGo+Am;%lrP_*=qn;|sTJ_V8GoP4i>I7&T;6Nq!Jh{dp#I@?zDEwvwPiwE=*3!4|8esTvsC3EV;(d* zB0Pgy9-0H~!6BtCRGP@#$5c(*d}4E9jS-rXKi-Y&dHK+jkYU0NAB2BzJ#Cwto3lDd z5LLT+bthXhKCC3;-+yWz;W_MBa($VsPA6-YDy>d<+)r0hgbO#QNDA;+#yPoSUMS04 zxC49~N0V2Mnp9*-ijs#yBcrJ^A}3* z<)C&5yk@O9zT~XHM_>K8bYaG6Rk@f``N+H3iy}UCkw;Of5&zH8Bm=>mu>c|=96g0Q zSwmNhOuJkF{pg6GM{V6C@1eAP<+aK(

5Te3oXm*Vsj;b9;^xWkug+8R5cBACEIK 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 a&zK)*-n(_ENM!{9H~pKpwW~F)BmW2Sy0+{9 literal 0 HcmV?d00001 diff --git a/ressources/icons/import_low.png b/ressources/icons/import_low.png new file mode 100644 index 0000000000000000000000000000000000000000..87fdb08d1caa2cdf458e5b14bae4f2a80edc70a1 GIT binary patch literal 6020 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 literal 0 HcmV?d00001 diff --git a/ressources/icons/search_low.png b/ressources/icons/search_low.png new file mode 100644 index 0000000000000000000000000000000000000000..d0a7fe8a5837e72439b01be97243a57e5c9a248a GIT binary patch literal 5434 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 literal 0 HcmV?d00001 diff --git a/ressources/icons/switch_user_low.png b/ressources/icons/switch_user_low.png new file mode 100644 index 0000000000000000000000000000000000000000..919cd8ca8dc701f4bc77056ea66bfeae7e40742c GIT binary patch literal 4558 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 Date: Fri, 3 Aug 2012 20:59:21 +0200 Subject: [PATCH 07/23] Retrive french.po --- ressources/po/french.po | 1012 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1012 insertions(+) create mode 100644 ressources/po/french.po diff --git a/ressources/po/french.po b/ressources/po/french.po new file mode 100644 index 0000000..5659885 --- /dev/null +++ b/ressources/po/french.po @@ -0,0 +1,1012 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-08-03 20:57+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: Soutadé \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: French\n" +"X-Poedit-Country: FRANCE\n" +"X-Poedit-SourceCharset: utf-8\n" + +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#: src/view/StatsPanel.cpp:408 +msgid " - " +msgstr " - " + +#: src/view/PreferencesPanel.cpp:1155 +msgid " ?" +msgstr " ?" + +#: src/view/UsersDialog.cpp:123 +#: src/view/PreferencesPanel.cpp:859 +#: src/view/PreferencesPanel.cpp:869 +#: src/view/PreferencesPanel.cpp:892 +#: src/view/PreferencesPanel.cpp:1034 +#: src/view/PreferencesPanel.cpp:1056 +#: src/view/PreferencesPanel.cpp:1099 +msgid " already exists" +msgstr " existe déjà" + +#: src/view/ImportPanel.cpp:274 +msgid " and " +msgstr " et " + +#: src/view/SnapshotsDialog.cpp:133 +#: src/view/SnapshotsDialog.cpp:167 +msgid " does not exist" +msgstr " n'existe pas" + +#: src/view/SearchPanel.cpp:96 +#: src/view/ExportPanel.cpp:90 +msgid " entries found" +msgstr " entrées trouvées" + +#: src/view/ImportPanel.cpp:296 +#: src/view/ImportPanel.cpp:320 +msgid " must have a name" +msgstr " doit avoir un nom" + +#: src/model/Database.cpp:99 +msgid " not found, aborting" +msgstr " non trouvé, arrêt" + +#: src/view/AccountPanel.cpp:933 +msgid " operations ?" +msgstr " opérations ?" + +#: src/view/SnapshotsDialog.cpp:113 +msgid " successfully created" +msgstr " crée" + +#: src/view/SnapshotsDialog.cpp:146 +msgid " successfully removed" +msgstr " supprimé" + +#: src/view/ImportPanel.cpp:280 +msgid " will be created, is it ok ?" +msgstr " vont être créés, êtes vous d'accord ?" + +#: src/view/ImportPanel.cpp:273 +#, c-format +msgid "%d accounts" +msgstr "%d comptes" + +#: src/view/ImportPanel.cpp:278 +#, c-format +msgid "%d categories" +msgstr "%d catégories" + +#: src/view/StatsPanel.cpp:352 +msgid "0 line" +msgstr "Limite 0" + +#: src/view/SearchPanel.cpp:98 +#: src/view/ExportPanel.cpp:92 +msgid "1 entry found" +msgstr "1 entrée trouvée" + +#: src/model/Database.cpp:93 +msgid "A new database will be created, continue ?" +msgstr "Une nouvelle base de données va être crée, continuer ?" + +#: src/view/SearchBanner.cpp:98 +#: src/view/grid/GridAccount.cpp:73 +msgid "Account" +msgstr "Compte" + +#: src/view/ImportPanel.cpp:296 +#: src/view/PreferencesPanel.cpp:869 +#: src/view/PreferencesPanel.cpp:892 +msgid "Account " +msgstr "Le compte " + +#: src/controller/KissCount.cpp:341 +msgid "Account 1" +msgstr "Compte 1" + +#: src/view/PreferencesPanel.cpp:859 +msgid "Account must have a name" +msgstr "Le compte doit avoir un nom" + +#: src/view/ImportPanel.cpp:68 +#: src/view/AccountPanel.cpp:499 +msgid "Account name" +msgstr "Nom du compte" + +#: src/view/AccountPanel.cpp:498 +msgid "Account number" +msgstr "Numéro de compte" + +#: src/view/StatsPanel.cpp:351 +#: src/view/PreferencesPanel.cpp:50 +msgid "Accounts" +msgstr "Comptes" + +#: src/view/AccountPanel.cpp:1165 +msgid "Accounts updated until " +msgstr "Comptes mis à jours jusqu'à " + +#: src/view/StatsPanel.cpp:329 +msgid "Amount" +msgstr "Montant" + +#: src/view/SearchBanner.cpp:94 +msgid "Amount from" +msgstr "Montant min" + +#: src/view/SearchBanner.cpp:95 +msgid "Amount to" +msgstr "Montant max" + +#: src/view/AccountPanel.cpp:1170 +msgid "Any account updated !" +msgstr "Aucun compte mis à jour" + +#: src/view/ImportPanel.cpp:162 +#: src/view/ExportPanel.cpp:130 +msgid "Any engine can process this file !" +msgstr "Format de fichier non reconnu" + +#: src/view/SnapshotsDialog.cpp:171 +msgid "Are you sure want to come back to " +msgstr "êtes vous sûr de vouloir revenir à " + +#: src/view/SnapshotsDialog.cpp:137 +#: src/view/AccountPanel.cpp:928 +msgid "Are you sure want to delete " +msgstr "Etes vous sûr de vouloir supprimer " + +#: src/view/grid/GridAccount.cpp:793 +msgid "Are you sure want to delete : \n" +msgstr "Etes vous sûr de vouloir supprimer : \n" + +#: src/view/PreferencesPanel.cpp:1155 +msgid "Are you sure want to delete profil of " +msgstr "Etes vous sûr de vouloir supprimer le profil de " + +#: src/view/ImportPanel.cpp:368 +msgid "Are you sure want to integrate these operations ?" +msgstr "Etes vous sûr de vouloir intégreer ces opérations" + +#: src/view/PreferencesPanel.cpp:467 +msgid "Ascending" +msgstr "Croissant" + +#: src/view/SnapshotsDialog.cpp:43 +msgid "Back to this snapshot" +msgstr "Revenir à cette sauvegarde" + +#: src/view/PreferencesPanel.cpp:345 +msgid "Background color" +msgstr "Couleur d'arrière plan" + +#: src/view/AccountPanel.cpp:291 +msgid "Balance" +msgstr "Solde" + +#: src/view/PreferencesPanel.cpp:212 +msgid "Blocked" +msgstr "Bloqué" + +#: src/view/UsersDialog.cpp:50 +#: src/view/GenerateDialog.cpp:49 +#: src/view/PasswordDialog.cpp:50 +msgid "Cancel" +msgstr "Annuler" + +#: src/view/grid/GridAccount.cpp:1305 +#: src/view/grid/GridAccount.cpp:1318 +msgid "Cannot group these operations" +msgstr "Impossible de grouper ces opérations" + +#: src/view/grid/GridAccount.cpp:1449 +#: src/view/grid/GridAccount.cpp:1455 +msgid "Cannot ungroup these operations" +msgstr "Impossible de dégrouper ces opérations" + +#: src/model/DatabaseUpdate.cpp:94 +msgid "Cannot update database version 2 to version 3 because some columns needs to be deleted." +msgstr "Impossible de migrer d'une base de données en version 2 à une base de données en version 3 car certaines colones ont été supprimées" + +#: src/controller/KissCount.cpp:332 +msgid "Car" +msgstr "Voiture" + +#: src/view/PreferencesPanel.cpp:51 +msgid "Categories" +msgstr "Catégories" + +#: src/view/SearchBanner.cpp:96 +#: src/view/grid/GridAccount.cpp:73 +msgid "Category" +msgstr "Catégorie" + +#: src/view/ImportPanel.cpp:320 +#: src/view/PreferencesPanel.cpp:1034 +#: src/view/PreferencesPanel.cpp:1056 +msgid "Category " +msgstr "La catégorie " + +#: src/view/PreferencesPanel.cpp:1024 +msgid "Category must have a name" +msgstr "La catégorie doit avoir un nom" + +#: src/view/ImportPanel.cpp:75 +msgid "Category name" +msgstr "Catégorie" + +#: src/view/PreferencesPanel.cpp:68 +msgid "Change Name" +msgstr "Changer de nom" + +#: src/view/PreferencesPanel.cpp:69 +msgid "Change Password" +msgstr "Changer le mot de passe" + +#: src/view/SearchPanel.cpp:51 +msgid "Change account" +msgstr "Changer de compte" + +#: src/view/SearchPanel.cpp:52 +msgid "Change category" +msgstr "Changer la catégorie" + +#: src/view/PasswordDialog.cpp:30 +msgid "Change password" +msgstr "Changer le mot de passe" + +#: src/view/AccountPanel.cpp:164 +msgid "Check" +msgstr "Rapprochement" + +#: src/view/SearchBanner.cpp:77 +msgid "Checked" +msgstr "Rapprochée" + +#: src/view/ImportPanel.cpp:125 +msgid "Choose a database to open" +msgstr "Choisissez une base de données à ouvrir" + +#: src/view/SearchPanel.cpp:143 +msgid "Choose a new account" +msgstr "Nouveau compte" + +#: src/view/SearchPanel.cpp:183 +msgid "Choose a new category" +msgstr "Nouvelle catégorie" + +#: src/view/PasswordDialog.cpp:41 +msgid "Confirm password" +msgstr "Confirmer le mot de passe" + +#: src/view/StatsPanel.cpp:162 +#: src/view/AccountPanel.cpp:113 +msgid "Cost repartition" +msgstr "Répartition des coûts" + +#: src/view/SnapshotsDialog.cpp:41 +msgid "Create a snapshot" +msgstr "Faire une sauvegarde" + +#: src/view/ImportPanel.cpp:173 +#: src/view/ImportPanel.cpp:203 +#: src/view/ImportPanel.cpp:247 +#: src/view/ImportPanel.cpp:258 +#: src/view/ImportPanel.cpp:287 +#: src/view/ImportPanel.cpp:310 +msgid "Create one" +msgstr "En créer un" + +#: src/view/grid/GridAccount.cpp:73 +msgid "Credit" +msgstr "Crédit" + +#: src/view/AccountPanel.cpp:287 +msgid "Cur Credit" +msgstr "Cur Crédit" + +#: src/view/AccountPanel.cpp:288 +msgid "Cur Debit" +msgstr "Cur Débit" + +#: src/view/AccountPanel.cpp:501 +msgid "Current value" +msgstr "Valeur courante" + +#: src/view/grid/GridAccount.cpp:73 +msgid "Date" +msgstr "Date" + +#: src/view/SearchBanner.cpp:30 +msgid "Date from" +msgstr "Date min" + +#: src/view/SearchBanner.cpp:31 +msgid "Date to" +msgstr "Date max" + +#: src/view/StatsPanel.cpp:343 +msgid "Days" +msgstr "Jours" + +#: src/view/grid/GridAccount.cpp:73 +msgid "Debit" +msgstr "Débit" + +#: src/view/PreferencesPanel.cpp:210 +msgid "Default" +msgstr "Défaut" + +#: src/view/PreferencesPanel.cpp:665 +msgid "Default account cannot be hidden" +msgstr "Impossible de cacher le compte par défaut" + +#: src/view/PreferencesPanel.cpp:213 +#: src/view/PreferencesPanel.cpp:348 +#: src/view/AccountPanel.cpp:786 +msgid "Delete" +msgstr "Supprimer" + +#: src/view/SnapshotsDialog.cpp:42 +msgid "Delete a snapshot" +msgstr "Supprimer la sauvegarde" + +#: src/view/PreferencesPanel.cpp:468 +msgid "Descending" +msgstr "Décroissant" + +#: src/view/SearchBanner.cpp:93 +#: src/view/grid/GridAccount.cpp:73 +msgid "Description" +msgstr "Description" + +#: src/view/SearchPanel.cpp:220 +msgid "Enter a new description" +msgstr "Nouvelle description" + +#: src/view/StatsPanel.cpp:423 +#: src/view/UsersDialog.cpp:93 +#: src/view/UsersDialog.cpp:123 +#: src/view/SearchBanner.cpp:156 +#: src/view/SearchBanner.cpp:166 +#: src/view/SearchBanner.cpp:179 +#: src/view/SearchBanner.cpp:188 +#: src/view/SnapshotsDialog.cpp:117 +#: src/view/SnapshotsDialog.cpp:133 +#: src/view/SnapshotsDialog.cpp:142 +#: src/view/SnapshotsDialog.cpp:167 +#: src/view/SnapshotsDialog.cpp:176 +#: src/view/ImportPanel.cpp:162 +#: src/view/ImportPanel.cpp:296 +#: src/view/ImportPanel.cpp:320 +#: src/view/ExportPanel.cpp:117 +#: src/view/ExportPanel.cpp:130 +#: src/view/ExportPanel.cpp:137 +#: src/view/PreferencesPanel.cpp:592 +#: src/view/PreferencesPanel.cpp:665 +#: src/view/PreferencesPanel.cpp:859 +#: src/view/PreferencesPanel.cpp:869 +#: src/view/PreferencesPanel.cpp:892 +#: src/view/PreferencesPanel.cpp:1024 +#: src/view/PreferencesPanel.cpp:1034 +#: src/view/PreferencesPanel.cpp:1056 +#: src/view/PreferencesPanel.cpp:1093 +#: src/view/PreferencesPanel.cpp:1099 +#: src/view/PreferencesPanel.cpp:1141 +#: src/view/PasswordDialog.cpp:64 +#: src/view/PasswordDialog.cpp:70 +#: src/view/AccountPanel.cpp:924 +#: src/view/grid/GridAccount.cpp:1305 +#: src/view/grid/GridAccount.cpp:1318 +#: src/view/grid/GridAccount.cpp:1449 +#: src/view/grid/GridAccount.cpp:1455 +#: src/view/grid/FormulaDelegate.cpp:59 +#: src/model/Database.cpp:47 +#: src/model/Database.cpp:55 +#: src/model/Database.cpp:74 +#: src/model/Database.cpp:99 +#: src/model/Database.cpp:105 +#: src/model/Database.cpp:111 +#: src/model/Database.cpp:121 +#: src/model/Database.cpp:140 +#: src/model/Database.cpp:582 +#: src/model/Database.cpp:758 +#: src/model/Database.cpp:900 +#: src/model/Database.cpp:1720 +#: src/model/DatabaseUpdate.cpp:31 +#: src/model/DatabaseUpdate.cpp:164 +msgid "Error" +msgstr "Erreur" + +#: src/model/Database.cpp:140 +msgid "Error creating original database" +msgstr "Erreur durant la création de la base de données initiale" + +#: src/view/ExportPanel.cpp:51 +#: src/view/ExportPanel.cpp:73 +msgid "Export" +msgstr "Export" + +#: src/view/ExportPanel.cpp:137 +msgid "Failed to save operations" +msgstr "Erreur lors de la sauvegarde des opérations" + +#: src/view/ImportPanel.cpp:68 +msgid "File account" +msgstr "Compte du fichier" + +#: src/view/ImportPanel.cpp:75 +msgid "File category" +msgstr "Catégorie du fichier" + +#: src/view/AccountPanel.cpp:502 +msgid "Final value" +msgstr "Valeur finale" + +#: src/view/SearchBanner.cpp:73 +#: src/view/grid/GridAccount.cpp:360 +#: src/controller/KissCount.cpp:332 +msgid "Fix" +msgstr "Fixe" + +#: src/view/PreferencesPanel.cpp:347 +msgid "Font" +msgstr "Police" + +#: src/view/PreferencesPanel.cpp:346 +msgid "Foreground color" +msgstr "Couleur d'avant plan" + +#: src/view/StatsPanel.cpp:75 +msgid "From" +msgstr "De" + +#: src/view/GenerateDialog.cpp:36 +msgid "From " +msgstr "A partir de " + +#: src/view/GenerateDialog.cpp:33 +#: src/view/AccountPanel.cpp:783 +msgid "Generate month" +msgstr "Générer mois" + +#: src/model/import/GrisbiImportEngine.cpp:166 +msgid "Grisbi files (*.gsb)" +msgstr "Fichiers Grisbi (*.gsb)" + +#: src/controller/KissCount.cpp:332 +msgid "Groceries" +msgstr "Courses" + +#: src/view/AccountPanel.cpp:188 +msgid "Group" +msgstr "Grouper" + +#: src/view/PreferencesPanel.cpp:214 +msgid "Hidden" +msgstr "Caché" + +#: src/controller/KissCount.cpp:332 +msgid "Hobbies" +msgstr "Loisirs" + +#: src/view/ImportPanel.cpp:113 +msgid "Import" +msgstr "Import" + +#: src/view/AccountPanel.cpp:500 +msgid "Initial value" +msgstr "Valeur initiale" + +#: src/view/ImportPanel.cpp:51 +msgid "Integrate operations" +msgstr "Intégrer les opérations" + +#: src/view/ImportPanel.cpp:68 +msgid "Internal account" +msgstr "Compte interne" + +#: src/view/ImportPanel.cpp:75 +msgid "Internal category" +msgstr "Catégorie interne" + +#: src/view/SearchBanner.cpp:166 +msgid "Invalid amount from" +msgstr "Montant min invalide" + +#: src/view/SearchBanner.cpp:188 +msgid "Invalid amount range" +msgstr "Intervalle des montants invalide" + +#: src/view/SearchBanner.cpp:179 +msgid "Invalid amount to" +msgstr "Montant max invalide" + +#: src/view/SearchBanner.cpp:156 +msgid "Invalid date range" +msgstr "Intervalle de temps invalide" + +#: src/view/grid/FormulaDelegate.cpp:59 +msgid "Invalid formula !" +msgstr "Formule invalide !" + +#: src/view/PreferencesPanel.cpp:1093 +msgid "Invalid name !" +msgstr "Nom invalide !" + +#: src/view/PasswordDialog.cpp:64 +msgid "Invalid old password" +msgstr "Ancien mot de passe invalide" + +#: src/view/UsersDialog.cpp:93 +msgid "Invalid password" +msgstr "Mot de passe invalide" + +#: src/view/StatsPanel.cpp:423 +msgid "Invalide date range" +msgstr "Intervalle de temps invalide" + +#: src/view/PreferencesPanel.cpp:592 +msgid "It must be at least one account !" +msgstr "Il doit y avoir au moins un compte !" + +#: src/view/AccountPanel.cpp:924 +msgid "It must be at least one month !" +msgstr "Il doit rester au moins un mois" + +#: src/view/PreferencesPanel.cpp:70 +msgid "Kill me" +msgstr "Kill me" + +#: src/view/SearchPanel.cpp:96 +#: src/view/SearchPanel.cpp:98 +#: src/view/SearchPanel.cpp:101 +#: src/view/ExportPanel.cpp:90 +#: src/view/ExportPanel.cpp:92 +#: src/view/ExportPanel.cpp:95 +#: src/view/ExportPanel.cpp:135 +msgid "KissCount" +msgstr "KissCount" + +#: src/view/ExportPanel.cpp:143 +msgid "KissCount - Export" +msgstr "KissCount - Export" + +#: src/view/ImportPanel.cpp:118 +msgid "KissCount - Import" +msgstr "KissCount - Import" + +#: src/model/export/XMLExportEngine.cpp:34 +msgid "KissCount XML files (*.xml)" +msgstr "Fichiers KissCount xml (*.xml)" + +#: src/model/import/XMLImportEngine.cpp:32 +msgid "KissCount xml files (*.xml)" +msgstr "Fichiers KissCount xml (*.xml)" + +#: src/view/PreferencesPanel.cpp:52 +msgid "Language" +msgstr "Langue" + +#: src/view/PreferencesPanel.cpp:1141 +msgid "Language not changed" +msgstr "Langue non changée" + +#: src/view/PreferencesPanel.cpp:1138 +msgid "Language successfully changed, please go to another panel" +msgstr "Langue changée, allez sur un autre panneau pour rendre le changement effectif" + +#: src/view/wxUI.cpp:309 +msgid "Licenced under GNU GPL v3" +msgstr "Licence GNU GPL v3" + +#: src/view/ImportPanel.cpp:47 +msgid "Load operations" +msgstr "Charger les opérations" + +#: src/view/AccountPanel.cpp:160 +msgid "Mode" +msgstr "Mode" + +#: src/view/StatsPanel.cpp:340 +msgid "Months" +msgstr "Mois" + +#: src/view/PreferencesPanel.cpp:62 +#: src/view/PreferencesPanel.cpp:208 +#: src/view/PreferencesPanel.cpp:344 +msgid "Name" +msgstr "Nom" + +#: src/view/PreferencesPanel.cpp:1105 +msgid "Name changed" +msgstr "Nom changé" + +#: src/view/UsersDialog.cpp:51 +#: src/view/UsersDialog.cpp:114 +msgid "New User" +msgstr "Nouvel utilisateur" + +#: src/view/PasswordDialog.cpp:37 +msgid "New password" +msgstr "Nouveau mot de passe" + +#: src/view/SearchPanel.cpp:101 +#: src/view/ExportPanel.cpp:95 +msgid "No entry found" +msgstr "Pas d'entrée trouvée" + +#: src/view/ImportPanel.cpp:352 +msgid "No operation found into this file" +msgstr "Aucun opération trouvée dans ce fichier" + +#: src/view/ExportPanel.cpp:117 +msgid "No operation to save" +msgstr "Aucun opération à sauvegarder" + +#: src/view/StatsPanel.cpp:138 +#: src/view/SearchBanner.cpp:75 +#: src/view/AccountPanel.cpp:292 +msgid "Non fix" +msgstr "Courantes" + +#: src/view/SearchPanel.cpp:139 +#: src/view/SearchPanel.cpp:179 +#: src/view/PreferencesPanel.cpp:608 +#: src/view/PreferencesPanel.cpp:700 +msgid "None" +msgstr "Aucun" + +#: src/view/SearchBanner.cpp:79 +msgid "Not checked" +msgstr "Non rapprochée" + +#: src/view/PreferencesPanel.cpp:209 +msgid "Number" +msgstr "Numéro de compte" + +#: src/model/import/OFXImportEngine.cpp:144 +msgid "OFX files (*.ofx)" +msgstr "Fichiers OFX (*.ofx)" + +#: src/view/UsersDialog.cpp:49 +#: src/view/SnapshotsDialog.cpp:55 +#: src/view/GenerateDialog.cpp:48 +#: src/view/PasswordDialog.cpp:49 +msgid "OK" +msgstr "OK" + +#: src/view/PasswordDialog.cpp:33 +msgid "Old password" +msgstr "Ancien mot de passe" + +#: src/view/PreferencesPanel.cpp:53 +msgid "Operation order" +msgstr "Ordre des opérations" + +#: src/view/SearchBanner.cpp:97 +#: src/view/AccountPanel.cpp:246 +msgid "Operations" +msgstr "Opérations" + +#: src/view/ImportPanel.cpp:425 +msgid "Operations successfully imported" +msgstr "les opérations ont été importées avec succès" + +#: src/view/ExportPanel.cpp:135 +msgid "Operations successfuly saved" +msgstr "Opérations sauvegardées avec succès" + +#: src/controller/KissCount.cpp:333 +msgid "Other" +msgstr "Autres" + +#: src/view/UsersDialog.cpp:44 +msgid "Password " +msgstr "Mot de passe " + +#: src/view/PasswordDialog.cpp:76 +msgid "Password changed" +msgstr "Mot de passe changé" + +#: src/view/wxUI.cpp:309 +msgid "Personal accounting software" +msgstr "Logiciel de comptabilité personnelle" + +#: src/view/PasswordDialog.cpp:70 +msgid "Please retype new password" +msgstr "Re entrez le mot de passe" + +#: src/view/PreferencesPanel.cpp:194 +#: src/view/PreferencesPanel.cpp:1146 +msgid "Preferences" +msgstr "Préférences" + +#: src/view/wxUI.cpp:314 +msgid "Quit KissCount ?" +msgstr "Quitter KissCount ?" + +#: src/view/AccountPanel.cpp:163 +msgid "Real" +msgstr "Réel" + +#: src/view/SearchPanel.cpp:53 +msgid "Rename" +msgstr "Renommer" + +#: src/view/ExportPanel.cpp:121 +msgid "Save as" +msgstr "Sauvegarder sous" + +#: src/view/ImportPanel.cpp:55 +msgid "Save import patterns" +msgstr "Sauvegarder les motifs d'import" + +#: src/view/SearchPanel.cpp:38 +#: src/view/SearchPanel.cpp:79 +#: src/view/SearchPanel.cpp:230 +#: src/view/ExportPanel.cpp:38 +msgid "Search" +msgstr "Chercher" + +#: src/view/PreferencesPanel.cpp:54 +msgid "Shared with" +msgstr "Partagé avec" + +#: src/view/SnapshotsDialog.cpp:32 +#: src/view/AccountPanel.cpp:191 +msgid "Snapshots" +msgstr "Sauvegardes" + +#: src/view/StatsPanel.cpp:207 +#: src/view/StatsPanel.cpp:408 +msgid "Statistics" +msgstr "Statistiques" + +#: src/view/StatsPanel.cpp:80 +msgid "To" +msgstr "A" + +#: src/view/AccountPanel.cpp:266 +#: src/view/AccountPanel.cpp:289 +msgid "Total Credit" +msgstr "Total Crédit" + +#: src/view/AccountPanel.cpp:267 +#: src/view/AccountPanel.cpp:290 +msgid "Total Debit" +msgstr "Total Débit" + +#: src/view/AccountPanel.cpp:189 +msgid "UnGroup" +msgstr "Dégrouper" + +#: src/model/Database.cpp:105 +#: src/model/Database.cpp:111 +msgid "Unable to Create " +msgstr "Impossible de créer " + +#: src/view/SnapshotsDialog.cpp:117 +msgid "Unable to create " +msgstr "Impossible de créer " + +#: src/model/Database.cpp:121 +msgid "Unable to open Database" +msgstr "Impossible d'ouvrir la base de données" + +#: src/model/Database.cpp:47 +#: src/model/Database.cpp:55 +#: src/model/Database.cpp:74 +#: src/model/Database.cpp:1720 +msgid "Unable to open database" +msgstr "Impossible d'ouvrir la base de données" + +#: src/view/SnapshotsDialog.cpp:142 +#: src/view/SnapshotsDialog.cpp:176 +msgid "Unable to remove " +msgstr "Impossible de supprimer " + +#: src/model/DatabaseUpdate.cpp:164 +msgid "Unable to upgrade Database" +msgstr "Impossible de mettre à jour la base de données" + +#: src/controller/KissCount.cpp:333 +msgid "Unexpected" +msgstr "Exceptionnel" + +#: src/view/SearchBanner.cpp:63 +#: src/view/SearchBanner.cpp:84 +#: src/view/AccountPanel.cpp:650 +#: src/model/User.cpp:65 +#: src/model/User.cpp:83 +#: src/model/User.cpp:161 +msgid "Unknown" +msgstr "Inconnu" + +#: src/view/ImportPanel.cpp:33 +msgid "Unresolved accounts" +msgstr "Comptes non résolus" + +#: src/view/ImportPanel.cpp:34 +msgid "Unresolved categories" +msgstr "Catégories non résolues" + +#: src/model/Database.cpp:582 +#: src/model/Database.cpp:758 +#: src/model/Database.cpp:900 +msgid "Update failed !\n" +msgstr "La mise à jour à échouée !\n" + +#: src/view/AccountPanel.cpp:190 +msgid "Update next months" +msgstr "Mettre à jour mois suivants" + +#: src/view/PreferencesPanel.cpp:49 +msgid "User" +msgstr "Utilisateur" + +#: src/view/UsersDialog.cpp:40 +#: src/view/UsersDialog.cpp:123 +#: src/view/PreferencesPanel.cpp:1099 +msgid "User " +msgstr "Utilisateur " + +#: src/view/UsersDialog.cpp:35 +msgid "Users" +msgstr "Utilisateurs" + +#: src/view/PreferencesPanel.cpp:211 +#: src/view/AccountPanel.cpp:162 +msgid "Virtual" +msgstr "Virtuel" + +#: src/view/grid/GridAccount.cpp:1111 +msgid "Warning" +msgstr "Attention" + +#: src/view/SnapshotsDialog.cpp:193 +#: src/view/SnapshotsDialog.cpp:203 +msgid "Welcome back to " +msgstr "Bienvenue sur " + +#: src/view/PreferencesPanel.cpp:613 +msgid "Wich account will replace this one ?" +msgstr "Quel compte va remplacer celui-ci ?" + +#: src/view/PreferencesPanel.cpp:706 +msgid "Wich category will replace this one ?" +msgstr "Quelle catégorie va remplacer celle-ci" + +#: src/view/grid/GridAccount.cpp:1111 +msgid "You made a debit on a blocked account" +msgstr "Vous avez effectué une opération de débit sur un compte bloqué" + +#: src/view/wxUI.cpp:167 +msgid "april" +msgstr "avril" + +#: src/view/wxUI.cpp:171 +msgid "august" +msgstr "août" + +#: src/view/wxUI.cpp:175 +msgid "december" +msgstr "décembre" + +#: src/view/wxUI.cpp:165 +msgid "february" +msgstr "février" + +#: src/view/wxUI.cpp:164 +msgid "january" +msgstr "janvier" + +#: src/view/wxUI.cpp:170 +msgid "july" +msgstr "juillet" + +#: src/view/wxUI.cpp:169 +msgid "june" +msgstr "juin" + +#: src/view/wxUI.cpp:166 +msgid "march" +msgstr "mars" + +#: src/view/wxUI.cpp:168 +msgid "may" +msgstr "mai" + +#: src/view/wxUI.cpp:174 +msgid "november" +msgstr "novembre" + +#: src/view/wxUI.cpp:173 +msgid "october" +msgstr "octobre" + +#: src/view/wxUI.cpp:172 +msgid "september" +msgstr "septembre" + +#~ msgid "" +#~ "Personal accounting software\n" +#~ "\n" +#~ "http://indefero.soutade.fr/p/kisscount/\n" +#~ "\n" +#~ "Licenced under GNU GPL v3\n" +#~ "\n" +#~ "Copyright (C) 2010-2012 Grégory Soutadé" +#~ msgstr "" +#~ "Logiciel de comptabilité personnelle\n" +#~ "\n" +#~ "http://indefero.soutade.fr/p/kisscount/\n" +#~ "\n" +#~ "Licence GNU GPL v3\n" +#~ "\n" +#~ "Copyright (C) 2010-2012 Grégory Soutadé" + +#~ msgid " profil ?" +#~ msgstr " profil ?" + +#~ msgid "" +#~ "!! Warning !! If there was a bug, the old database will be suppressed !" +#~ msgstr "" +#~ "!! Attention !! S'il y a eu un bug, l'ancienne base de donnée va être " +#~ "supprimée !" + +#~ msgid "" +#~ "No database found, would you like to create a new one ?\n" +#~ "\n" +#~ msgstr "" +#~ "Aucune base de données trouvée, voulez vous en créer une nouvelle ?\n" +#~ "\n" + +#~ msgid "Serie 1" +#~ msgstr "Série 1" + +#~ msgid "To " +#~ msgstr "Vers " + +#~ msgid "XML files (*.xml)|*.xml" +#~ msgstr "Fichiers XML (*.xml)|*.xml" + +#~ msgid "Remains" +#~ msgstr "Restant" + +#~ msgid "Operating expense" +#~ msgstr "Fonctionnement" + +#~ msgid "Check mode" +#~ msgstr "Mode rapprochement" + +#~ msgid "Query failed !\n" +#~ msgstr "La requête a échouée !\n" + +#~ msgid "About" +#~ msgstr "A propos" + +#~ msgid "Change user" +#~ msgstr "Changer d'utilisateur" + +#~ msgid "Quit" +#~ msgstr "Quitter" + +#~ msgid "Both" +#~ msgstr "Les deux" + +#~ msgid "Color" +#~ msgstr "Couleur" + +#~ msgid "Fixe" +#~ msgstr "Fixe" From c685d4b3fb636345395cedff430b43ed77c5634b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Fri, 3 Aug 2012 21:08:20 +0200 Subject: [PATCH 08/23] Fix a bug : argc must be passed as a reference --- src/controller/KissCount.cpp | 2 +- src/controller/KissCount.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controller/KissCount.cpp b/src/controller/KissCount.cpp index 9d7222e..a9e0894 100644 --- a/src/controller/KissCount.cpp +++ b/src/controller/KissCount.cpp @@ -28,7 +28,7 @@ std::vector * KissCount::_importEngines; std::vector * KissCount::_exportEngines; -KissCount::KissCount(int argc, char** argv) : QApplication(argc, argv), _user(0) +KissCount::KissCount(int& argc, char** argv) : QApplication(argc, argv), _user(0) { QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8")); QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8")); diff --git a/src/controller/KissCount.hpp b/src/controller/KissCount.hpp index c206920..f7c8b88 100644 --- a/src/controller/KissCount.hpp +++ b/src/controller/KissCount.hpp @@ -56,7 +56,7 @@ class ExportEngine; class KissCount : public QApplication { public: - KissCount(int argc, char** argv); + KissCount(int& argc, char** argv); ~KissCount(); std::list GetUsers(); From d206d5b051e7933cf2cf1109bead74a9afa364d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Sat, 4 Aug 2012 15:01:21 +0200 Subject: [PATCH 09/23] Add TODO in Debian packaging, because it breaks autobuild --- tools/package.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/package.sh b/tools/package.sh index e2a947d..b8fdc6d 100755 --- a/tools/package.sh +++ b/tools/package.sh @@ -32,7 +32,7 @@ if [ -d "debian" ] ; then DEB_FILE="kisscount_${VERSION}-1_${ARCH}.deb" rm -rf "$DEB_DIR" "$DEB_FILE" mkdir "$DEB_DIR" -cp -r kc.1 kc debian README* ChangeLog AUTHORS COPYING ressources "$DEB_DIR" +cp -r kc.1 kc debian README* ChangeLog AUTHORS COPYING TODO ressources "$DEB_DIR" rm -rf "$DEB_DIR/ressources/po/*" cp -r ressources/po/*.qm "$DEB_DIR"/ressources/po/ # Copy only QM files cd "$DEB_DIR" From 3e89eb7279c60cbc21dd15c87b7a8d8a7c4909af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Sun, 16 Dec 2012 09:49:51 +0100 Subject: [PATCH 10/23] Sort categories with translated names --- lib/libkdchart/src/KDChartBackgroundAttributes.cpp | 10 +++++----- src/controller/KissCount.cpp | 4 ++++ src/model/Category.hpp | 4 +++- src/model/User.cpp | 7 +++++++ src/view/wxUI.cpp | 8 ++++++++ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/libkdchart/src/KDChartBackgroundAttributes.cpp b/lib/libkdchart/src/KDChartBackgroundAttributes.cpp index f9f1520..91d8b81 100644 --- a/lib/libkdchart/src/KDChartBackgroundAttributes.cpp +++ b/lib/libkdchart/src/KDChartBackgroundAttributes.cpp @@ -147,11 +147,11 @@ QPixmap BackgroundAttributes::pixmap() const QDebug operator<<(QDebug dbg, const KDChart::BackgroundAttributes& ba) { dbg << "KDChart::BackgroundAttributes(" - << "visible="<LoadUser(user) ; + if (_user) _wxUI->LoadUser(); } @@ -504,6 +505,9 @@ QFont KissCount::ExtractFont(QString strFont) weight = list[3].toInt(); faceName = list[4]; + (void) family; + (void) style; + return QFont(faceName, pointSize, weight); } diff --git a/src/model/Category.hpp b/src/model/Category.hpp index ead5511..6ed6099 100644 --- a/src/model/Category.hpp +++ b/src/model/Category.hpp @@ -23,6 +23,8 @@ #include #include +#include + struct Category { int id; @@ -38,7 +40,7 @@ struct Category if (cat1.fix_cost) return true; if (cat2.fix_cost) return false; - return cat1.name < cat2.name; + return QApplication::translate("", cat1.name.toStdString().c_str()) < QApplication::translate("", cat2.name.toStdString().c_str()); } bool operator == (int catId) diff --git a/src/model/User.cpp b/src/model/User.cpp index 76468f4..40f6792 100644 --- a/src/model/User.cpp +++ b/src/model/User.cpp @@ -35,6 +35,8 @@ User::~User() void User::InvalidateOperations() { std::map >* >::iterator it; + std::vector::iterator it2; + int i; for (it = _operations.begin(); it != _operations.end(); it++) { @@ -48,6 +50,11 @@ void User::InvalidateOperations() std::sort(_accounts.begin(), _accounts.end(), Account()); std::sort(_categories.begin(), _categories.end(), Category()); + + for (i=0, it2=_categories.begin(); it2 !=_categories.end(); it2++, i++) + { + _categoriesFonts[i] = KissCount::ExtractFont(it2->font); + } } Category User::GetCategory(int catId) diff --git a/src/view/wxUI.cpp b/src/view/wxUI.cpp index 41ff229..d9aee22 100644 --- a/src/view/wxUI.cpp +++ b/src/view/wxUI.cpp @@ -238,12 +238,20 @@ void wxUI::LoadPanels() void wxUI::LoadUser() { User* user = _kiss->GetUser(); + int i; if (user->_preferences["language"].size()) SetLanguage(user->GetLanguage()); else SetLanguage(SupportedLanguages::languages[0].name); + // Sort with translated names + std::sort(user->_categories.begin(), user->_categories.end(), Category()); + for (i=0; i < (int)user->_categories.size(); i++) + { + user->_categoriesFonts[i] = KissCount::ExtractFont(user->_categories[i].font); + } + LoadPanels(); if (_panels.size()) From 6a90c340d38c2328c3425ed3c770c84cf6fd7a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 27 Dec 2012 09:42:53 +0100 Subject: [PATCH 11/23] Update Changelog --- ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f53b387..09057f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ -v0.4 (29/06/2012) +v0.4 (16/12/2012) ** User ** Add icons for low resolution + Sort categories using translated names ** Dev ** Primitive handle of low resolutions From ba24fd4a9150d2ef2598310c741e11b63828e571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 27 Dec 2012 17:56:20 +0100 Subject: [PATCH 12/23] Rework GridAccount to be simpler, more modulable and more resitant to bugs --- TODO | 6 +- src/view/grid/GridAccount.cpp | 684 ++++++++++++++-------------------- src/view/grid/GridAccount.hpp | 12 +- 3 files changed, 299 insertions(+), 403 deletions(-) diff --git a/TODO b/TODO index e7d63b4..8b2adaf 100644 --- a/TODO +++ b/TODO @@ -29,13 +29,9 @@ Undo/redo =============================================================== BUGS -* When we broke a transfert into a meta operation and re create it, -it's not taken in account by UpdateStats - * If a sub operation is found using SearchPanel but not its parent it will not be displayed. In this case we must load whole meta. This bug can't be resolved without use of hashtable because of complexity in searching this issue. -* When changing date in a sub operation (set date > main date), -meta amount is set to 0 \ No newline at end of file +* After manipulating some meta operation, it withdrawn diff --git a/src/view/grid/GridAccount.cpp b/src/view/grid/GridAccount.cpp index af938e1..0cc2a98 100644 --- a/src/view/grid/GridAccount.cpp +++ b/src/view/grid/GridAccount.cpp @@ -177,13 +177,13 @@ void GridAccount::UpdateOperation(Operation& op) } } -int GridAccount::GetDisplayedRow(int id) +int GridAccount::GetDisplayedRow(int id) throw (OperationNotFound) { std::vector::iterator it = std::find(_displayedOperations.begin(), _displayedOperations.end(), id); if (it != _displayedOperations.end()) return it-_displayedOperations.begin(); - return -1; + throw OperationNotFound(); } void GridAccount::ClearGrid() @@ -347,7 +347,7 @@ void GridAccount::InsertOperation(User* user, Operation& op, int line, bool fix, // // First is header // if (op.id) - _displayedOperations.insert(_displayedOperations.begin()+line, op); + _displayedOperations.insert(_displayedOperations.begin()+line, op); if (!user->_accounts.size()) return; @@ -433,6 +433,7 @@ void GridAccount::InsertOperation(User* user, Operation& op, int line, bool fix, } else { + // NULL Op item = new QTableWidgetItem(""); setItem(line, DESCRIPTION, item); if (fix) @@ -498,16 +499,74 @@ void GridAccount::InsertOperation(User* user, Operation& op, int line, bool fix, _inModification = false; } -void GridAccount::DeleteOperation(const Operation& op) +void GridAccount::DeleteOperation(const Operation& op) throw (OperationNotFound) { std::vector::iterator it = std::find(_operations->begin(), _operations->end(), op.id); + std::vector::iterator it2; + Operation parent; - if (it != _operations->end()) _operations->erase(it); + User* user = _kiss->GetUser(); + + if (it == _operations->end()) + throw OperationNotFound(); + + if (it->parent) + user->UnGroup(*it); + + if (it != _operations->end()) + { + if (_databaseSynchronization) + _kiss->DeleteOperation(*it); + if (it->parent) + { + parent = GetOperation(it->parent); + it2 = std::find(parent.childs.begin(), parent.childs.end(), it->id); + + if (it2 != parent.childs.end()) + parent.childs.erase(it2); + } + _operations->erase(it); + } } -void GridAccount::InsertIntoGrid(Operation& op) +void GridAccount::RemoveRow(const Operation& op, int line, bool deleteOp) { - int i, a, start; + QPushButton* button = qobject_cast (cellWidget(line, TREE)); + + if (button) + button->disconnect(&_treeSignalMapper, SLOT(map())); + QCheckBox* checkBox = qobject_cast (cellWidget(line, CHECKED)); + if (checkBox) + checkBox->disconnect(&_checkSignalMapper, SLOT(map())); + checkBox = qobject_cast (cellWidget(line, OP_DELETE)); + if (checkBox) + checkBox->disconnect(&_deleteSignalMapper, SLOT(map())); + removeRow(line); + _displayedOperations.erase(_displayedOperations.begin()+line); + if (op.fix_cost) _fixCosts--; + if (deleteOp) + DeleteOperation(op); +} + +bool GridAccount::CheckDay(User* user, const Operation& op, int& i) +{ + if (user->_preferences["operation_order"] == "ASC") + { + if ((_displayedOperations)[i].day > op.day) + return true; + } + else + { + if ((_displayedOperations)[i].day < op.day) + return true; + } + + return false; +} + +int GridAccount::InsertIntoGrid(Operation& op) +{ + int i, a, start=0; User* user = _kiss->GetUser(); Operation parent; @@ -520,61 +579,81 @@ void GridAccount::InsertIntoGrid(Operation& op) else { if (op.parent) - start = GetDisplayedRow(op.parent); - else - start = 0; - - for(i=start; i<(int)_displayedOperations.size(); i++) { - if (!_displayedOperations[i].id) continue; - if (_displayedOperations[i].parent) continue; - if ((_displayedOperations)[i].fix_cost && !op.fix_cost) continue; - if (!(_displayedOperations)[i].fix_cost && op.fix_cost) break; - if (user->_preferences["operation_order"] == "ASC") + start = GetDisplayedRow(op.parent)+1; + for(i=start; i<(int)_displayedOperations.size(); i++) { - if ((_displayedOperations)[i].day > op.day) - break; + if (!_displayedOperations[i].parent) break; + if (_displayedOperations[i].id == 0) break; + if (CheckDay(user, op, i)) break; + } + } + else + { + if (op.fix_cost) + { + for(i=1; i<(int)_fixCosts; i++) + { + if (_displayedOperations[i].parent) continue; + if (_displayedOperations[i].id == 0) break; + if (CheckDay(user, op, i)) break; + } } else { - if ((_displayedOperations)[i].day < op.day) - break; + for(i=_fixCosts+1; i<(int)_displayedOperations.size()-1; i++) + { + if (_displayedOperations[i].parent) continue; + if (_displayedOperations[i].fix_cost) continue; + if (_displayedOperations[i].id == 0) break; + if (CheckDay(user, op, i)) break; + } } } - - if (op.parent) - { - if ((i-start) > (int)(parent.childs.size())) - i = start + parent.childs.size(); - if (parent.day >= op.day) - i = start + 1; - } - else if (i == (int)_displayedOperations.size() || - i == _fixCosts) - i--; - else if (!(_displayedOperations)[i].fix_cost && op.fix_cost) - i --; } for (a=0; a<(int)_operations->size(); a++) { if ((*_operations)[a].fix_cost && !op.fix_cost) continue; - if (!(*_operations)[a].fix_cost && op.fix_cost) - { - a--; - break; - } - if ((*_operations)[a].day > op.day) - { - a--; - break; - } + if (!(*_operations)[a].fix_cost && op.fix_cost) break; + if ((*_operations)[a].day > op.day) break; } - if (a < 0) a = 0; _operations->insert(_operations->begin()+a, op); - InsertOperationWithWeek(user, (*_operations)[a], i, op.fix_cost, _curMonth, _curYear); + InsertOperationWithWeek(user, op, i, op.fix_cost, _curMonth, _curYear); + + return i; +} + +void GridAccount::CheckOperation(Operation& op, int line, bool check, bool force) +{ + QColor color; + int r,g,b; + User* user = _kiss->GetUser(); + + if (!force) + { + if (op.checked == check) return; + + op.checked = check; + UpdateOperation(op); + + QCheckBox* checkBox = qobject_cast(cellWidget(line, CHECKED)); + if (checkBox) + checkBox->setCheckState(check ? Qt::Checked : Qt::Unchecked); + } + + color = user->GetCategory(op.category).backcolor; + + if (check) + { + r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; + g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; + b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; + color.setRgb(r, g, b); + } + SET_ROW_COLOR(line, color, user->GetCategory(op.category).forecolor); } int GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool deleteOp) @@ -588,23 +667,14 @@ int GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool delete { op2 = GetOperation(op.childs[i]); if (op2.meta) - RemoveMeta(op2, line+1, true, deleteOp); + deletedOperations += RemoveMeta(op2, line+1, true, deleteOp); else { if (button->text() == "-") - { - removeRow(line+1); - deletedOperations++; - if (op2.fix_cost) _fixCosts--; - _displayedOperations.erase(_displayedOperations.begin()+line+1); - } - - if (deleteOp) - { - DeleteOperation(op2); - if (_databaseSynchronization) - _kiss->DeleteOperation(op2); - } + { + RemoveRow(op2, line+1, deleteOp); + deletedOperations++; + } } } @@ -612,21 +682,8 @@ int GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool delete if (removeRoot) { - button->disconnect(&_treeSignalMapper, SLOT(map())); - QCheckBox* checkBox = qobject_cast (cellWidget(line, CHECKED)); - checkBox->disconnect(&_checkSignalMapper, SLOT(map())); - checkBox = qobject_cast (cellWidget(line, OP_DELETE)); - checkBox->disconnect(&_deleteSignalMapper, SLOT(map())); - removeRow(line); - _displayedOperations.erase(_displayedOperations.begin()+line); - if (op.fix_cost) _fixCosts--; - if (deleteOp) - { - DeleteOperation(op); - if (_databaseSynchronization) - _kiss->DeleteOperation(op); - } - deletedOperations++; + RemoveRow(op, line, deleteOp); + deletedOperations++; } return deletedOperations; @@ -634,41 +691,53 @@ int GridAccount::RemoveMeta(Operation op, int line, bool removeRoot, bool delete void GridAccount::CheckMeta(Operation& op, int line, bool check) { - int i, new_line; + int i; Operation op2; - QColor color ; - unsigned char r, g, b; - User* user = _kiss->GetUser(); - QPushButton* button = qobject_cast(cellWidget(line, TREE)); + CheckOperation(op, line, check, false); - for(i=0; i<(int)op.childs.size(); i++) + if (IsMetaOpened(op.id)) { - op2 = GetOperation(op.childs[i]); - op2.checked = check; - UpdateOperation(op2); + for(i=0; i<(int)op.childs.size(); i++) + { + op2 = GetOperation(op.childs[i]); - if (op2.meta) - CheckMeta(op2, line+1, check); - - if (button->text() == "-") - { - QCheckBox* checkBox = qobject_cast(cellWidget(line+i+1, CHECKED)); - checkBox->setCheckState(check ? Qt::Checked : Qt::Unchecked); - color = user->GetCategory(op2.category).backcolor; - - if (check) - { - r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; - g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; - b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; - color.setRgb(r, g, b); - } - - new_line = line+i+1; - SET_ROW_COLOR(new_line, color, user->GetCategory(op2.category).forecolor); - } + if (op2.meta) + CheckMeta(op2, line+i+1, check); + else + CheckOperation(op2, line+i+1, check, false); + } } + else + { + for(i=0; i<(int)op.childs.size(); i++) + { + op2 = GetOperation(op.childs[i]); + + if (op2.meta) + CheckMeta(op2, line+i+1, check); + else + { + op2.checked = check; + UpdateOperation(op2); + } + } + } +} + +bool GridAccount::IsMetaOpened(int id) +{ + int row = GetDisplayedRow(id); + + QPushButton* button = qobject_cast (cellWidget(row, TREE)); + + return (button->text() == QString("-")); +} + +void GridAccount::OpenMeta(const Operation& meta) +{ + if (!IsMetaOpened(meta.id)) + OnMetaClicked(meta.id); } void GridAccount::OnMetaClicked(int id) @@ -688,12 +757,12 @@ void GridAccount::OnMetaClicked(int id) row = it - _displayedOperations.begin(); - if (button->text() == "+") + if (button->text() == QString("+")) { for (i=1, it2=op.childs.begin(); it2!=op.childs.end(); it2++, i++) { op2 = GetOperation(*it2); - InsertOperationWithWeek(user, op2, row+i, op2.fix_cost, op2.month, op2.year); + InsertOperation(user, op2, row+i, op2.fix_cost, op2.month, op2.year); } button->setText("-"); } @@ -702,21 +771,20 @@ void GridAccount::OnMetaClicked(int id) RemoveMeta(op, row, false, false); button->setText("+"); } + + ComputeWeeks(); } void GridAccount::OnCheckClicked(int id) { std::vector::iterator it; + std::vector::iterator it2; int row; - Operation op2; - QColor color; - User* user = _kiss->GetUser(); - unsigned char r, g, b; + Operation op2, parent; + bool fullCheck = true; if (_inModification || _loadOperations) return; - QCheckBox* checkBox = qobject_cast (_checkSignalMapper.mapping(id)); - it = std::find(_displayedOperations.begin(), _displayedOperations.end(), id); if (it == _displayedOperations.end()) return ; @@ -724,45 +792,26 @@ void GridAccount::OnCheckClicked(int id) _inModification = true; row = it-_displayedOperations.begin(); - _displayedOperations[row].checked = (checkBox->checkState() == Qt::Checked); - color = user->GetCategory(it->category).backcolor; - - if (it->checked) - { - r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; - g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; - b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; - color.setRgb(r, g, b); - } - - SET_ROW_COLOR(row, color, user->GetCategory(it->category).forecolor); - SET_ROW_FONT(row, user->GetCategoryFont(it->category)); - - UpdateOperation(*it); if (it->meta) - CheckMeta(*it, row, it->checked); + CheckMeta(*it, row, !it->checked); else { + CheckOperation(*it, row, !it->checked, false); + if (it->parent) { - op2 = GetOperation(it->parent); - UpdateMeta(op2); - int row2 = GetDisplayedRow(op2.id); - QCheckBox* checkBox = qobject_cast(cellWidget(row2, CHECKED)); - checkBox->setCheckState(op2.checked ? Qt::Checked : Qt::Unchecked); - - color = user->GetCategory(op2.category).backcolor; - - if (op2.checked) + parent = GetOperation(it->parent); + for(it2=parent.childs.begin(); it2!=parent.childs.end(); it2++) { - r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; - g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; - b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; - color.setRgb(r, g, b); + op2 = GetOperation(*it2); + if (!op2.checked) + { + fullCheck = false; + break; + } } - - SET_ROW_COLOR(row2, color, user->GetCategory(op2.category).forecolor); + CheckOperation(parent, GetDisplayedRow(parent.id), fullCheck, false); } } @@ -773,12 +822,9 @@ void GridAccount::OnCheckClicked(int id) void GridAccount::OnDeleteClicked(int id) { std::vector::iterator it; - std::vector::iterator it2; - int row; + int row, parentRow; + Operation op, op2, parent; User* user = _kiss->GetUser(); - Operation op, op_tmp, op_tmp2; - QColor color; - unsigned char r, g, b; if (_inModification || _loadOperations) return; @@ -802,73 +848,35 @@ void GridAccount::OnDeleteClicked(int id) row = it-_displayedOperations.begin(); - if (op.parent) - user->UnGroup(_displayedOperations[row]); - if (op.meta) - RemoveMeta(_displayedOperations[row], row, true, true); + RemoveMeta(op, row, true, true); else { - if (op.parent) - { - op_tmp = GetOperation(op.parent); - it2 = std::find(op_tmp.childs.begin(), op_tmp.childs.end(), op.id); - if (it2 != op_tmp.childs.end()) - op_tmp.childs.erase(it2); - } - - removeRow(row); - DeleteOperation(*it); - if (_databaseSynchronization) - _kiss->DeleteOperation(*it); - _displayedOperations.erase(_displayedOperations.begin()+row); + RemoveRow(op, row, true); if (op.parent) { - if (op_tmp.childs.size() < 2) + user->UnGroup(op); + + parent = GetOperation(op.parent); + parentRow = GetDisplayedRow(parent.id); + + // One child remains + if (parent.childs.size() == 1) { - if (op_tmp.childs.size() == 1) - { - op_tmp2 = GetOperation(op_tmp.childs[0]); - op_tmp2.parent = 0; - UpdateOperation(op_tmp2); - row = GetDisplayedRow(op_tmp2.id); - _displayedOperations[row] = op_tmp2; - } - - row = GetDisplayedRow(op.parent); - removeRow(row); - DeleteOperation(op_tmp); - if (_databaseSynchronization) - _kiss->DeleteOperation(op_tmp); - _displayedOperations.erase(_displayedOperations.begin()+row); - if (op.fix_cost) - _fixCosts--; - setItem(row, DESCRIPTION, new QTableWidgetItem(op.description)); // Remove tabulation - color = user->GetCategory(op.category).backcolor; - - if (op.checked) - { - r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; - g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; - b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; - color.setRgb(r, g, b); - } - - SET_ROW_COLOR(row, color, user->GetCategory(op.category).forecolor); - SET_ROW_FONT(row, user->GetCategoryFont(op.category)); + op = GetOperation(parent.childs[0]); + user->UnGroup(op); + // Remove parent + RemoveRow(parent, parentRow, true); + // Remove child + op.parent = 0; + UpdateOperation(op); + RemoveRow(op, parentRow, false); + InsertIntoGrid(op); } else - { - UpdateMeta(op_tmp); - row = GetDisplayedRow(op_tmp.id); - RemoveMeta(op_tmp, row, true, false); - InsertIntoGrid(op_tmp); - } + UpdateMeta(parent); } - if (op.fix_cost) - _fixCosts--; - ComputeWeeks(); } _kiss->UpdateStats(); @@ -879,19 +887,17 @@ void GridAccount::OnOperationModified(int row, int col) { User* user = _kiss->GetUser(); Operation new_op, cur_op, op_tmp, op_tmp2; - int op_complete = 6, i, last_day; + int op_complete = 6; QString value, v ; QDate date; bool need_insertion = false, transfertCompleted = false; - QColor color ; - unsigned char r, g, b; std::vector::iterator it; - Operation op, op2; - int amount; + std::vector::iterator it2; + Operation op, op2, parent; QFont font; Category cat ; bool fix_cost; - QDate curDate = QDate::currentDate(); + Operation NULLop; // Avoid recursives calls if (_inModification || _loadOperations) return; @@ -1005,19 +1011,6 @@ void GridAccount::OnOperationModified(int row, int col) new_op.checked = false; op_complete--; - color = user->GetCategory(new_op.category).backcolor; - - if (new_op.checked) - { - r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; - g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; - b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; - color.setRgb(r, g, b); - } - - SET_ROW_COLOR(row, color, user->GetCategory(new_op.category).forecolor); - SET_ROW_FONT(row, user->GetCategoryFont(new_op.category)); - fix_cost = (row <= _fixCosts); // Modify an operation @@ -1033,20 +1026,32 @@ void GridAccount::OnOperationModified(int row, int col) new_op.childs = cur_op.childs; new_op._virtual = cur_op._virtual; + UpdateOperation(new_op); + if (cur_op.day != new_op.day) { - need_insertion = true; - removeRow(row); - if (fix_cost) - _fixCosts--; + // Remove from _operation without DeleteOperation to avoid commit into database + it2 = std::find(_operations->begin(), _operations->end(), new_op.id); + if (it2 != _operations->end()) + _operations->erase(it2); + need_insertion = true; + RemoveRow(new_op, row, false); + } + else + { + (_displayedOperations)[row] = new_op; + cat = user->GetCategory(new_op.category); + CheckOperation(new_op, row, new_op.checked, true); + SET_ROW_FONT(row, user->GetCategoryFont(cat.id)); } - - (_displayedOperations)[row] = new_op; - UpdateOperation(new_op); } // Add an operation else { + cat = user->GetCategory(new_op.category); + CheckOperation(new_op, row, new_op.checked, true); + SET_ROW_FONT(row, user->GetCategoryFont(cat.id)); + if (op_complete) { _inModification = false ; return ; @@ -1057,49 +1062,9 @@ void GridAccount::OnOperationModified(int row, int col) new_op._virtual = false; new_op.parent = 0; - for(i=0; iitem(row, DEBIT)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - this->item(row, CREDIT)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - this->item(row, OP_DELETE)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); - this->item(row, CHECKED)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); - - if (!fix_cost) - { - int day; - if (curDate.year() == _curYear) - { - if (curDate.month() > (_curMonth+1)) - day = QDate(_curYear, _curMonth+1, 1).daysInMonth(); - else if (curDate.month() < (_curMonth+1)) - day = 1; - else - day = curDate.day(); - - } - else if (curDate.year() > _curYear) - day = QDate(_curYear, _curMonth+1, 1).daysInMonth(); - else - day = 1; - setItem(row, OP_DATE, new QTableWidgetItem(_kiss->FormatDate(day, _curMonth+1, _curYear))); - this->item(row, OP_DATE)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); - } - DEFAULT_FONT(font); - - if (fix_cost) - { - SET_ROW_COLOR(row, view::OWN_YELLOW, Qt::black); - } - else - { - SET_ROW_COLOR(row, view::OWN_GREEN, Qt::black); - } - - SET_ROW_FONT(row, font); + RemoveRow(new_op, row, false); + NULLop.id = 0; + InsertOperation(user, NULLop, row, new_op.fix_cost, _curMonth, _curYear); new_op.id = _kiss->AddOperation(new_op); @@ -1115,101 +1080,8 @@ void GridAccount::OnOperationModified(int row, int col) if (new_op.parent) { - row = GetDisplayedRow(new_op.parent); - - last_day = new_op.day; - new_op = _displayedOperations[row]; - - it = std::find(new_op.childs.begin(), new_op.childs.end(), cur_op.id); - new_op.childs.erase(it); - - i = 0; - for(it = new_op.childs.begin(); it != new_op.childs.end(); it++) - { - op2 = GetOperation(*it); - if ((int)op2.day > last_day) break; - i++; - } - - new_op.childs.insert(new_op.childs.begin()+i, cur_op.id); - - last_day = new_op.day; - - UpdateMeta(new_op); - - _displayedOperations[row] = new_op; - - cat = user->GetCategory(new_op.category); - - if (new_op.category) - color = cat.backcolor; - else - color = view::OWN_GREEN; - - QCheckBox* checkBox = qobject_cast (_checkSignalMapper.mapping(new_op.id)); - if (new_op.checked) - { - r = ((color.red()*1.5) >= 0xFF) ? 0xFF : color.red()*1.5 ; - g = ((color.green()*1.5) >= 0xFF) ? 0xFF : color.green()*1.5 ; - b = ((color.blue()*1.5) >= 0xFF) ? 0xFF : color.blue()*1.5 ; - color.setRgb(r, g, b); - checkBox->setCheckState(Qt::Checked); - } - else - checkBox->setCheckState(Qt::Unchecked); - - setItem(row, OP_DATE, new QTableWidgetItem(_kiss->FormatDate(new_op.day+1, _curMonth+1, _curYear))); - - if (!_displayedOperations[row].amount) - { - amount = _kiss->MetaPositiveAmount(new_op.id); - - setItem(row, DEBIT, new QTableWidgetItem(v.sprintf("%.2lf", (double)amount/100))); - setItem(row, CREDIT, new QTableWidgetItem(v.sprintf("%.2lf", (double)amount/100))); - } - else - { - if (_displayedOperations[row].amount < 0) - { - setItem(row, DEBIT, new QTableWidgetItem(v.sprintf("%.2lf", (double)-new_op.amount/100))); - setItem(row, CREDIT, new QTableWidgetItem("")); - } - else - { - setItem(row, DEBIT, new QTableWidgetItem("")); - setItem(row, CREDIT, new QTableWidgetItem(v.sprintf("%.2lf", (double)new_op.amount/100))); - } - } - - this->item(row, OP_DATE)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter); - this->item(row, DEBIT)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - this->item(row, CREDIT)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - - SET_ROW_COLOR(row, color, cat.forecolor); - - if (new_op.category && cat.font.length()) - { - SET_ROW_FONT(row, user->GetCategoryFont(cat.id)); - } - - // Move updated meta - if ((int)new_op.day != last_day) - { - int i; - RemoveMeta(new_op, row, true, false); - InsertIntoGrid(new_op); - row = GetDisplayedRow(new_op.id); - for (i=1, it=new_op.childs.begin(); it!=new_op.childs.end(); it++, i++) - { - op2 = GetOperation(*it); - InsertOperationWithWeek(user, op2, row+i, op2.fix_cost, _curMonth, _curYear); - } - QPushButton* button = qobject_cast (cellWidget(row, TREE)); - if (button->text() == "+") - button->setText("-"); - else - button->setText("+"); - } + parent = GetOperation(new_op.parent); + UpdateMeta(parent); } _kiss->UpdateStats(); @@ -1219,20 +1091,24 @@ void GridAccount::OnOperationModified(int row, int col) void GridAccount::UpdateMeta(Operation& meta) { std::vector::iterator it; + std::vector::iterator it2; Operation op ; int category = 0; bool updateCat = false ; + bool openMeta; if (!meta.childs.size()) return ; + openMeta = IsMetaOpened(meta.id); + meta.category = 0; - meta.checked = true; meta.amount = 0; op = GetOperation(meta.childs[0]); meta.year = op.year; meta.month = op.month; meta.day = op.day; + meta.description = ""; for(it=meta.childs.begin(); it!=meta.childs.end(); it++) { @@ -1243,7 +1119,6 @@ void GridAccount::UpdateMeta(Operation& meta) meta.month = op.month; meta.day = op.day; } - meta.checked &= op.checked; if (!meta.description.length() && op.description.length()) meta.description = op.description; if (!category) @@ -1267,8 +1142,17 @@ void GridAccount::UpdateMeta(Operation& meta) meta.amount = _kiss->MetaAmount(meta.id); - if (_databaseSynchronization) - _kiss->UpdateOperation(meta); + UpdateOperation(meta); + + RemoveMeta(meta, GetDisplayedRow(meta.id), true, false); + it2 = std::find(_operations->begin(), _operations->end(), meta.id); + if (it2 != _operations->end()) + _operations->erase(it2); + + InsertIntoGrid(meta); + + if (openMeta) + OpenMeta(meta); } void GridAccount::Group() @@ -1281,8 +1165,9 @@ void GridAccount::Group() int parent = 0, deletedRows; Operation op, op2; int fix = -1, i, a, row; - + User* user = _kiss->GetUser(); QModelIndexList selected = selectedIndexes(); + bool fullCheck = true; for (int i = 0; i < selected.size(); ++i) { @@ -1366,9 +1251,7 @@ void GridAccount::Group() deletedRows = RemoveMeta(ops[i], rows[i], true, false); else { - if (ops[i].fix_cost) _fixCosts--; - removeRow(rows[i]); - _displayedOperations.erase(_displayedOperations.begin()+rows[i]); + RemoveRow(ops[i], rows[i], false); deletedRows = 1; } for(a=i+1; a<(int)rows.size(); a++) @@ -1383,9 +1266,19 @@ void GridAccount::Group() for (i=0, it3=op.childs.begin(); it3!=op.childs.end(); it3++, i++) { op2 = GetOperation(*it3); - if (*it3 == it2->id || - op2.day > it2->day) - break; + if (*it3 == it2->id) + { + if (user->_preferences["operation_order"] == "ASC") + { + if (op2.day > it2->day) + break; + } + else + { + if (op2.day < it2->day) + break; + } + } } if (i) i--; @@ -1399,11 +1292,16 @@ void GridAccount::Group() it2->parent = op.id; UpdateOperation(*it2); + if (!it2->checked) + fullCheck = false; } + row = InsertIntoGrid(op); + UpdateMeta(op); - InsertIntoGrid(op); + if (fullCheck) + CheckMeta(op, row, true); } void GridAccount::GetSelectedOperations(std::vector* rows) @@ -1433,7 +1331,7 @@ void GridAccount::UnGroup() std::vector::iterator it3; int parent = 0; Operation op, op2; - int fix = -1, i, a, line; + int fix = -1, i, line; QModelIndexList selected = selectedIndexes(); @@ -1475,6 +1373,8 @@ void GridAccount::UnGroup() if (!ops.size() && !parent) return; + _inModification = true; + removeLastGroup: // Only one meta is selected if (!ops.size()) @@ -1492,7 +1392,6 @@ removeLastGroup: InsertIntoGrid(op2); } - _kiss->DeleteOperation(op); DeleteOperation(op); } else @@ -1508,19 +1407,14 @@ removeLastGroup: op.parent = 0; UpdateOperation(op); line = GetDisplayedRow(op.id); - removeRow(line); - _displayedOperations.erase(_displayedOperations.begin()+line); - InsertIntoGrid(GetOperation(op.id)); - if (op.fix_cost) _fixCosts--; - for (a=0; a<(int)op2.childs.size(); a++) - if (op2.childs[a] == op.id) - { - op2.childs.erase(op2.childs.begin()+a); - break; - } - UpdateMeta(op2); + RemoveRow(op, line, false); + InsertIntoGrid(op); + it = std::find(op2.childs.begin(), op2.childs.end(), op.id); + if (it != op2.childs.end()) + op2.childs.erase(it); } + UpdateMeta(op2); line = GetDisplayedRow(parent); _displayedOperations[line] = op2; @@ -1534,7 +1428,7 @@ removeLastGroup: UpdateOperation(op2); } - ComputeWeeks(); + _inModification = false; } void GridAccount::MassUpdate(std::vector& rows, bool do_childs, updateOperationFunc func, void** params) diff --git a/src/view/grid/GridAccount.hpp b/src/view/grid/GridAccount.hpp index 2b42410..b029c80 100644 --- a/src/view/grid/GridAccount.hpp +++ b/src/view/grid/GridAccount.hpp @@ -91,14 +91,20 @@ private: void ResetWeeks(); void ComputeWeeks(); - void InsertIntoGrid(Operation& op); - void DeleteOperation(const Operation& op); + bool CheckDay(User* user, const Operation& op, int& i); + + bool IsMetaOpened(int id); + void OpenMeta(const Operation& meta); + int InsertIntoGrid(Operation& op); + void DeleteOperation(const Operation& op) throw (OperationNotFound); + void RemoveRow(const Operation& op, int line, bool deleteOp); + void CheckOperation(Operation& op, int line, bool check, bool force); void UpdateMeta(Operation& op); int RemoveMeta(Operation op, int line, bool removeRoot, bool deleteOp); void CheckMeta(Operation& op, int line, bool check); Operation& GetOperation(int id) throw(OperationNotFound); void UpdateOperation(Operation& op); - int GetDisplayedRow(int id); + int GetDisplayedRow(int id) throw (OperationNotFound); }; #endif From d74ad570ad4f51d7347db2c3caf624c90848695e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 27 Dec 2012 17:58:35 +0100 Subject: [PATCH 13/23] Update Changelog --- ChangeLog | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 09057f8..3216168 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,14 @@ -v0.4 (16/12/2012) +v0.4 (27/12/2012) ** User ** Add icons for low resolution Sort categories using translated names ** Dev ** Primitive handle of low resolutions + Rework GridAccount + +** Bugs ** + Remove some bugs in GridAccount v0.3 (31/05/2012) From e9c677f5b26feaa16eb47bb9b3af949311fd93da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Sun, 13 Jan 2013 20:36:42 +0100 Subject: [PATCH 14/23] When user changes month or year in SearchBanner, A new date wasn't selected by default resulting in bad SQL query --- ChangeLog | 3 ++- src/view/SearchBanner.cpp | 15 +++++++++++++++ src/view/SearchBanner.hpp | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3216168..387b384 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -v0.4 (27/12/2012) +v0.4 (13/01/2013) ** User ** Add icons for low resolution Sort categories using translated names @@ -9,6 +9,7 @@ v0.4 (27/12/2012) ** Bugs ** Remove some bugs in GridAccount + When user changes month or year in SearchBanner, A new date wasn't selected by default resulting in bad SQL query v0.3 (31/05/2012) diff --git a/src/view/SearchBanner.cpp b/src/view/SearchBanner.cpp index 1495175..e178e86 100644 --- a/src/view/SearchBanner.cpp +++ b/src/view/SearchBanner.cpp @@ -42,6 +42,9 @@ SearchBanner::SearchBanner(KissCount* kiss, QFrame *parent, void* caller, OnButt // _calendarFrom->setNavigationBarVisible(false); _calendarFrom->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); _calendarFrom->setMaximumSize(_calendarFrom->sizeHint()); + _calendarFrom->setSelectedDate(QDate::currentDate()); + + connect(_calendarFrom, SIGNAL(currentPageChanged(int, int)), this, SLOT(OnCalendarFromPageChanged(int, int))); _calendarTo = new QCalendarWidget(this); _calendarTo->setGridVisible(false); @@ -49,7 +52,9 @@ SearchBanner::SearchBanner(KissCount* kiss, QFrame *parent, void* caller, OnButt // _calendarTo->setNavigationBarVisible(false); _calendarTo->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); _calendarTo->setMaximumSize(_calendarTo->sizeHint()); + _calendarTo->setSelectedDate(QDate::currentDate()); + connect(_calendarTo, SIGNAL(currentPageChanged(int, int)), this, SLOT(OnCalendarToPageChanged(int, int))); _description = new QLineEdit(this); _description->setMinimumWidth(_description->width()*2); @@ -122,6 +127,16 @@ SearchBanner::~SearchBanner() if (_operations) delete _operations; } +void SearchBanner::OnCalendarFromPageChanged(int year, int month) +{ + _calendarFrom->setSelectedDate(QDate(year, month, 1)); +} + +void SearchBanner::OnCalendarToPageChanged(int year, int month) +{ + _calendarTo->setSelectedDate(QDate(year, month, 1)); +} + std::vector * SearchBanner::Search() { QString *description=0; diff --git a/src/view/SearchBanner.hpp b/src/view/SearchBanner.hpp index 098e244..96455b3 100644 --- a/src/view/SearchBanner.hpp +++ b/src/view/SearchBanner.hpp @@ -39,6 +39,8 @@ public: private slots: void OnEnter(); + void OnCalendarFromPageChanged(int year, int month); + void OnCalendarToPageChanged(int year, int month); private: KissCount* _kiss; From 62a3712ff79339d235556aec8dfe6251c8c0b6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 17 Jan 2013 20:22:42 +0100 Subject: [PATCH 15/23] Add CSV Export Set DateFrom to first of month for SearchBanner Fix a bug : for dates in Search Fix a bug : file was not truncated during export --- src/model/Database.cpp | 4 +- src/model/export/CSVExportEngine.cpp | 213 +++++++++++++++++++++++++++ src/model/export/CSVExportEngine.hpp | 44 ++++++ src/model/export/XMLExportEngine.cpp | 4 +- src/view/SearchBanner.cpp | 10 +- src/view/SearchBanner.hpp | 2 +- 6 files changed, 267 insertions(+), 10 deletions(-) create mode 100644 src/model/export/CSVExportEngine.cpp create mode 100644 src/model/export/CSVExportEngine.hpp diff --git a/src/model/Database.cpp b/src/model/Database.cpp index 3437e52..d411daa 100644 --- a/src/model/Database.cpp +++ b/src/model/Database.cpp @@ -1245,14 +1245,14 @@ std::vector* Database::Search(User* user, QString* description, QDate if (dateFrom) { dayFrom = QString::number(dateFrom->day()-1); - monthFrom = QString::number(dateFrom->month()); + monthFrom = QString::number(dateFrom->month()-1); yearFrom = QString::number(dateFrom->year()); } if (dateTo) { dayTo = QString::number(dateTo->day()-1); - monthTo = QString::number(dateTo->month()); + monthTo = QString::number(dateTo->month()-1); yearTo = QString::number(dateTo->year()); } diff --git a/src/model/export/CSVExportEngine.cpp b/src/model/export/CSVExportEngine.cpp new file mode 100644 index 0000000..54586e5 --- /dev/null +++ b/src/model/export/CSVExportEngine.cpp @@ -0,0 +1,213 @@ +/* + Copyright 2010-2013 Grégory Soutadé + + This file is part of KissCount. + + KissCount 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. + + KissCount 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 KissCount. If not, see . +*/ + +#include +#include + +#include + +#include "CSVExportEngine.hpp" + +static CSVExportEngine csvExportEngine; + +CSVExportEngine::CSVExportEngine() +{ + KissCount::RegisterExportEngine(this); + + _shortExt = ".csv"; + _longExt = _("CSV files (*.csv)"); +} + +CSVExportEngine::~CSVExportEngine() +{ +} + +bool CSVExportEngine::HandleFile(const QString& path, User* user, Database* db, KissCount* kiss) +{ + return ExportEngine::HandleFile(path, user, db, kiss); +} + +bool CSVExportEngine::SaveAccounts() +{ + Account account; + std::map::iterator it; + + *_writer << "Accounts" << endl << endl; + *_writer << "id;name;number;blocked;virtual;hidden" << endl; + + for(it=_accounts.begin(); it!=_accounts.end(); it++) + { + try + { + account = _user->GetAccount(it->first); + } + catch(User::AccountNotFound) + { + account.id = it->first; + account.name = "Unknown"; + account.blocked = false; + account._virtual = false; + account.hidden = false; + } + + ESCAPE_CHARS(account.name); + ESCAPE_CHARS(account.number); + + *_writer << QString::number(account.id) << ";"; + *_writer << "\"" << account.name << "\"" << ";"; + *_writer << "\"" << account.number << "\"" << ";"; + // *_writer << (account.shared ? "1" : "0") << ";"; + *_writer << (account.blocked ? "1" : "0") << ";"; + // *_writer << (account._default ? "1" : "0") << ";" ; + // *_writer << (account.is_owner ? "1" : "0") << ";"; + *_writer << (account._virtual ? "1" : "0") << ";"; + *_writer << (account.hidden ? "1" : "0"); + *_writer << endl; + } + + *_writer << endl << endl; + + return true; +} + +bool CSVExportEngine::SaveAccountAmounts() +{ + std::map::iterator it; + QString v; + + *_writer << "Account Amounts" << endl << endl; + *_writer << "id;month;year;amount" << endl; + + for(it=_accountAmounts.begin(); it!=_accountAmounts.end(); it++) + { + *_writer << QString::number(it->first.account) << ";"; + *_writer << QString::number(it->first.month+1) << ";"; + *_writer << QString::number(it->first.year) << ";"; + *_writer << v.sprintf("%d", it->second); + *_writer << endl; + } + + *_writer << endl << endl; + + return true; +} + +bool CSVExportEngine::SaveCategories() +{ + Category category; + std::map::iterator it; + int rgb; + QString v; + + *_writer << "Categories" << endl << endl; + *_writer << "id;parent;name;font;backcolor;forecolor;fix_cost" << endl; + + for(it=_categories.begin(); it!=_categories.end(); it++) + { + category = _user->GetCategory(it->first); + + ESCAPE_CHARS(category.name); + + *_writer << QString::number(category.id) << ";"; + *_writer << QString::number(category.parent) << ";"; + *_writer << "\"" << category.name << "\"" << ";"; + *_writer << "\"" << category.font << "\"" << ";"; + rgb = category.backcolor.blue(); + rgb |= category.backcolor.green() << 8; + rgb |= category.backcolor.red() << 16; + *_writer << v.sprintf("0x%08X", rgb) << ";"; + rgb = category.forecolor.blue(); + rgb |= category.forecolor.green() << 8; + rgb |= category.forecolor.red() << 16; + *_writer << v.sprintf("0x%08X", rgb) << ";"; + *_writer << (category.fix_cost ? "1" : "0"); + *_writer << endl; + } + + *_writer << endl << endl; + + return true; +} + +bool CSVExportEngine::SaveOperations(std::vector* operations) +{ + std::vector::iterator it; + QString v; + + *_writer << "Operations" << endl << endl; + *_writer << "id;parent;day;month;year;amount;description;category;fix_cost;account;checked;transfert;formula;meta;virtual" << endl; + + for(it=operations->begin(); it!=operations->end(); it++) + { + ESCAPE_CHARS(it->description); + + *_writer << QString::number(it->id) << ";" ; + *_writer << QString::number(it->parent) << ";"; + *_writer << QString::number(it->day+1) << ";"; + *_writer << QString::number(it->month+1) << ";"; + *_writer << QString::number(it->year) << ";"; + *_writer << v.sprintf("%d", it->amount) << ";"; + *_writer << "\"" << it->description << "\"" << ";"; + *_writer << QString::number(it->category) << ";"; + *_writer << (it->fix_cost ? "1" : "0") << ";"; + *_writer << QString::number(it->account) << ";"; + *_writer << (it->checked ? "1" : "0") << ";"; + *_writer << QString::number(it->transfert) << ";"; + *_writer << it->formula << ";"; + *_writer << (it->meta ? "1" : "0") << ";"; + *_writer << (it->_virtual ? "1" : "0"); + *_writer << endl; + } + + *_writer << endl << endl; + + return true; +} + +bool CSVExportEngine::SaveFile(std::vector* operations) +{ + QFile file(_path); + int rc; + + rc = ExportEngine::SaveFile(operations); + + if (!rc) return false; + + if (!file.open(QIODevice::ReadWrite|QIODevice::Truncate)) + { + std::cout << "Error can't open the file " << _path.toStdString() << std::endl; + return false; + } + + _writer = new QTextStream(&file); + + _writer->setCodec("UTF-8"); + + SaveAccounts(); + SaveAccountAmounts(); + SaveCategories(); + SaveOperations(operations); + + file.flush(); + file.close(); + + delete _writer; + + return true; +} diff --git a/src/model/export/CSVExportEngine.hpp b/src/model/export/CSVExportEngine.hpp new file mode 100644 index 0000000..54dd88d --- /dev/null +++ b/src/model/export/CSVExportEngine.hpp @@ -0,0 +1,44 @@ +/* + Copyright 2010-2013 Grégory Soutadé + + This file is part of KissCount. + + KissCount 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. + + KissCount 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 KissCount. If not, see . +*/ + +#ifndef CSVEXPORTENGINE_H +#define CSVEXPORTENGINE_H + +#include +#include +#include "ExportEngine.hpp" + +class CSVExportEngine : public ExportEngine { +public: + CSVExportEngine(); + ~CSVExportEngine(); + + bool HandleFile(const QString& path, User* user, Database* db, KissCount* kiss); + bool SaveFile(std::vector* operations); + +private: + QTextStream* _writer; + + bool SaveAccounts(); + bool SaveAccountAmounts(); + bool SaveCategories(); + bool SaveOperations(std::vector* operations); +}; + +#endif diff --git a/src/model/export/XMLExportEngine.cpp b/src/model/export/XMLExportEngine.cpp index 805363e..082f3f4 100644 --- a/src/model/export/XMLExportEngine.cpp +++ b/src/model/export/XMLExportEngine.cpp @@ -1,5 +1,5 @@ /* - Copyright 2010-2012 Grégory Soutadé + Copyright 2010-2013 Grégory Soutadé This file is part of KissCount. @@ -173,7 +173,7 @@ bool XMLExportEngine::SaveFile(std::vector* operations) if (!rc) return false; - if (!file.open(QIODevice::ReadWrite)) + if (!file.open(QIODevice::ReadWrite|QIODevice::Truncate)) { std::cout << "Error can't open the file " << _path.toStdString() << std::endl; return false; diff --git a/src/view/SearchBanner.cpp b/src/view/SearchBanner.cpp index e178e86..a8772a6 100644 --- a/src/view/SearchBanner.cpp +++ b/src/view/SearchBanner.cpp @@ -1,5 +1,5 @@ /* - Copyright 2010-2012 Grégory Soutadé + Copyright 2010-2013 Grégory Soutadé This file is part of KissCount. @@ -42,7 +42,7 @@ SearchBanner::SearchBanner(KissCount* kiss, QFrame *parent, void* caller, OnButt // _calendarFrom->setNavigationBarVisible(false); _calendarFrom->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); _calendarFrom->setMaximumSize(_calendarFrom->sizeHint()); - _calendarFrom->setSelectedDate(QDate::currentDate()); + _calendarFrom->setSelectedDate(firstOfMonth); connect(_calendarFrom, SIGNAL(currentPageChanged(int, int)), this, SLOT(OnCalendarFromPageChanged(int, int))); @@ -157,19 +157,19 @@ std::vector * SearchBanner::Search() if (_checkDateFrom->checkState() == Qt::Checked) { dateFrom = new QDate(); - *dateFrom = _calendarFrom->selectedDate().addMonths(-1); + *dateFrom = _calendarFrom->selectedDate(); } if (_checkDateTo->checkState() == Qt::Checked) { dateTo = new QDate(); - *dateTo = _calendarTo->selectedDate().addMonths(-1); + *dateTo = _calendarTo->selectedDate(); } if (dateFrom && dateTo && *dateFrom > *dateTo) { QMessageBox::critical(0, _("Error"), _("Invalid date range")); - goto end; + goto end; } if (_amountFrom->text().length()) diff --git a/src/view/SearchBanner.hpp b/src/view/SearchBanner.hpp index 96455b3..0f3028e 100644 --- a/src/view/SearchBanner.hpp +++ b/src/view/SearchBanner.hpp @@ -1,5 +1,5 @@ /* - Copyright 2010-2012 Grégory Soutadé + Copyright 2010-2013 Grégory Soutadé This file is part of KissCount. From fcc7d090714e24fe56d870e9c0ac65d38ca84f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 17 Jan 2013 20:25:27 +0100 Subject: [PATCH 16/23] Update Changelog --- ChangeLog | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 387b384..1af1317 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,9 @@ -v0.4 (13/01/2013) +v0.4 (17/01/2013) ** User ** Add icons for low resolution Sort categories using translated names + Set DateFrom to first of month for SearchBanner + Add CSV export ** Dev ** Primitive handle of low resolutions @@ -10,6 +12,8 @@ v0.4 (13/01/2013) ** Bugs ** Remove some bugs in GridAccount When user changes month or year in SearchBanner, A new date wasn't selected by default resulting in bad SQL query + Date in search failed in january + File was not truncated during export v0.3 (31/05/2012) From e0efe42b14e69b003312abfc4eb34c4aef79aa2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Sun, 17 Feb 2013 18:58:32 +0100 Subject: [PATCH 17/23] Simplify UpdateNextMonths function Add "create_if_not_exsits" to Database::GetAccountAmount --- ChangeLog | 4 +- src/controller/KissCount.cpp | 4 +- src/controller/KissCount.hpp | 2 +- src/model/Database.cpp | 5 +- src/model/Database.hpp | 2 +- src/view/AccountPanel.cpp | 124 +++++++++++------------------------ 6 files changed, 48 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1af1317..f7d8f45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -v0.4 (17/01/2013) +v0.4 (17/02/2013) ** User ** Add icons for low resolution Sort categories using translated names @@ -8,6 +8,8 @@ v0.4 (17/01/2013) ** Dev ** Primitive handle of low resolutions Rework GridAccount + Simplify UpdateNextMonths function + Add "create_if_not_exsits" to Database::GetAccountAmount ** Bugs ** Remove some bugs in GridAccount diff --git a/src/controller/KissCount.cpp b/src/controller/KissCount.cpp index a687f00..3697276 100644 --- a/src/controller/KissCount.cpp +++ b/src/controller/KissCount.cpp @@ -99,9 +99,9 @@ User* KissCount::GetUser() return _user; } -int KissCount::GetAccountAmount(int id, int month, int year, bool* had_value) +int KissCount::GetAccountAmount(int id, int month, int year, bool* had_value, bool create_if_not_exsits) { - return _db->GetAccountAmount(id, month, year, had_value); + return _db->GetAccountAmount(id, month, year, had_value, create_if_not_exsits); } int KissCount::CalcAccountAmount(int id, int month, int year, bool* had_values) diff --git a/src/controller/KissCount.hpp b/src/controller/KissCount.hpp index f7c8b88..74fe6b2 100644 --- a/src/controller/KissCount.hpp +++ b/src/controller/KissCount.hpp @@ -77,7 +77,7 @@ public: int MetaAmount(int id); int MetaPositiveAmount(int id); - int GetAccountAmount(int id, int month, int year, bool* had_values=0); + int GetAccountAmount(int id, int month, int year, bool* had_values=0, bool create_if_not_exsits=true); void SetAccountAmount(int accountId, int month, int year, int value); int CalcAccountAmount(int id, int month, int year, bool* had_values); diff --git a/src/model/Database.cpp b/src/model/Database.cpp index d411daa..d20a29f 100644 --- a/src/model/Database.cpp +++ b/src/model/Database.cpp @@ -379,7 +379,7 @@ void Database::LoadYear(User* user, int year) query.clear(); } -int Database::GetAccountAmount(int id, int month, int year, bool* had_value) +int Database::GetAccountAmount(int id, int month, int year, bool* had_value, bool create_if_not_exsits) { QSqlRecord set; QString req; @@ -400,7 +400,8 @@ int Database::GetAccountAmount(int id, int month, int year, bool* had_value) } else { - SetAccountAmount(id, month, year, 0); + if (create_if_not_exsits) + SetAccountAmount(id, month, year, 0); if (had_value) *had_value = false; } diff --git a/src/model/Database.hpp b/src/model/Database.hpp index 639b993..4ac3797 100644 --- a/src/model/Database.hpp +++ b/src/model/Database.hpp @@ -113,7 +113,7 @@ public: int MetaAmount(int id); int MetaPositiveAmount(int id); - int GetAccountAmount(int id, int month, int year, bool* had_value=0); + int GetAccountAmount(int id, int month, int year, bool* had_value=0, bool create_if_not_exsits=true); void SetAccountAmount(int accountId, int month, int year, int amount); int CalcAccountAmount(int id, int month, int year, bool* had_values); diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp index 8dd08b9..11ee723 100644 --- a/src/view/AccountPanel.cpp +++ b/src/view/AccountPanel.cpp @@ -1054,112 +1054,65 @@ void AccountPanel::OnUnGroup() void AccountPanel::OnUpdateNextMonths() { - int* deltas, *cur_amounts, amount; - int i, a; + int *cur_amounts, amount, i; User* user = _kiss->GetUser(); - bool had_values, accounts_updated = false; - int last_month = 0, last_year = 0, account_updated = 0; - std::map > operations; + bool has_values, accounts_updated = false; + int cur_month = 0, cur_year = 0, delta_computed = 0; + int last_month, last_year; + bool *valid_account; - deltas = new int[user->_accounts.size()] ; cur_amounts = new int[user->_accounts.size()] ; + valid_account = new bool[user->_accounts.size()] ; - operations = _kiss->GetAllOperations(); + cur_month = _curMonth; + cur_year = _curYear; - if (_curMonth == 11) - { - last_month = 0; - last_year = _curYear+1; - } - else - { - last_month = _curMonth+1; - last_year = _curYear; - } - - // Compute deltas for (i=0; i<(int)user->_accounts.size(); i++) { - deltas[i] = _kiss->GetAccountAmount(user->_accounts[i].id, _curMonth, _curYear); - cur_amounts[i] = deltas[i] += _kiss->CalcAccountAmount(user->_accounts[i].id, _curMonth, _curYear, &had_values); - - for (a=0; a<(int)operations[last_year].size(); a++) - if (operations[last_year][a] == last_month) break; - - if (a == (int)operations[last_year].size()) - { - deltas[i] = 0; - continue; - } - - amount = _kiss->GetAccountAmount(user->_accounts[i].id, last_month, last_year); - - deltas[i] -= amount; - - if (deltas[i]) - account_updated++; + cur_amounts[i] = _kiss->GetAccountAmount(user->_accounts[i].id, cur_month, cur_year, &has_values, false); + valid_account[i] = has_values; } - if (!account_updated) - goto end; - - last_month = _curMonth; - last_year = _curYear; - - // Apply deltas while (1) { - account_updated = 0; + delta_computed = 0; - if (last_month == 11) + for (i=0; i<(int)user->_accounts.size(); i++) { - last_month = 0; - last_year = last_year+1; + if (!valid_account[i]) continue; + cur_amounts[i] += _kiss->CalcAccountAmount(user->_accounts[i].id, cur_month, cur_year, &has_values); + if (has_values) + delta_computed++; + } + + if (!delta_computed) break; + + if (cur_month == 11) + { + cur_month = 0; + cur_year++; } else - last_month++; + cur_month++; for (i=0; i<(int)user->_accounts.size(); i++) { - if (deltas[i] == 0.0) continue; - - _kiss->CalcAccountAmount(user->_accounts[i].id, last_month, last_year, &had_values); - if (had_values) - account_updated++; + if (!valid_account[i]) continue; + amount = _kiss->GetAccountAmount(user->_accounts[i].id, cur_month, cur_year, &has_values, false); + if (!has_values) + { + valid_account[i] = false; + continue; + } + if (amount != cur_amounts[i]) + { + accounts_updated = true; + _kiss->SetAccountAmount(user->_accounts[i].id, cur_month, cur_year, cur_amounts[i]); + last_month = cur_month; last_year = cur_year; + } } - - if (!account_updated) break; - - account_updated = 0; - - for (i=0; i<(int)user->_accounts.size(); i++) - { - if (deltas[i] == 0.0) continue; - - amount = _kiss->GetAccountAmount(user->_accounts[i].id, last_month, last_year); - if ((cur_amounts[i] - amount) != deltas[i]) continue; - - cur_amounts[i] = amount + deltas[i]; - _kiss->SetAccountAmount(user->_accounts[i].id, last_month, last_year, cur_amounts[i]); - cur_amounts[i] += _kiss->CalcAccountAmount(user->_accounts[i].id, last_month, last_year, &had_values); - - account_updated++; - } - - if (!account_updated) break; - - accounts_updated = true; } - if (last_month == 0) - { - last_month = 11; - last_year--; - } - else - last_month--; - -end: if (accounts_updated) { QString message = _("Accounts updated until ") + wxUI::months[last_month] + " " + QString::number(last_year); @@ -1169,7 +1122,6 @@ end: else QMessageBox::information(0, "KissCount", _("Any account updated !")); - delete[] deltas; delete[] cur_amounts; } From 0d80d91a479b9169f5df8967f9c95b346506a659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Sun, 17 Feb 2013 19:11:38 +0100 Subject: [PATCH 18/23] Fix a bug : Group a non checked operation with a checked meta did not uncheck meta --- ChangeLog | 1 + src/view/grid/GridAccount.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f7d8f45..28725f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,7 @@ v0.4 (17/02/2013) When user changes month or year in SearchBanner, A new date wasn't selected by default resulting in bad SQL query Date in search failed in january File was not truncated during export + Group a non checked operation with a checked meta did not uncheck meta v0.3 (31/05/2012) diff --git a/src/view/grid/GridAccount.cpp b/src/view/grid/GridAccount.cpp index 0cc2a98..33e403e 100644 --- a/src/view/grid/GridAccount.cpp +++ b/src/view/grid/GridAccount.cpp @@ -1298,10 +1298,19 @@ void GridAccount::Group() row = InsertIntoGrid(op); + if (fullCheck) + { + op.checked = true; + CheckOperation(op, row, true, false); + } + else + { + op.checked = false; + CheckOperation(op, row, false, false); + } + UpdateMeta(op); - if (fullCheck) - CheckMeta(op, row, true); } void GridAccount::GetSelectedOperations(std::vector* rows) From 2ec5e124da3a7fe8c0b37a3ac46106ea95fafe56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 26 Feb 2013 12:17:35 +0100 Subject: [PATCH 19/23] Extract cost repartition banner --- ChangeLog | 4 +- src/view/AccountPanel.cpp | 120 +++------------------ src/view/AccountPanel.hpp | 5 +- src/view/CostRepartitionBanner.cpp | 165 +++++++++++++++++++++++++++++ src/view/CostRepartitionBanner.hpp | 47 ++++++++ 5 files changed, 230 insertions(+), 111 deletions(-) create mode 100644 src/view/CostRepartitionBanner.cpp create mode 100644 src/view/CostRepartitionBanner.hpp diff --git a/ChangeLog b/ChangeLog index 28725f7..29e9771 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,12 +1,12 @@ v0.4 (17/02/2013) ** User ** - Add icons for low resolution + Add icons for low resolution screens Sort categories using translated names Set DateFrom to first of month for SearchBanner Add CSV export ** Dev ** - Primitive handle of low resolutions + Primitive handle of low resolution screens Rework GridAccount Simplify UpdateNextMonths function Add "create_if_not_exsits" to Database::GetAccountAmount diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp index 11ee723..efb2dde 100644 --- a/src/view/AccountPanel.cpp +++ b/src/view/AccountPanel.cpp @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include "AccountPanel.hpp" #include "grid/FloatDelegate.hpp" @@ -29,7 +27,7 @@ #include "SnapshotsDialog.hpp" enum {ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_INIT, ACCOUNT_CUR, ACCOUNT_FINAL, NUMBER_COLS_ACCOUNTS}; -enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, BALANCE, STATS_ROW, CATS_STATS, NON_FIX}; +enum {CUR_CREDIT, CUR_DEBIT, TOTAL_CREDIT, TOTAL_DEBIT, BALANCE, CATS_STATS}; enum {VIRTUAL_MODE=0, REAL_MODE, CHECK_MODE}; @@ -51,12 +49,10 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode) QVBoxLayout *vbox = new QVBoxLayout; QVBoxLayout *vbox2 = new QVBoxLayout; QVBoxLayout *vbox3 = new QVBoxLayout; - // wxChartPanel* chart ; - int i ; + int i; User* user = _kiss->GetUser(); std::vector::iterator accountIt; std::vector::iterator categoryIt; - int nbCategories; _icons[KissPanel::LOW_RES_ICON] = USER_LOW_ICON; _icons[KissPanel::HIGH_RES_ICON] = USER_ICON; @@ -70,8 +66,6 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode) _tree->setContextMenuPolicy(Qt::CustomContextMenu); connect(_tree, SIGNAL(customContextMenuRequested ( const QPoint & )), this, SLOT(OnTreeRightClick(const QPoint &))); -// ColorScheme* colorScheme = new ColorScheme(wxUI::categoryColors, WXSIZEOF(wxUI::categoryColors)); - _calendar = new QCalendarWidget(this); _calendar->setGridVisible(false); _calendar->setFirstDayOfWeek(Qt::Monday); @@ -96,48 +90,7 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode) _categoriesIndexes[categoryIt->name] = i; } - nbCategories = user->GetCategoriesNumber(); - // nbCategories = (user->GetCategoriesNumber() <= wxUI::MAX_CATEGORY) ? user->GetCategoriesNumber() : wxUI::MAX_CATEGORY; - - _pie = new KDChart::Widget(); - _pie->setType( KDChart::Widget::Pie ); - QPen pen; - pen.setWidth(2); - pen.setColor(Qt::black); - _pie->pieDiagram()->setPen(pen); - - _pie->addLegend(KDChart::Position::South); - KDChart::Legend* legend = _pie->legend(); - // legend->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - legend->setOrientation( Qt::Vertical ); - legend->setTitleText( _("Cost repartition") ); - QVector< double > vec; - vec << 0.0; - _dataset = new QStandardItemModel(nbCategories, 2, this); - _categoriesValues = new int[nbCategories]; - for(i=0; isetDataset( i, vec, _categories[i] ); - _pie->pieDiagram()->setBrush(i, QBrush(wxUI::categoryColors[i])); - legend->setText( i, _categories[i] ); - _dataset->setData(_dataset->index(i, 0, QModelIndex()), _categories[i]); - _dataset->setData(_dataset->index(i, 1, QModelIndex()), 0.0); - if (i < wxUI::MAX_CATEGORY) - _dataset->setData(_dataset->index(i, 0, QModelIndex()), wxUI::categoryColors[i], Qt::DecorationRole); - } - - _pie->setMaximumSize( 200, 400 ); - - KDChart::TextAttributes legendTextAttr(legend->textAttributes()); - legendTextAttr.setFontSize(64); - legendTextAttr.setAutoShrink(true); - legend->setTextAttributes(legendTextAttr); - - legendTextAttr = KDChart::TextAttributes(legend->titleTextAttributes()); - legendTextAttr.setFontSize(64); - legendTextAttr.setAutoShrink(true); - legend->setTitleTextAttributes(legendTextAttr); + _categoriesValues = new int[user->GetCategoriesNumber()]; _grid = new GridAccount(_kiss, this, true, true, true); _grid->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -155,8 +108,10 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode) _statsGrid = new QTableWidget(this); _statsGrid->verticalHeader()->setHidden(true); _statsGrid->horizontalHeader()->setHidden(true); - _statsGrid->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); + _statsGrid->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + _costRepartitionBanner = new CostRepartitionBanner(_kiss, this, _categories); + QGroupBox *groupBox = new QGroupBox(_("Mode")); _virtual = new QRadioButton(_("Virtual")); @@ -212,15 +167,12 @@ void AccountPanel::Init(KissCount* kiss, wxUI *parent, int curMode) vbox2->addWidget(_grid, 1); hbox->addLayout(vbox2); vbox->addWidget(_statsGrid); - vbox->addWidget(_pie); + vbox->addWidget(_costRepartitionBanner); hbox->addLayout(vbox); ChangeUser(); layout(); - - QSize s = legend->sizeHint(); - legend->setMaximumSize(s.width(), s.height()/3); } AccountPanel::~AccountPanel() @@ -248,8 +200,6 @@ QString AccountPanel::GetToolTip() void AccountPanel::InitStatsGrid(User* user) { - int i; - int nb_categories = user->GetCategoriesNumber(); DEFAULT_FONT(font); if (!_statsGrid->rowCount()) @@ -261,27 +211,11 @@ void AccountPanel::InitStatsGrid(User* user) { _statsGrid->clear(); } - _statsGrid->setRowCount(nb_categories+CATS_STATS+1); // Headers + blank + categories + non fix + _statsGrid->setRowCount(CATS_STATS); // Headers _statsGrid->setItem(TOTAL_CREDIT, 0, new QTableWidgetItem(_("Total Credit"))); _statsGrid->setItem(TOTAL_DEBIT, 0, new QTableWidgetItem(_("Total Debit"))); - for(i=0; isetItem(CATS_STATS+i+1, 0, new QTableWidgetItem(_categories[i])); - _statsGrid->setItem(CATS_STATS+i+1, 1, new QTableWidgetItem("")); - _statsGrid->item(CATS_STATS+i+1, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - } - else - { - _statsGrid->setItem(CATS_STATS+i, 0, new QTableWidgetItem(_categories[i])); - _statsGrid->setItem(CATS_STATS+i, 1, new QTableWidgetItem("")); - _statsGrid->item(CATS_STATS+i, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - } - } - font.setBold(true); _statsGrid->setItem(CUR_CREDIT, 0, new QTableWidgetItem(_("Cur Credit"))); @@ -289,14 +223,12 @@ void AccountPanel::InitStatsGrid(User* user) _statsGrid->setItem(TOTAL_CREDIT, 0, new QTableWidgetItem(_("Total Credit"))); _statsGrid->setItem(TOTAL_DEBIT, 0, new QTableWidgetItem(_("Total Debit"))); _statsGrid->setItem(BALANCE, 0, new QTableWidgetItem(_("Balance"))); - _statsGrid->setItem(NON_FIX, 0, new QTableWidgetItem(_("Non fix"))); _statsGrid->setItem(CUR_CREDIT, 1, new QTableWidgetItem("")); _statsGrid->setItem(CUR_DEBIT, 1, new QTableWidgetItem("")); _statsGrid->setItem(TOTAL_CREDIT, 1, new QTableWidgetItem("")); _statsGrid->setItem(TOTAL_DEBIT, 1, new QTableWidgetItem("")); _statsGrid->setItem(BALANCE, 1, new QTableWidgetItem("")); - _statsGrid->setItem(NON_FIX, 1, new QTableWidgetItem("")); _statsGrid->item(CUR_DEBIT, 0)->setFont(font); _statsGrid->item(CUR_CREDIT, 0)->setFont(font); @@ -308,9 +240,10 @@ void AccountPanel::InitStatsGrid(User* user) _statsGrid->item(TOTAL_CREDIT, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); _statsGrid->item(TOTAL_DEBIT, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); _statsGrid->item(BALANCE, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - _statsGrid->item(NON_FIX, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); _statsGrid->resizeColumnToContents(0); + + _costRepartitionBanner->Reset(); } void AccountPanel::ChangeUser() @@ -572,6 +505,7 @@ void AccountPanel::UpdateStats() Operation op; bool blocked_account ; QString v; + std::vector operations; _inModification = true; @@ -666,6 +600,7 @@ void AccountPanel::UpdateStats() curAccountAmount[op.account] += op.amount; finalAccountAmount[op.account] += op.amount; } + operations.push_back(op); } balance = totalCredit - totalDebit; @@ -677,35 +612,6 @@ void AccountPanel::UpdateStats() _statsGrid->item(BALANCE, 1)->setText(v.sprintf("%.2lf", (double)balance/100)); _statsGrid->item(BALANCE, 1)->setForeground((balance >= 0) ? QBrush(Qt::green) : QBrush(Qt::red)); - // KDChart::Legend* legend = _pie->legend(); - for(i=0; iGetCategoriesNumber(); i++) - { - if (totalDebit != 0) - percents = (_categoriesValues[i]*100)/totalDebit; - else - percents = 0.0; - if (i) - _statsGrid->item(CATS_STATS+i+1, 1)->setText(v.sprintf("%.2lf (%02d %%)", (double)_categoriesValues[i]/100, (int)percents)); - else - _statsGrid->item(CATS_STATS+i, 1)->setText(v.sprintf("%.2lf (%02d %%)", (double)_categoriesValues[i]/100, (int)percents)); - - QVector< double > vec; - vec << (double) _categoriesValues[i] / 100; - _pie->setDataset( i, vec, _categories[i] ); - // if (_categoriesValues[i] == 0.0) - // legend->setDatasetHidden(i, true); - // else - // legend->setDatasetHidden(i, false); - // _dataset->setData(_dataset->index(i, 1, QModelIndex()), _categoriesValues[i]); - } - - value = totalDebit - _categoriesValues[0]; - if (totalDebit != 0) - percents = (value*100)/totalDebit; - else - percents = 0.0; - _statsGrid->item(NON_FIX, 1)->setText(v.sprintf("%.2lf (%02d %%)", (double)value/100, (int)percents)); - for (i=0, accountIt=user->_accounts.begin(); accountIt!=user->_accounts.end(); accountIt++, i++) { if (accountIt->hidden) @@ -740,6 +646,8 @@ void AccountPanel::UpdateStats() } } + _costRepartitionBanner->UpdateCosts(operations, _categoriesValues, totalDebit); + _accountsGrid->resizeColumnToContents(ACCOUNT_INIT); _accountsGrid->resizeColumnToContents(ACCOUNT_CUR); _accountsGrid->resizeColumnToContents(ACCOUNT_FINAL); diff --git a/src/view/AccountPanel.hpp b/src/view/AccountPanel.hpp index aa54a04..251719b 100644 --- a/src/view/AccountPanel.hpp +++ b/src/view/AccountPanel.hpp @@ -25,12 +25,12 @@ #include #include #include -#include #include "view.hpp" #include #include "grid/GridAccount.hpp" +#include "CostRepartitionBanner.hpp" class GridAccount; @@ -76,14 +76,13 @@ private: QCalendarWidget* _calendar; GridAccount* _grid; QTableWidget* _accountsGrid, *_statsGrid; - KDChart::Widget* _pie; + CostRepartitionBanner* _costRepartitionBanner; int *_categoriesValues; // wxRadioBox *_radioMode; std::map _categoriesIndexes; std::vector* _curOperations; QString* _categories, *_accounts; std::map _accountsInitValues; - QStandardItemModel* _dataset; int _fixCosts; QRadioButton *_virtual, *_real, *_check; bool _inModification; diff --git a/src/view/CostRepartitionBanner.cpp b/src/view/CostRepartitionBanner.cpp new file mode 100644 index 0000000..04da323 --- /dev/null +++ b/src/view/CostRepartitionBanner.cpp @@ -0,0 +1,165 @@ +/* + Copyright 2010-2013 Grégory Soutadé + + This file is part of KissCount. + + KissCount 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. + + KissCount 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 KissCount. If not, see . +*/ + +#include +#include + +#include "CostRepartitionBanner.hpp" + +CostRepartitionBanner::CostRepartitionBanner(KissCount* kiss, QFrame* parent, QString* categories) : QFrame(parent), _kiss(kiss), _categories(categories) +{ + User* user = _kiss->GetUser(); + int nbCategories, i; + QVBoxLayout *vbox = new QVBoxLayout; + + setLayout(vbox); + + nbCategories = user->GetCategoriesNumber(); + + _pie = new KDChart::Widget(); + _pie->setType( KDChart::Widget::Pie ); + QPen pen; + pen.setWidth(2); + pen.setColor(Qt::black); + _pie->pieDiagram()->setPen(pen); + + _pie->addLegend(KDChart::Position::South); + KDChart::Legend* legend = _pie->legend(); + // legend->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + legend->setOrientation( Qt::Vertical ); + legend->setTitleText( _("Cost repartition") ); + QVector< double > vec; + vec << 0.0; + _dataset = new QStandardItemModel(nbCategories, 2, this); + for(i=0; isetDataset( i, vec, _categories[i] ); + _pie->pieDiagram()->setBrush(i, QBrush(wxUI::categoryColors[i])); + legend->setText( i, _categories[i] ); + _dataset->setData(_dataset->index(i, 0, QModelIndex()), _categories[i]); + _dataset->setData(_dataset->index(i, 1, QModelIndex()), 0.0); + if (i < wxUI::MAX_CATEGORY) + _dataset->setData(_dataset->index(i, 0, QModelIndex()), wxUI::categoryColors[i], Qt::DecorationRole); + } + + _pie->setMaximumSize( 200, 400 ); + + KDChart::TextAttributes legendTextAttr(legend->textAttributes()); + legendTextAttr.setFontSize(64); + legendTextAttr.setAutoShrink(true); + legend->setTextAttributes(legendTextAttr); + + legendTextAttr = KDChart::TextAttributes(legend->titleTextAttributes()); + legendTextAttr.setFontSize(64); + legendTextAttr.setAutoShrink(true); + legend->setTitleTextAttributes(legendTextAttr); + + _statsGrid = new QTableWidget(this); + _statsGrid->verticalHeader()->setHidden(true); + _statsGrid->horizontalHeader()->setHidden(true); + _statsGrid->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); + + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding); + + QSize s = legend->sizeHint(); + legend->setMaximumSize(s.width(), s.height()/3); + + vbox->addWidget(_statsGrid); + vbox->addWidget(_pie); + + setMaximumWidth(300); +} + +void CostRepartitionBanner::Reset() +{ + int i; + User* user = _kiss->GetUser(); + int nb_categories = user->GetCategoriesNumber(); + + if (!_statsGrid->rowCount()) + { + _statsGrid->setColumnCount(2); + //_statsGrid->EnableEditing(false); + } + else + { + _statsGrid->clear(); + } + _statsGrid->setRowCount(nb_categories+1); // categories + non fix + + _statsGrid->setItem(1, 0, new QTableWidgetItem(_("Non fix"))); + _statsGrid->setItem(1, 1, new QTableWidgetItem("")); + + for(i=0; isetItem(i, 0, new QTableWidgetItem(_categories[i])); + _statsGrid->setItem(i, 1, new QTableWidgetItem("")); + _statsGrid->item(i, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + } + else + { + _statsGrid->setItem(i+1, 0, new QTableWidgetItem(_categories[i])); + _statsGrid->setItem(i+1, 1, new QTableWidgetItem("")); + _statsGrid->item(i+1, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + } + } + + _statsGrid->resizeColumnToContents(0); +} + +void CostRepartitionBanner::UpdateCosts(std::vector& operations, int *categoriesValues, int totalDebit) +{ + int i; + User* user = _kiss->GetUser(); + int value, percents; + QString v; + + for(i=0; iGetCategoriesNumber(); i++) + { + if (totalDebit != 0) + percents = (categoriesValues[i]*100)/totalDebit; + else + percents = 0.0; + if (!i) + _statsGrid->item(i, 1)->setText(v.sprintf("%.2lf (%02d %%)", (double)categoriesValues[i]/100, (int)percents)); + else + _statsGrid->item(i+1, 1)->setText(v.sprintf("%.2lf (%02d %%)", (double)categoriesValues[i]/100, (int)percents)); + + // KDChart::Legend* legend = _pie->legend(); + QVector< double > vec; + vec << (double) categoriesValues[i] / 100; + _pie->setDataset( i, vec, _categories[i] ); + // if (categoriesValues[i] == 0.0) + // legend->setDatasetHidden(i, true); + // else + // legend->setDatasetHidden(i, false); + // _dataset->setData(_dataset->index(i, 1, QModelIndex()), categoriesValues[i]); + } + + value = totalDebit - categoriesValues[0]; + if (totalDebit != 0) + percents = (value*100)/totalDebit; + else + percents = 0.0; + _statsGrid->item(1, 1)->setText(v.sprintf("%.2lf (%02d %%)", (double)value/100, (int)percents)); + + _statsGrid->resizeColumnToContents(1); +} diff --git a/src/view/CostRepartitionBanner.hpp b/src/view/CostRepartitionBanner.hpp new file mode 100644 index 0000000..b6ec7ca --- /dev/null +++ b/src/view/CostRepartitionBanner.hpp @@ -0,0 +1,47 @@ +/* + Copyright 2010-2013 Grégory Soutadé + + This file is part of KissCount. + + KissCount 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. + + KissCount 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 KissCount. If not, see . +*/ + +#ifndef COSTREPARTITIONBANNER_H +#define COSTREPARTITIONBANNER_H + +#include +#include + +#include "view.hpp" +#include + +class CostRepartitionBanner: public QFrame +{ + Q_OBJECT; + +public: + CostRepartitionBanner(KissCount* kiss, QFrame* parent, QString* categories); + + void Reset(); + void UpdateCosts(std::vector& operations, int *categoriesValues, int totalDebit); + +private: + KissCount* _kiss; + QString* _categories; + QTableWidget* _statsGrid; + KDChart::Widget* _pie; + QStandardItemModel* _dataset; +}; + +#endif From fb2541358c7fc3fa60ef7bb6f49d4ebef449eb70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 26 Feb 2013 15:05:34 +0100 Subject: [PATCH 20/23] Fix a regression : meta description always updated to first child description --- src/view/grid/GridAccount.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/view/grid/GridAccount.cpp b/src/view/grid/GridAccount.cpp index 33e403e..d5a1827 100644 --- a/src/view/grid/GridAccount.cpp +++ b/src/view/grid/GridAccount.cpp @@ -1081,7 +1081,7 @@ void GridAccount::OnOperationModified(int row, int col) if (new_op.parent) { parent = GetOperation(new_op.parent); - UpdateMeta(parent); + UpdateMeta(parent); } _kiss->UpdateStats(); @@ -1108,7 +1108,6 @@ void GridAccount::UpdateMeta(Operation& meta) meta.year = op.year; meta.month = op.month; meta.day = op.day; - meta.description = ""; for(it=meta.childs.begin(); it!=meta.childs.end(); it++) { @@ -1119,7 +1118,7 @@ void GridAccount::UpdateMeta(Operation& meta) meta.month = op.month; meta.day = op.day; } - if (!meta.description.length() && op.description.length()) + if (meta.description.length() == 0) meta.description = op.description; if (!category) { From eaba622a3fd7199f73e21c22daaafb2d6877b4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 26 Feb 2013 15:34:52 +0100 Subject: [PATCH 21/23] Extract cost repartition from StatsPannel --- src/view/AccountPanel.cpp | 4 +- src/view/CostRepartitionBanner.cpp | 2 +- src/view/CostRepartitionBanner.hpp | 2 +- src/view/StatsPanel.cpp | 112 +++-------------------------- src/view/StatsPanel.hpp | 4 +- 5 files changed, 15 insertions(+), 109 deletions(-) diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp index efb2dde..cf6690a 100644 --- a/src/view/AccountPanel.cpp +++ b/src/view/AccountPanel.cpp @@ -505,7 +505,6 @@ void AccountPanel::UpdateStats() Operation op; bool blocked_account ; QString v; - std::vector operations; _inModification = true; @@ -600,7 +599,6 @@ void AccountPanel::UpdateStats() curAccountAmount[op.account] += op.amount; finalAccountAmount[op.account] += op.amount; } - operations.push_back(op); } balance = totalCredit - totalDebit; @@ -646,7 +644,7 @@ void AccountPanel::UpdateStats() } } - _costRepartitionBanner->UpdateCosts(operations, _categoriesValues, totalDebit); + _costRepartitionBanner->UpdateCosts(_categoriesValues, totalDebit); _accountsGrid->resizeColumnToContents(ACCOUNT_INIT); _accountsGrid->resizeColumnToContents(ACCOUNT_CUR); diff --git a/src/view/CostRepartitionBanner.cpp b/src/view/CostRepartitionBanner.cpp index 04da323..1678570 100644 --- a/src/view/CostRepartitionBanner.cpp +++ b/src/view/CostRepartitionBanner.cpp @@ -125,7 +125,7 @@ void CostRepartitionBanner::Reset() _statsGrid->resizeColumnToContents(0); } -void CostRepartitionBanner::UpdateCosts(std::vector& operations, int *categoriesValues, int totalDebit) +void CostRepartitionBanner::UpdateCosts(int *categoriesValues, int totalDebit) { int i; User* user = _kiss->GetUser(); diff --git a/src/view/CostRepartitionBanner.hpp b/src/view/CostRepartitionBanner.hpp index b6ec7ca..dc8738b 100644 --- a/src/view/CostRepartitionBanner.hpp +++ b/src/view/CostRepartitionBanner.hpp @@ -34,7 +34,7 @@ public: CostRepartitionBanner(KissCount* kiss, QFrame* parent, QString* categories); void Reset(); - void UpdateCosts(std::vector& operations, int *categoriesValues, int totalDebit); + void UpdateCosts(int *categoriesValues, int totalDebit); private: KissCount* _kiss; diff --git a/src/view/StatsPanel.cpp b/src/view/StatsPanel.cpp index a9b3dae..874145d 100644 --- a/src/view/StatsPanel.cpp +++ b/src/view/StatsPanel.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -33,13 +32,12 @@ StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : _hbox2 = new QHBoxLayout(); _vbox2 = new QVBoxLayout(); _vbox3 = new QVBoxLayout(); - int i; + int i, nbCategories; User* user = _kiss->GetUser(); std::vector::iterator accountIt; std::vector::iterator categoryIt; std::map > operations; std::map >::iterator it; - int nbCategories; QListWidgetItem* item; _icons[KissPanel::LOW_RES_ICON] = STATS_LOW_ICON; @@ -112,85 +110,23 @@ StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : DEFAULT_FONT(font); - _statsGrid = new QTableWidget(this); - - _statsGrid->setRowCount(user->GetCategoriesNumber()+1); - _statsGrid->setColumnCount(2); - _statsGrid->verticalHeader()->setHidden(true); - _statsGrid->horizontalHeader()->setHidden(true); - - _statsGrid->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - - for(i=0; iGetCategoriesNumber(); i++) - { - if (i) - { - _statsGrid->setItem(i+1, 0, new QTableWidgetItem(_categories[i])); - _statsGrid->item(i+1, 0)->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); - } - else - { - _statsGrid->setItem(i, 0, new QTableWidgetItem(_categories[i])); - _statsGrid->item(i, 0)->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter); - } - } - - _statsGrid->setItem(1, 0, new QTableWidgetItem(_("Non fix"))); - _statsGrid->setItem(1, 1, new QTableWidgetItem("")); - _statsGrid->item(1, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); + _costRepartitionBanner = new CostRepartitionBanner(_kiss, this, _categories); _vbox3->addWidget(_account); - _vbox3->addWidget(_statsGrid); nbCategories = user->GetCategoriesNumber(); - // nbCategories = (user->GetCategoriesNumber() <= wxUI::MAX_CATEGORY) ? user->GetCategoriesNumber() : wxUI::MAX_CATEGORY; - _categoriesValues = new int[user->GetCategoriesNumber()]; - for(i=0; iGetCategoriesNumber(); i++) - _categoriesValues[i] = 0.0; - - _pie = new KDChart::Widget(); - _pie->setType( KDChart::Widget::Pie); - QPen pen; - pen.setWidth(2); - pen.setColor(Qt::black); - _pie->pieDiagram()->setPen(pen); - - _pie->addLegend(KDChart::Position::South); - KDChart::Legend* legend = _pie->legend(); - legend->setOrientation(Qt::Vertical); - legend->setTitleText(_("Cost repartition")); - QVector< double > vec; - vec << 0.0; _categoriesValues = new int[nbCategories]; for(i=0; isetDataset(i, vec, _categories[i]); - if (i < wxUI::MAX_CATEGORY) - _pie->pieDiagram()->setBrush(i, QBrush(wxUI::categoryColors[i])); - legend->setText(i, _categories[i]); - } - - _pie->setMinimumSize(200, 400); - _pie->setMaximumSize(200, 400); - - KDChart::TextAttributes legendTextAttr(legend->textAttributes()); - legendTextAttr.setFontSize(64); - legendTextAttr.setAutoShrink(true); - legend->setTextAttributes(legendTextAttr); - - legendTextAttr = KDChart::TextAttributes(legend->titleTextAttributes()); - legendTextAttr.setFontSize(64); - legendTextAttr.setAutoShrink(true); - legend->setTitleTextAttributes(legendTextAttr); + _categoriesValues[i] = 0.0; + + _vbox3->addWidget(_costRepartitionBanner); _vbox2->addLayout(hbox); _hbox2->addLayout(_vbox2); vbox->addLayout(_hbox2); _hbox2->addLayout(_vbox3); - _hbox2->addWidget(_pie); OnRangeChange(0); @@ -215,8 +151,8 @@ void StatsPanel::UpdateStats(int monthFrom, int yearFrom, int monthTo, int yearT std::vector::iterator accountIt; std::map::iterator categoriesIt; std::map >::iterator accountYearIt; - int total, non_fix; - int account, size, i, a, b, percents, nbDays; + int total; + int account, size, i, a, b, nbDays; QString value, v; User* user = _kiss->GetUser(); QDate date; @@ -363,42 +299,13 @@ void StatsPanel::UpdateStats(int monthFrom, int yearFrom, int monthTo, int yearT _vbox2->addWidget(_plot); total = 0.0; - for(categoriesIt = categories.begin(); categoriesIt != categories.end(); categoriesIt++) - total += categoriesIt->second; - for(i=0, categoriesIt = categories.begin(); categoriesIt != categories.end(); categoriesIt++, i++) { _categoriesValues[_categoriesIndexes[categoriesIt->first]] = categoriesIt->second; - if (total) - percents = (categoriesIt->second*100)/total; - else - percents = 0; - value = v.sprintf("%0.2lf (%02d%%)", (double) categoriesIt->second/100, percents); - if (i) - { - _statsGrid->setItem(_categoriesIndexes[categoriesIt->first]+1, 1, new QTableWidgetItem(value)); - _statsGrid->item(_categoriesIndexes[categoriesIt->first]+1, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - } - else - { - _statsGrid->setItem(_categoriesIndexes[categoriesIt->first], 1, new QTableWidgetItem(value)); - _statsGrid->item(_categoriesIndexes[categoriesIt->first], 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); - } - QVector< double > vec; - vec << (double) _categoriesValues[_categoriesIndexes[categoriesIt->first]] / 100; - _pie->setDataset(_categoriesIndexes[categoriesIt->first], vec, _categories[_categoriesIndexes[categoriesIt->first]]); + total += categoriesIt->second; } - non_fix = total - _categoriesValues[0]; - - if (total) - percents = (non_fix*100)/total; - else - percents = 0; - value = v.sprintf("%0.2lf (%02d%%)", (double)non_fix/100, percents); - _statsGrid->setItem(1, 1, new QTableWidgetItem(value)); - - _statsGrid->resizeColumnsToContents(); + _costRepartitionBanner->UpdateCosts(_categoriesValues, total); layout(); } @@ -424,6 +331,7 @@ void StatsPanel::OnRangeChange(int index) return; } + _costRepartitionBanner->Reset(); UpdateStats(monthFrom, yearFrom, monthTo, yearTo); } diff --git a/src/view/StatsPanel.hpp b/src/view/StatsPanel.hpp index ffa418b..67164c4 100644 --- a/src/view/StatsPanel.hpp +++ b/src/view/StatsPanel.hpp @@ -22,6 +22,7 @@ #include #include +#include "CostRepartitionBanner.hpp" #include "view.hpp" #include @@ -44,8 +45,7 @@ private slots: private: QCalendarWidget* _calendarFrom, *_calendarTo; QComboBox* _monthFrom, *_yearFrom, *_monthTo, *_yearTo; - QTableWidget *_statsGrid; - KDChart::Widget* _pie; + CostRepartitionBanner* _costRepartitionBanner; int *_categoriesValues; //CategorySimpleDataset* _dataset; KDChart::Widget *_plot ; From d6ef8aebdb74f40f6a3964ba5f6411471374fed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 26 Feb 2013 16:04:27 +0100 Subject: [PATCH 22/23] Add cost repartition to SearchPanel --- src/view/CostRepartitionBanner.cpp | 1 + src/view/SearchPanel.cpp | 58 ++++++++++++++++++++++++++++++ src/view/SearchPanel.hpp | 7 ++++ 3 files changed, 66 insertions(+) diff --git a/src/view/CostRepartitionBanner.cpp b/src/view/CostRepartitionBanner.cpp index 1678570..4a66950 100644 --- a/src/view/CostRepartitionBanner.cpp +++ b/src/view/CostRepartitionBanner.cpp @@ -105,6 +105,7 @@ void CostRepartitionBanner::Reset() _statsGrid->setItem(1, 0, new QTableWidgetItem(_("Non fix"))); _statsGrid->setItem(1, 1, new QTableWidgetItem("")); + _statsGrid->item(1, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); for(i=0; i::iterator accountIt; std::vector::iterator categoryIt; + int i; + User* user = _kiss->GetUser(); QVBoxLayout *vbox = new QVBoxLayout; QVBoxLayout *vbox2 = new QVBoxLayout; @@ -56,12 +58,26 @@ SearchPanel::SearchPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : connect(_changeCategoryButton, SIGNAL(clicked()), this, SLOT(OnButtonChangeCategory())); connect(_renameButton, SIGNAL(clicked()), this, SLOT(OnButtonRename())); + _categories = new QString[user->GetCategoriesNumber()] ; + _categoriesValues = new int[user->GetCategoriesNumber()] ; + for(i=0, categoryIt = user->_categories.begin(); + categoryIt != user->_categories.end(); + categoryIt++, i++) + { + _categoriesIndexes[categoryIt->id] = i; + _categories[i] = _(categoryIt->name.toStdString().c_str()) ; + } + + _costRepartitionBanner = new CostRepartitionBanner(_kiss, this, _categories); + vbox2->addWidget(_changeAccountButton); vbox2->addWidget(_changeCategoryButton); vbox2->addWidget(_renameButton); hbox->addLayout(vbox2); + hbox->addWidget(_costRepartitionBanner); + vbox->addLayout(hbox, 2); } @@ -79,6 +95,40 @@ QString SearchPanel::GetToolTip() return _("Search"); } +void SearchPanel::UpdateCostRepartition() +{ + int i; + User* user = _kiss->GetUser(); + double total=0.0; + std::vector::iterator it; + Account account; + Operation op; + + _costRepartitionBanner->Reset(); + + for (i=0; iGetCategoriesNumber(); i++) + _categoriesValues[i] = 0.0; + + for(it=_operations->begin(); it!=_operations->end(); it++) + { + if (it->meta) continue; + + op = *it; + + account = user->GetAccount(op.account); + + if (account.blocked && op.transfert && op.amount > 0) + op.amount = -op.amount; + + if (op.amount >= 0) continue; + + _categoriesValues[_categoriesIndexes[op.category]] -= op.amount; + total -= op.amount; + } + + _costRepartitionBanner->UpdateCosts(_categoriesValues, total); +} + void SearchPanel::OnEnter(void* caller) { SearchPanel* _this = (SearchPanel*) caller; @@ -111,6 +161,8 @@ void SearchPanel::OnButtonSearch() _wxUI->setEnabled(true); _kiss->setOverrideCursor(QCursor(Qt::ArrowCursor)); + UpdateCostRepartition(); + _wxUI->layout(); } @@ -148,6 +200,8 @@ void SearchPanel::OnButtonChangeAccount() _grid->MassUpdate(rows, true, ChangeAccount, params); + UpdateCostRepartition(); + _wxUI->NeedReload(); } @@ -196,6 +250,8 @@ void SearchPanel::OnButtonChangeCategory() _grid->MassUpdate(rows, true, ChangeCategory, params); + UpdateCostRepartition(); + _wxUI->NeedReload(); } @@ -222,6 +278,8 @@ void SearchPanel::OnButtonRename() _grid->MassUpdate(rows, false, ChangeName, params); + UpdateCostRepartition(); + _wxUI->NeedReload(); } diff --git a/src/view/SearchPanel.hpp b/src/view/SearchPanel.hpp index b7bd531..da643fe 100644 --- a/src/view/SearchPanel.hpp +++ b/src/view/SearchPanel.hpp @@ -26,6 +26,7 @@ #include "grid/GridAccount.hpp" #include "AccountPanel.hpp" #include "SearchBanner.hpp" +#include "CostRepartitionBanner.hpp" #include @@ -53,9 +54,15 @@ private slots: void OnButtonRename(); private: + void UpdateCostRepartition(); + std::vector *_operations; SearchBanner* _banner; GridAccount *_grid; + CostRepartitionBanner *_costRepartitionBanner; + QString* _categories; + int *_categoriesValues; + std::map _categoriesIndexes; QPushButton* _searchButton, *_renameButton, *_changeAccountButton, *_changeCategoryButton; static void OnEnter(void* caller); From 68f2294b96721d59616c664c2317ba9938d7c3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 26 Feb 2013 16:06:57 +0100 Subject: [PATCH 23/23] Update ChangeLog --- ChangeLog | 4 +++- TODO | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29e9771..efb3cdf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,17 @@ -v0.4 (17/02/2013) +v0.4 (26/02/2013) ** User ** Add icons for low resolution screens Sort categories using translated names Set DateFrom to first of month for SearchBanner Add CSV export + Add Cost repartition statistics to SearchBanner ** Dev ** Primitive handle of low resolution screens Rework GridAccount Simplify UpdateNextMonths function Add "create_if_not_exsits" to Database::GetAccountAmount + Add CostRepartitionBanner ** Bugs ** Remove some bugs in GridAccount diff --git a/TODO b/TODO index 8b2adaf..7a02502 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,9 @@ -Version 0.4 +Version 0.5 Using tabulation to navigate throw interface (Search Panel) Choosing accounts & categories position -Cool for 0.5: +Cool for 0.6: Database auto saving at startup Use caches for created panels (avoid destroying/creating panels for nothing) Add search function to web view @@ -18,6 +18,7 @@ More translations Printing (maybe in xml/html) Refactor web view code Plugins ? +Qt 5 =============================================================== Will not be implemented