From d25230f523abd3a3efc103f39fe262e4cf175558 Mon Sep 17 00:00:00 2001 From: lafricain79 Date: Fri, 20 Mar 2026 11:22:51 +0100 Subject: [PATCH] feat: convert bookmarks to tags with color highlighting - Add COL_COLOR column to bookmark tree store (bookmarks_treeview.h/c) - Add color attribute to XML folder nodes (xml.c/h) - New folder dialog with color picker (ui/folder.gtkbuilder, ui/folder.glade) - Tag color saved and restored from bookmarks.xml - Verse highlighting in Bible text using tag color (display.cc) - Text color auto-adjusted for dark backgrounds (luminance) - Multi-reference support: semicolons, commas, verse ranges - Popup menu for multi-reference bookmarks navigation - Drag and drop reordering enabled by default - Cairo color dot in treeview for tagged folders - Current verse green highlight disabled when tag color present - Fix bookmark folder labels localization: gettext now initialized before default bookmarks are created, so folder names (Personal, What must I do to be saved?, etc.) are properly translated on first run Closes #968 Closes #685 --- po/POTFILES.in | 1 + po/fr.po | 465 +++++++++++++++++++---------------- po/xiphos.pot | 449 +++++++++++++++++---------------- src/gtk/bookmark_dialog.c | 127 ++++++---- src/gtk/bookmarks_menu.c | 370 ++++++++++++++++++---------- src/gtk/bookmarks_treeview.c | 324 +++++++++++++++++++++--- src/gtk/utilities.c | 23 +- src/gui/bookmarks_menu.h | 4 + src/gui/bookmarks_treeview.h | 6 + src/main/display.cc | 174 ++++++++++++- src/main/main.c | 22 ++ src/main/settings.c | 3 +- src/main/xml.c | 57 +++++ src/main/xml.h | 4 + ui/CMakeLists.txt | 2 + ui/folder.gtkbuilder | 152 ++++++++++++ win32/xc-xiphos-win.sh | 3 +- 17 files changed, 1553 insertions(+), 633 deletions(-) create mode 100644 ui/folder.gtkbuilder diff --git a/po/POTFILES.in b/po/POTFILES.in index c7940a3ed..978073f61 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -93,6 +93,7 @@ src/xiphos_html/xiphos_html.c ## Glade files ui/bookmarks.glade [type: gettext/glade]ui/bookmarks.gtkbuilder +[type: gettext/glade]ui/folder.gtkbuilder [type: gettext/glade]ui/editor_link_dialog.gtkbuilder ui/editor_note.xml ui/editor_studypad.xml diff --git a/po/fr.po b/po/fr.po index 48c997ec1..636f35517 100644 --- a/po/fr.po +++ b/po/fr.po @@ -26,8 +26,8 @@ msgid "" msgstr "" "Project-Id-Version: Xiphos 4.0.7\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-03-11 22:00+0100\n" -"PO-Revision-Date: 2026-03-08 17:03+0100\n" +"POT-Creation-Date: 2026-03-20 18:05+0100\n" +"PO-Revision-Date: 2026-03-20 18:08+0100\n" "Last-Translator: Cyrille \n" "Language-Team: none\n" "Language: fr\n" @@ -192,7 +192,7 @@ msgstr "" "Si vous n’enregistrez pas, les modifications seront définitivement perdues." #: ../src/editor/slib-editor.c:1071 ../src/editor/webkit_editor.c:1236 -#: ../ui/xi-menus.glade.h:63 ../ui/xi-menus-popup.gtkbuilder.h:39 +#: ../ui/xi-menus.glade.h:63 ../ui/xi-menus-popup.gtkbuilder.h:40 msgid "File" msgstr "Fichier" @@ -252,13 +252,13 @@ msgid "Daily Devotion" msgstr "Lectures du jour" #: ../src/gtk/about_modules.c:458 ../src/gtk/mod_mgr.c:1616 -#: ../src/gtk/utilities.c:609 ../src/main/sidebar.cc:1085 +#: ../src/gtk/utilities.c:612 ../src/main/sidebar.cc:1085 #: ../src/main/sidebar.cc:1087 msgid "Maps" msgstr "Cartes" #: ../src/gtk/about_modules.c:460 ../src/gtk/mod_mgr.c:1622 -#: ../src/gtk/utilities.c:615 ../src/main/sidebar.cc:1096 +#: ../src/gtk/utilities.c:618 ../src/main/sidebar.cc:1096 #: ../src/main/sidebar.cc:1098 msgid "Images" msgstr "Images" @@ -510,80 +510,86 @@ msgstr "" "Tous nos remerciements vont à Troy Griffitts et toutes\n" "les autres personnes qui font vivre le Projet SWORD." -#. info->stock_icon = GTK_STOCK_OPEN; -#: ../src/gtk/bookmark_dialog.c:163 ../src/gtk/bookmarks_menu.c:361 -#: ../src/gtk/bookmarks_menu.c:653 ../src/gtk/bookmarks_menu.c:753 -#: ../src/gtk/bookmarks_treeview.c:138 ../ui/editor_studypad.xml.h:15 -#: ../ui/xi-menus.glade.h:60 ../ui/xi-menus-popup.gtkbuilder.h:36 -msgid "Bookmark" -msgstr "Signet" - -#: ../src/gtk/bookmark_dialog.c:165 ../src/gtk/bookmarks_menu.c:755 -#: ../src/gtk/bookmarks_treeview.c:139 -msgid "Enter Folder Name" -msgstr "Saisir le nom du dossier" - -#: ../src/gtk/bookmark_dialog.c:167 ../src/gtk/bookmarks_menu.c:757 -msgid "Folder Name" -msgstr "Nom du dossier" +#: ../src/gtk/bookmark_dialog.c:178 +msgid "New Tag" +msgstr "Nouvelle étiquette" -#: ../src/gtk/bookmark_dialog.c:168 ../src/gtk/bookmarks_menu.c:758 -#: ../src/gtk/bookmarks_treeview.c:141 -msgid "Folder: " -msgstr "Dossier : " - -#: ../src/gtk/bookmarks_menu.c:200 +#: ../src/gtk/bookmarks_menu.c:208 msgid "Specify bookmarks file" msgstr "Spécifie le fichier des signets" -#: ../src/gtk/bookmarks_menu.c:350 ../ui/xi-menus.glade.h:65 +#: ../src/gtk/bookmarks_menu.c:372 +msgid "Edit Tag" +msgstr "Éditer l'étiquette" + +#: ../src/gtk/bookmarks_menu.c:413 ../ui/xi-menus.glade.h:65 #: ../ui/xi-menus-popup.gtkbuilder.h:29 msgid "Edit" msgstr "Édition" -#: ../src/gtk/bookmarks_menu.c:364 -msgid "Folder name: " -msgstr "Nom du dossier : " +#: ../src/gtk/bookmarks_menu.c:414 ../src/gtk/bookmarks_menu.c:681 +#: ../src/gtk/bookmarks_treeview.c:139 ../ui/editor_studypad.xml.h:15 +#: ../ui/xi-menus.glade.h:60 ../ui/xi-menus-popup.gtkbuilder.h:37 +msgid "Bookmark" +msgstr "Signet" -#: ../src/gtk/bookmarks_menu.c:367 +#: ../src/gtk/bookmarks_menu.c:416 msgid "Bookmark name: " msgstr "Nom du signet : " -#: ../src/gtk/bookmarks_menu.c:370 ../src/gtk/bookmarks_menu.c:661 +#: ../src/gtk/bookmarks_menu.c:420 ../src/gtk/bookmarks_menu.c:689 msgid "Verse: " msgstr "Verset : " -#: ../src/gtk/bookmarks_menu.c:371 ../src/gtk/bookmarks_menu.c:662 +#: ../src/gtk/bookmarks_menu.c:421 ../src/gtk/bookmarks_menu.c:690 msgid "Module: " msgstr "Module : " -#: ../src/gtk/bookmarks_menu.c:493 +#: ../src/gtk/bookmarks_menu.c:521 msgid "Remove the selected folder" msgstr "Supprimer le dossier sélectionné" -#: ../src/gtk/bookmarks_menu.c:494 +#: ../src/gtk/bookmarks_menu.c:522 msgid "(and all its contents)?" msgstr "(et tout son contenu) ?" -#: ../src/gtk/bookmarks_menu.c:498 +#: ../src/gtk/bookmarks_menu.c:526 msgid "Remove the selected bookmark" msgstr "Supprimer le signet sélectionné" -#: ../src/gtk/bookmarks_menu.c:654 +#: ../src/gtk/bookmarks_menu.c:682 msgid "Add" msgstr "Ajouter" -#: ../src/gtk/bookmarks_menu.c:660 +#: ../src/gtk/bookmarks_menu.c:688 msgid "Label: " msgstr "Étiquette : " -#: ../src/gtk/bookmarks_treeview.c:102 ../src/gtk/export_bookmarks.c:172 +#: ../src/gtk/bookmarks_menu.c:788 ../ui/bookmarks.glade.h:4 +#: ../ui/bookmarks.gtkbuilder.h:4 ../ui/xi-menus.glade.h:122 +#: ../ui/xi-menus-popup.gtkbuilder.h:5 +msgid "New Folder" +msgstr "Nouveau dossier" + +#: ../src/gtk/bookmarks_menu.c:901 +msgid "Choose folder color" +msgstr "Choisir une couleur de dossier" + +#: ../src/gtk/bookmarks_treeview.c:103 ../src/gtk/export_bookmarks.c:172 #: ../src/gtk/export_bookmarks.c:229 #, c-format msgid "Search result: %s" msgstr "Résultat de la requête : %s" -#: ../src/gtk/bookmarks_treeview.c:747 +#: ../src/gtk/bookmarks_treeview.c:140 +msgid "Enter Folder Name" +msgstr "Saisir le nom du dossier" + +#: ../src/gtk/bookmarks_treeview.c:142 +msgid "Folder: " +msgstr "Dossier : " + +#: ../src/gtk/bookmarks_treeview.c:834 msgid "" "Opening a multi-reference bookmark in\n" "separate tabs is not supported." @@ -591,8 +597,8 @@ msgstr "" "L’ouverture d’un signet avec de multiples références dans\n" "un onglet séparé n’est pas supporté." -#: ../src/gtk/bookmarks_treeview.c:850 ../src/gtk/sidebar.c:1480 -#: ../src/gtk/sidebar.c:1532 +#: ../src/gtk/bookmarks_treeview.c:1115 ../src/gtk/sidebar.c:1540 +#: ../src/gtk/sidebar.c:1592 msgid "Bookmarks" msgstr "Signets" @@ -633,25 +639,25 @@ msgstr "Xiphos :" msgid "Close _without Saving" msgstr "Ferme sans enre_gistrer" -#: ../src/gtk/dictlex.c:378 +#: ../src/gtk/dictlex.c:379 msgid "Do sidebar search for this Strong's number" msgstr "" "Effectuer une recherche dans la barre latérale pour ce numéro de Strong" -#: ../src/gtk/dictlex.c:402 +#: ../src/gtk/dictlex.c:403 msgid "Go back in history" msgstr "Retourner en arrière dans l'historique" -#: ../src/gtk/dictlex.c:417 +#: ../src/gtk/dictlex.c:418 msgid "Go forward in history" msgstr "Avancer dans l'historique" -#: ../src/gtk/dictlex.c:623 +#: ../src/gtk/dictlex.c:628 msgid "Click to choose a date" msgstr "Cliquer pour choisir une date" #: ../src/gtk/export_bookmarks.c:175 ../src/gtk/export_bookmarks.c:232 -#: ../src/gtk/sidebar.c:1502 ../src/gtk/sidebar.c:1550 +#: ../src/gtk/sidebar.c:1562 ../src/gtk/sidebar.c:1610 #, c-format msgid "Verse List" msgstr "_Versets" @@ -790,8 +796,8 @@ msgstr "Xiphos - Logiciel d’étude biblique" msgid "Open a new tab" msgstr "Ouvre un nouvel onglet" -#: ../src/gtk/main_window.c:1164 ../src/gtk/sidebar.c:578 -#: ../src/gtk/sidebar.c:583 ../src/main/sidebar.cc:655 +#: ../src/gtk/main_window.c:1164 ../src/gtk/sidebar.c:579 +#: ../src/gtk/sidebar.c:596 ../src/main/sidebar.cc:655 #: ../src/main/sidebar.cc:1020 ../src/main/sidebar.cc:1021 #: ../src/main/sidebar.cc:1022 msgid "Standard View" @@ -1010,7 +1016,7 @@ msgstr "Préparation à la suppression" msgid "Removing" msgstr "Suppression de" -#: ../src/gtk/mod_mgr.c:193 ../ui/xi-menus.glade.h:161 +#: ../src/gtk/mod_mgr.c:193 ../ui/xi-menus.glade.h:164 #: ../ui/xi-menus-popup.gtkbuilder.h:27 msgid "Remove" msgstr "Enlever" @@ -1174,9 +1180,9 @@ msgstr "Terminé" #: ../src/gtk/mod_mgr.c:1190 ../src/gtk/mod_mgr.c:1192 #: ../src/gtk/mod_mgr.c:1302 ../src/gtk/mod_mgr.c:1335 -#: ../src/gtk/mod_mgr.c:1337 ../src/gtk/utilities.c:429 -#: ../src/gtk/utilities.c:492 ../src/gtk/utilities.c:494 -#: ../src/gtk/utilities.c:985 ../src/main/sidebar.cc:807 +#: ../src/gtk/mod_mgr.c:1337 ../src/gtk/utilities.c:432 +#: ../src/gtk/utilities.c:495 ../src/gtk/utilities.c:497 +#: ../src/gtk/utilities.c:988 ../src/main/sidebar.cc:807 #: ../src/main/sidebar.cc:878 ../src/main/sidebar.cc:880 msgid "Unknown" msgstr "Inconnu" @@ -1198,39 +1204,39 @@ msgstr "" "Modules classés\n" "par type" -#: ../src/gtk/mod_mgr.c:1580 ../src/gtk/utilities.c:571 +#: ../src/gtk/mod_mgr.c:1580 ../src/gtk/utilities.c:574 #: ../src/main/sidebar.cc:1004 ../src/main/sidebar.cc:1006 msgid "Biblical Texts" msgstr "Textes bibliques" -#: ../src/gtk/mod_mgr.c:1586 ../src/gtk/utilities.c:577 +#: ../src/gtk/mod_mgr.c:1586 ../src/gtk/utilities.c:580 #: ../src/main/sidebar.cc:666 ../src/main/sidebar.cc:1030 #: ../src/main/sidebar.cc:1032 msgid "Commentaries" msgstr "Commentaires" -#: ../src/gtk/mod_mgr.c:1592 ../src/gtk/utilities.c:584 +#: ../src/gtk/mod_mgr.c:1592 ../src/gtk/utilities.c:587 #: ../src/main/sidebar.cc:1041 ../src/main/sidebar.cc:1043 msgid "Dictionaries" msgstr "Dictionnaires" -#: ../src/gtk/mod_mgr.c:1598 ../src/gtk/utilities.c:590 +#: ../src/gtk/mod_mgr.c:1598 ../src/gtk/utilities.c:593 #: ../src/main/sidebar.cc:1052 ../src/main/sidebar.cc:1054 msgid "Glossaries" msgstr "Glossaires" -#: ../src/gtk/mod_mgr.c:1604 ../src/gtk/utilities.c:597 +#: ../src/gtk/mod_mgr.c:1604 ../src/gtk/utilities.c:600 #: ../src/main/sidebar.cc:1063 ../src/main/sidebar.cc:1065 msgid "Daily Devotionals" msgstr "Calendriers bibliques" -#: ../src/gtk/mod_mgr.c:1610 ../src/gtk/utilities.c:603 +#: ../src/gtk/mod_mgr.c:1610 ../src/gtk/utilities.c:606 #: ../src/main/sidebar.cc:674 ../src/main/sidebar.cc:1074 #: ../src/main/sidebar.cc:1076 msgid "General Books" msgstr "Livres généraux" -#: ../src/gtk/mod_mgr.c:1628 ../src/gtk/utilities.c:621 +#: ../src/gtk/mod_mgr.c:1628 ../src/gtk/utilities.c:624 #: ../src/main/sidebar.cc:1107 ../src/main/sidebar.cc:1109 msgid "Cult/Unorthodox" msgstr "Hétérodoxie" @@ -1251,8 +1257,8 @@ msgstr "Mise à jour disponible" msgid "Uninstalled" msgstr "Non installé" -#: ../src/gtk/mod_mgr.c:1653 ../src/gtk/sidebar.c:594 -#: ../src/gtk/utilities.c:629 ../src/main/prayerlists.cc:233 +#: ../src/gtk/mod_mgr.c:1653 ../src/gtk/sidebar.c:607 +#: ../src/gtk/utilities.c:632 ../src/main/prayerlists.cc:233 #: ../src/main/sidebar.cc:1118 ../src/main/sidebar.cc:1120 msgid "Prayer List/Journal" msgstr "Liste de prières / Journal" @@ -1315,7 +1321,7 @@ msgid "Choose" msgstr "Sélection" #: ../src/gtk/mod_mgr.c:2025 ../src/gtk/preferences_dialog.c:2254 -#: ../src/gtk/sidebar.c:1512 ../src/gtk/sidebar.c:1558 +#: ../src/gtk/sidebar.c:1572 ../src/gtk/sidebar.c:1618 msgid "Modules" msgstr "Modules" @@ -1454,12 +1460,12 @@ msgid "Detach/Attach" msgstr "Détacher/Attacher" #: ../src/gtk/parallel_view.c:117 ../ui/xi-menus.glade.h:68 -#: ../ui/xi-menus-popup.gtkbuilder.h:43 +#: ../ui/xi-menus-popup.gtkbuilder.h:44 msgid "Module Options" msgstr "Options du module" -#: ../src/gtk/parallel_view.c:216 ../src/gtk/sidebar.c:578 -#: ../src/gtk/sidebar.c:583 ../src/gtk/tabbed_browser.c:239 +#: ../src/gtk/parallel_view.c:216 ../src/gtk/sidebar.c:579 +#: ../src/gtk/sidebar.c:596 ../src/gtk/tabbed_browser.c:239 #: ../src/main/sidebar.cc:638 ../src/main/sidebar.cc:1012 #: ../src/main/sidebar.cc:1013 ../src/main/sidebar.cc:1014 msgid "Parallel View" @@ -1495,9 +1501,9 @@ msgstr "BibleSync : %s (mot de passe \"%s\")." msgid "Disabled" msgstr "Désactivé" -#: ../src/gtk/preferences_dialog.c:1005 ../src/main/xml.c:96 +#: ../src/gtk/preferences_dialog.c:1005 ../src/main/xml.c:97 msgid "Personal" -msgstr "Notes personnelles" +msgstr "Personnelles" #: ../src/gtk/preferences_dialog.c:1007 msgid "Speaker" @@ -1735,7 +1741,7 @@ msgstr "" msgid "Module is neither Bible nor commentary" msgstr "Le module n’est ni une Bible ni un commentaire" -#: ../src/gtk/search_dialog.c:1212 ../src/gtk/sidebar.c:946 +#: ../src/gtk/search_dialog.c:1212 ../src/gtk/sidebar.c:959 msgid "BibleSync is not active for transmit." msgstr "BibleSync n’est pas actif pour émission." @@ -1815,23 +1821,23 @@ msgstr "Basse" msgid "Upper" msgstr "Haute" -#: ../src/gtk/sidebar.c:806 +#: ../src/gtk/sidebar.c:819 msgid "Open module in editor?" msgstr "Ouvrir le module dans l’éditeur ?" -#: ../src/gtk/sidebar.c:807 +#: ../src/gtk/sidebar.c:820 msgid "If no, it will open for display only." msgstr "Si la réponse est négative, il sera ouvert en lecture seulement." -#: ../src/gtk/sidebar.c:907 +#: ../src/gtk/sidebar.c:920 msgid "Paste verse references" msgstr "Coller les références de verset" -#: ../src/gtk/sidebar.c:909 +#: ../src/gtk/sidebar.c:922 msgid "List:" msgstr "Liste :" -#: ../src/gtk/sidebar.c:1491 ../src/gtk/sidebar.c:1541 +#: ../src/gtk/sidebar.c:1551 ../src/gtk/sidebar.c:1601 msgid "Search" msgstr "Rechercher" @@ -1861,55 +1867,55 @@ msgstr "Nouveau nom" msgid "Remove the selected item" msgstr "Supprimer l’élément sélectionné" -#: ../src/gtk/utilities.c:80 +#: ../src/gtk/utilities.c:81 msgid "January" msgstr "Janvier" -#: ../src/gtk/utilities.c:81 +#: ../src/gtk/utilities.c:82 msgid "February" msgstr "Février" -#: ../src/gtk/utilities.c:82 +#: ../src/gtk/utilities.c:83 msgid "March" msgstr "Mars" -#: ../src/gtk/utilities.c:83 +#: ../src/gtk/utilities.c:84 msgid "April" msgstr "Avril" -#: ../src/gtk/utilities.c:84 +#: ../src/gtk/utilities.c:85 msgid "May" msgstr "Mai" -#: ../src/gtk/utilities.c:85 +#: ../src/gtk/utilities.c:86 msgid "June" msgstr "Juin" -#: ../src/gtk/utilities.c:86 +#: ../src/gtk/utilities.c:87 msgid "July" msgstr "Juillet" -#: ../src/gtk/utilities.c:87 +#: ../src/gtk/utilities.c:88 msgid "August" msgstr "Août" -#: ../src/gtk/utilities.c:88 +#: ../src/gtk/utilities.c:89 msgid "September" msgstr "Septembre" -#: ../src/gtk/utilities.c:89 +#: ../src/gtk/utilities.c:90 msgid "October" msgstr "Octobre" -#: ../src/gtk/utilities.c:90 +#: ../src/gtk/utilities.c:91 msgid "November" msgstr "Novembre" -#: ../src/gtk/utilities.c:91 +#: ../src/gtk/utilities.c:92 msgid "December" msgstr "Décembre" -#: ../src/gtk/utilities.c:2021 +#: ../src/gtk/utilities.c:2024 msgid "" "An image file's size could not be determined.\n" "Xiphos cannot resize images to fit window." @@ -2030,14 +2036,14 @@ msgstr "" "\n" "UUID : " -#: ../src/main/display.cc:89 +#: ../src/main/display.cc:90 msgid "" "

This module has no content at this point.
" msgstr "" "

Ce module n’a aucun contenu à cette référence." -#: ../src/main/display.cc:259 +#: ../src/main/display.cc:260 #, c-format msgid "" "Improperly encoded personal annotation label:\n" @@ -2046,8 +2052,8 @@ msgstr "" "Ce nom d’annotation personnelle est improprement formé :\n" "’%s’" -#: ../src/main/display.cc:1214 ../src/main/display.cc:1271 -#: ../src/main/display.cc:1312 ../ui/export-dialog.glade.h:14 +#: ../src/main/display.cc:1215 ../src/main/display.cc:1272 +#: ../src/main/display.cc:1313 ../ui/export-dialog.glade.h:14 #: ../ui/export-dialog.gtkbuilder.h:14 msgid "Chapter" msgstr "Chapitre" @@ -2056,23 +2062,23 @@ msgstr "Chapitre" msgid "Xiphos does not understand more than one argument." msgstr "Xiphos n’accepte pas plus d’un argument." -#: ../src/main/main.c:258 +#: ../src/main/main.c:280 msgid "Initiating HTML" msgstr "Initialisation HTML" -#: ../src/main/main.c:263 +#: ../src/main/main.c:285 msgid "Building Interface" msgstr "Construction de l’interface" -#: ../src/main/main.c:266 +#: ../src/main/main.c:288 msgid "Starting Sword" msgstr "Démarrage de Sword" -#: ../src/main/main.c:269 +#: ../src/main/main.c:291 msgid "Loading Settings" msgstr "Chargement des préférences" -#: ../src/main/main.c:272 +#: ../src/main/main.c:294 msgid "Displaying Xiphos" msgstr "Affichage de Xiphos" @@ -2111,69 +2117,69 @@ msgid "Unknown parallel module: " msgstr "Module parallèle inconnu : " #: ../src/main/parallel_view.cc:361 ../ui/xi-menus.glade.h:73 -#: ../ui/xi-menus-popup.gtkbuilder.h:48 +#: ../ui/xi-menus-popup.gtkbuilder.h:49 msgid "Strong's Numbers" msgstr "Nombres de Strong" #: ../src/main/parallel_view.cc:370 ../ui/search-dialog.glade.h:102 #: ../ui/search-dialog.gtkbuilder.h:101 ../ui/xi-menus.glade.h:76 -#: ../ui/xi-menus-popup.gtkbuilder.h:51 +#: ../ui/xi-menus-popup.gtkbuilder.h:52 msgid "Footnotes" msgstr "Notes de bas de page" #: ../src/main/parallel_view.cc:379 ../ui/search-dialog.glade.h:99 #: ../ui/search-dialog.gtkbuilder.h:98 ../ui/xi-menus.glade.h:75 -#: ../ui/xi-menus-popup.gtkbuilder.h:50 +#: ../ui/xi-menus-popup.gtkbuilder.h:51 msgid "Morphological Tags" msgstr "Étiquettes morphologiques" #: ../src/main/parallel_view.cc:388 ../ui/xi-menus.glade.h:81 -#: ../ui/xi-menus-popup.gtkbuilder.h:55 +#: ../ui/xi-menus-popup.gtkbuilder.h:56 msgid "Hebrew Vowel Points" msgstr "Ponctuation des voyelles en hébreu" #: ../src/main/parallel_view.cc:397 ../ui/xi-menus.glade.h:82 -#: ../ui/xi-menus-popup.gtkbuilder.h:56 +#: ../ui/xi-menus-popup.gtkbuilder.h:57 msgid "Hebrew Cantillation" msgstr "Vocalisations en hébreu" #: ../src/main/parallel_view.cc:406 ../ui/xi-menus.glade.h:80 -#: ../ui/xi-menus-popup.gtkbuilder.h:54 +#: ../ui/xi-menus-popup.gtkbuilder.h:55 msgid "Greek Accents" msgstr "Accents grecs" #: ../src/main/parallel_view.cc:415 ../ui/xi-menus.glade.h:77 -#: ../ui/xi-menus-popup.gtkbuilder.h:52 +#: ../ui/xi-menus-popup.gtkbuilder.h:53 msgid "Cross-references" msgstr "Références croisées" #: ../src/main/parallel_view.cc:424 ../ui/xi-menus.glade.h:74 -#: ../ui/xi-menus-popup.gtkbuilder.h:49 +#: ../ui/xi-menus-popup.gtkbuilder.h:50 msgid "Lemmas" msgstr "Lemmes" #: ../src/main/parallel_view.cc:433 ../ui/xi-menus.glade.h:70 -#: ../ui/xi-menus-popup.gtkbuilder.h:45 +#: ../ui/xi-menus-popup.gtkbuilder.h:46 msgid "Headings" msgstr "Titres" #: ../src/main/parallel_view.cc:443 ../ui/xi-menus.glade.h:71 -#: ../ui/xi-menus-popup.gtkbuilder.h:46 +#: ../ui/xi-menus-popup.gtkbuilder.h:47 msgid "Italic Headings" msgstr "Titres en italique" #: ../src/main/parallel_view.cc:453 ../src/main/parallel_view.cc:542 -#: ../ui/xi-menus.glade.h:91 ../ui/xi-menus-popup.gtkbuilder.h:65 +#: ../ui/xi-menus.glade.h:91 ../ui/xi-menus-popup.gtkbuilder.h:66 msgid "Morpheme Segmentation" msgstr "Segmentation de morphème" #: ../src/main/parallel_view.cc:462 ../ui/xi-menus.glade.h:72 -#: ../ui/xi-menus-popup.gtkbuilder.h:47 +#: ../ui/xi-menus-popup.gtkbuilder.h:48 msgid "Words of Christ in Red" msgstr "Paroles de Christ en rouge" #: ../src/main/parallel_view.cc:471 ../ui/xi-menus.glade.h:83 -#: ../ui/xi-menus-popup.gtkbuilder.h:57 +#: ../ui/xi-menus-popup.gtkbuilder.h:58 msgid "Transliteration" msgstr "Translittération" @@ -2182,32 +2188,32 @@ msgid "Textual Variants" msgstr "Variantes du texte" #: ../src/main/parallel_view.cc:488 ../ui/xi-menus.glade.h:85 -#: ../ui/xi-menus-popup.gtkbuilder.h:59 +#: ../ui/xi-menus-popup.gtkbuilder.h:60 msgid "Primary Reading" msgstr "Lectures principales" #: ../src/main/parallel_view.cc:497 ../ui/xi-menus.glade.h:86 -#: ../ui/xi-menus-popup.gtkbuilder.h:60 +#: ../ui/xi-menus-popup.gtkbuilder.h:61 msgid "Secondary Reading" msgstr "Lectures secondaires" #: ../src/main/parallel_view.cc:506 ../ui/xi-menus.glade.h:87 -#: ../ui/xi-menus-popup.gtkbuilder.h:61 +#: ../ui/xi-menus-popup.gtkbuilder.h:62 msgid "All Readings" msgstr "Toutes les lectures" #: ../src/main/parallel_view.cc:515 ../ui/xi-menus.glade.h:88 -#: ../ui/xi-menus-popup.gtkbuilder.h:62 +#: ../ui/xi-menus-popup.gtkbuilder.h:63 msgid "Transliterated Forms" msgstr "Formes translittérées" #: ../src/main/parallel_view.cc:524 ../ui/xi-menus.glade.h:89 -#: ../ui/xi-menus-popup.gtkbuilder.h:63 +#: ../ui/xi-menus-popup.gtkbuilder.h:64 msgid "Enumerations" msgstr "Énumérations" #: ../src/main/parallel_view.cc:533 ../ui/xi-menus.glade.h:90 -#: ../ui/xi-menus-popup.gtkbuilder.h:64 +#: ../ui/xi-menus-popup.gtkbuilder.h:65 msgid "Glosses" msgstr "Annotations" @@ -2618,7 +2624,7 @@ msgstr "" msgid "Book names and menus may not be translated." msgstr "Les noms de livres et les menus ne seront peut-être pas traduits." -#: ../src/main/sword.cc:1137 ../src/main/sword.cc:1324 +#: ../src/main/sword.cc:1136 ../src/main/sword.cc:1324 #, c-format msgid "" "Module %s has companion modules:\n" @@ -2629,7 +2635,7 @@ msgstr "" "%s.\n" "Voulez-vous les ouvrir également ?%s" -#: ../src/main/sword.cc:1141 ../src/main/sword.cc:1328 +#: ../src/main/sword.cc:1140 ../src/main/sword.cc:1328 msgid "" "\n" "\n" @@ -2697,67 +2703,67 @@ msgstr "Erreur d’aperçu :\n" msgid "Show %s in main window" msgstr "Affiche %s dans la fenêtre principale" -#: ../src/main/xml.c:87 ../src/main/xml.c:443 ../src/main/xml.c:574 +#: ../src/main/xml.c:88 ../src/main/xml.c:500 ../src/main/xml.c:631 #, c-format msgid "Document not created successfully. \n" msgstr "Erreur de création du document. \n" -#: ../src/main/xml.c:99 +#: ../src/main/xml.c:100 msgid "What must I do to be saved?" msgstr "Comment être sauvé ?" -#: ../src/main/xml.c:100 ../src/main/xml.c:101 +#: ../src/main/xml.c:101 ../src/main/xml.c:102 msgid "Acts 16:31" msgstr "Act 16:31" -#: ../src/main/xml.c:102 ../src/main/xml.c:103 +#: ../src/main/xml.c:103 ../src/main/xml.c:104 msgid "Eph 2:8,9" msgstr "Éph 2:8,9" -#: ../src/main/xml.c:104 ../src/main/xml.c:105 +#: ../src/main/xml.c:105 ../src/main/xml.c:106 msgid "Romans 1:16" msgstr "Romains 1:16" -#: ../src/main/xml.c:107 +#: ../src/main/xml.c:108 msgid "What is the Gospel?" msgstr "Qu’est-ce que l’Évangile ?" -#: ../src/main/xml.c:108 ../src/main/xml.c:109 +#: ../src/main/xml.c:109 ../src/main/xml.c:110 msgid "1 Cor 15:1-4" msgstr "1 Cor 15:1-4" -#: ../src/main/xml.c:238 ../src/main/xml.c:384 ../src/main/xml.c:1504 +#: ../src/main/xml.c:295 ../src/main/xml.c:441 ../src/main/xml.c:1561 #, c-format msgid "Document not parsed successfully. \n" msgstr "Erreur de lecture du document. \n" -#: ../src/main/xml.c:244 ../src/main/xml.c:390 ../src/main/xml.c:410 -#: ../src/main/xml.c:1061 ../src/main/xml.c:1391 ../src/main/xml.c:1587 +#: ../src/main/xml.c:301 ../src/main/xml.c:447 ../src/main/xml.c:467 +#: ../src/main/xml.c:1118 ../src/main/xml.c:1448 ../src/main/xml.c:1644 #, c-format msgid "empty document \n" msgstr "document vide \n" -#: ../src/main/xml.c:250 +#: ../src/main/xml.c:307 #, c-format msgid "wrong type, root node != SwordBookmarks\n" msgstr "erreur de type, root node != SwordBookmarks\n" -#: ../src/main/xml.c:396 +#: ../src/main/xml.c:453 #, c-format msgid "wrong type, root node != Copy_Export\n" msgstr "erreur de type, root node !=Copy_Export\n" -#: ../src/main/xml.c:473 +#: ../src/main/xml.c:530 #, c-format msgid "%s
%s
Chapter %d

" msgstr "%s
%s
Chapitre %d

" -#: ../src/main/xml.c:477 +#: ../src/main/xml.c:534 #, c-format msgid "
Chapter %d

" msgstr "
Chapitre %d

" -#: ../src/main/xml.c:480 +#: ../src/main/xml.c:537 #, c-format msgid "" "%s\n" @@ -2770,7 +2776,7 @@ msgstr "" "Chapitre %d\n" "\n" -#: ../src/main/xml.c:483 +#: ../src/main/xml.c:540 #, c-format msgid "" "\n" @@ -2783,12 +2789,12 @@ msgstr "" "Chapitre %d\n" "\n" -#: ../src/main/xml.c:492 +#: ../src/main/xml.c:549 #, c-format msgid "%s%s: %s Chapter %d

" msgstr "%s%s: %s Chapitre %d

" -#: ../src/main/xml.c:495 +#: ../src/main/xml.c:552 #, c-format msgid "" "%s: %s Chapter %d\n" @@ -2797,82 +2803,82 @@ msgstr "" "%s: %s Chapitre %d\n" "\n" -#: ../src/main/xml.c:503 +#: ../src/main/xml.c:560 #, c-format msgid "  [%d]" msgstr "  [%d]" -#: ../src/main/xml.c:506 +#: ../src/main/xml.c:563 #, c-format msgid " [%d]" msgstr " [%d]" -#: ../src/main/xml.c:515 +#: ../src/main/xml.c:572 #, c-format msgid "%s%s (%s %d:%d%s)" msgstr "%s%s (%s %d:%d%s)" -#: ../src/main/xml.c:518 +#: ../src/main/xml.c:575 #, c-format msgid "%s(%s %d:%d%s)%s " msgstr "%s(%s %d:%d%s)%s " -#: ../src/main/xml.c:520 +#: ../src/main/xml.c:577 #, c-format msgid "%s (%s %d:%d%s)" msgstr "%s (%s %d:%d%s)" -#: ../src/main/xml.c:523 +#: ../src/main/xml.c:580 #, c-format msgid "(%s %d:%d%s) %s" msgstr "(%s %d:%d%s) %s" -#: ../src/main/xml.c:531 +#: ../src/main/xml.c:588 #, c-format msgid " %s%s" msgstr " %s%s" -#: ../src/main/xml.c:533 ../src/main/xml.c:537 +#: ../src/main/xml.c:590 ../src/main/xml.c:594 #, c-format msgid "%s(%s %d:%d-%d%s)" msgstr "%s(%s %d:%d-%d%s)" -#: ../src/main/xml.c:535 +#: ../src/main/xml.c:592 #, c-format msgid "(%s %d:%d-%d%s)
" msgstr "(%s %d:%d-%d%s)
" -#: ../src/main/xml.c:540 +#: ../src/main/xml.c:597 #, c-format msgid "(%s %d:%d-%d%s)\n" msgstr "(%s %d:%d-%d%s)\n" -#: ../src/main/xml.c:589 +#: ../src/main/xml.c:646 msgid "Old Testament" msgstr "Ancien Testament" -#: ../src/main/xml.c:591 +#: ../src/main/xml.c:648 msgid "Gen - Mal" msgstr "Ge - Mal" -#: ../src/main/xml.c:597 +#: ../src/main/xml.c:654 msgid "New Testament" msgstr "Nouveau Testament" -#: ../src/main/xml.c:599 +#: ../src/main/xml.c:656 msgid "Mat - Rev" msgstr "Mt - Ap" -#: ../src/main/xml.c:608 +#: ../src/main/xml.c:665 msgid "Sample Module List" msgstr "Exemple de liste de modules" -#: ../src/main/xml.c:1067 ../src/main/xml.c:1397 +#: ../src/main/xml.c:1124 ../src/main/xml.c:1454 #, c-format msgid "wrong type, root node != %s\n" msgstr "erreur de type, root node != %s\n" -#: ../src/main/xml.c:1549 +#: ../src/main/xml.c:1606 #, c-format msgid "" "Save of settings failed! stat %d, size %d\n" @@ -2881,7 +2887,7 @@ msgstr "" "La sauvegarde de la configuration a échouée ! stat %d, taille %d\n" "%s" -#: ../src/main/xml.c:1551 +#: ../src/main/xml.c:1608 msgid "Attempting to revert to previous save." msgstr "Tentative de retour à la sauvegarde précédente." @@ -2897,11 +2903,6 @@ msgstr "Fenêtre de dialogue des signets" msgid "Create new folder" msgstr "Crée un nouveau dossier" -#: ../ui/bookmarks.glade.h:4 ../ui/bookmarks.gtkbuilder.h:4 -#: ../ui/xi-menus.glade.h:122 ../ui/xi-menus-popup.gtkbuilder.h:5 -msgid "New Folder" -msgstr "Nouveau dossier" - #: ../ui/bookmarks.glade.h:5 ../ui/bookmarks.gtkbuilder.h:3 msgid "New ..." msgstr "Nouveau..." @@ -2942,6 +2943,30 @@ msgstr "Entrée Module" msgid "Bookmark Folder Treeview" msgstr "Arborescence Dossier des signets" +#: ../ui/folder.gtkbuilder.h:1 +msgid "Folder" +msgstr "Dossier : " + +#: ../ui/folder.gtkbuilder.h:2 +msgid "Name:" +msgstr "Nom : " + +#: ../ui/folder.gtkbuilder.h:3 +msgid "Tag color:" +msgstr "Étiquette de couleur :" + +#: ../ui/folder.gtkbuilder.h:4 +msgid "Choose a highlight color for this tag group" +msgstr "Choisir une couleur de surlignement pour ce groupe d’étiquettes" + +#: ../ui/folder.gtkbuilder.h:5 +msgid "No color" +msgstr "Pas couleur" + +#: ../ui/folder.gtkbuilder.h:6 +msgid "Remove tag color from this folder" +msgstr "Supprimer l’étiquette de couleur de ce dossier" + # T'es sûr de la traduction? #: ../ui/editor_link_dialog.gtkbuilder.h:2 msgid "Test Link" @@ -3049,7 +3074,7 @@ msgid "New Document" msgstr "Nouveau document" #: ../ui/export-dialog.glade.h:1 ../ui/export-dialog.gtkbuilder.h:1 -#: ../ui/xi-menus.glade.h:62 ../ui/xi-menus-popup.gtkbuilder.h:38 +#: ../ui/xi-menus.glade.h:62 ../ui/xi-menus-popup.gtkbuilder.h:39 msgid "Copy/Export Passage" msgstr "Copier/exporter le passage" @@ -5316,27 +5341,27 @@ msgstr "À propos de _Xiphos" msgid "Learn about Xiphos" msgstr "En savoir plus sur Xiphos" -#: ../ui/xi-menus.glade.h:61 ../ui/xi-menus-popup.gtkbuilder.h:37 +#: ../ui/xi-menus.glade.h:61 ../ui/xi-menus-popup.gtkbuilder.h:38 msgid "Annotate Verse" msgstr "Annoter ce verset" -#: ../ui/xi-menus.glade.h:64 ../ui/xi-menus-popup.gtkbuilder.h:40 +#: ../ui/xi-menus.glade.h:64 ../ui/xi-menus-popup.gtkbuilder.h:41 msgid "Open Module" msgstr "Ouvrir le module" -#: ../ui/xi-menus.glade.h:66 ../ui/xi-menus-popup.gtkbuilder.h:41 +#: ../ui/xi-menus.glade.h:66 ../ui/xi-menus-popup.gtkbuilder.h:42 msgid "Note" msgstr "Note" -#: ../ui/xi-menus.glade.h:67 ../ui/xi-menus-popup.gtkbuilder.h:42 +#: ../ui/xi-menus.glade.h:67 ../ui/xi-menus-popup.gtkbuilder.h:43 msgid "Open in editor" msgstr "Modifier le commentaire" -#: ../ui/xi-menus.glade.h:69 ../ui/xi-menus-popup.gtkbuilder.h:44 +#: ../ui/xi-menus.glade.h:69 ../ui/xi-menus-popup.gtkbuilder.h:45 msgid "Verse Per Line" msgstr "Verset par ligne" -#: ../ui/xi-menus.glade.h:78 ../ui/xi-menus-popup.gtkbuilder.h:53 +#: ../ui/xi-menus.glade.h:78 ../ui/xi-menus-popup.gtkbuilder.h:54 msgid "Footnote/Cross-ref Markers" msgstr "Marques des notes de bas de page et des références croisées" @@ -5344,85 +5369,85 @@ msgstr "Marques des notes de bas de page et des références croisées" msgid "Show non-anonymous markers e.g. \"*n23\"" msgstr "Afficher les marques non-anonymes comme « *n23 »" -#: ../ui/xi-menus.glade.h:84 ../ui/xi-menus-popup.gtkbuilder.h:58 +#: ../ui/xi-menus.glade.h:84 ../ui/xi-menus-popup.gtkbuilder.h:59 msgid "Variants" msgstr "Variantes" -#: ../ui/xi-menus.glade.h:92 ../ui/xi-menus-popup.gtkbuilder.h:66 +#: ../ui/xi-menus.glade.h:92 ../ui/xi-menus-popup.gtkbuilder.h:67 msgid "Image Content" msgstr "Afficher les images" -#: ../ui/xi-menus.glade.h:93 ../ui/xi-menus-popup.gtkbuilder.h:67 +#: ../ui/xi-menus.glade.h:93 ../ui/xi-menus-popup.gtkbuilder.h:68 msgid "Respect Font Faces" msgstr "Respect des polices" -#: ../ui/xi-menus.glade.h:94 ../ui/xi-menus-popup.gtkbuilder.h:68 +#: ../ui/xi-menus.glade.h:94 ../ui/xi-menus-popup.gtkbuilder.h:69 msgid "Display chapter numbers" msgstr "Afficher les numéros de chapitres" -#: ../ui/xi-menus.glade.h:95 ../ui/xi-menus-popup.gtkbuilder.h:69 +#: ../ui/xi-menus.glade.h:95 ../ui/xi-menus-popup.gtkbuilder.h:70 msgid "Commentary by Chapter" msgstr "Commentaire par chapitre" -#: ../ui/xi-menus.glade.h:96 ../ui/xi-menus-popup.gtkbuilder.h:70 +#: ../ui/xi-menus.glade.h:96 ../ui/xi-menus-popup.gtkbuilder.h:71 msgid "Doublespace" msgstr "Double espace" -#: ../ui/xi-menus.glade.h:97 ../ui/xi-menus-popup.gtkbuilder.h:71 +#: ../ui/xi-menus.glade.h:97 ../ui/xi-menus-popup.gtkbuilder.h:72 msgid "Lookup Selection" msgstr "Définition du mot sélectionné" # src/gs_preferences_dlg.c -#: ../ui/xi-menus.glade.h:98 ../ui/xi-menus-popup.gtkbuilder.h:72 +#: ../ui/xi-menus.glade.h:98 ../ui/xi-menus-popup.gtkbuilder.h:73 msgid "Use Current Dictionary" msgstr "Utiliser le dictionnaire en cours" -#: ../ui/xi-menus.glade.h:99 ../ui/xi-menus-popup.gtkbuilder.h:73 +#: ../ui/xi-menus.glade.h:99 ../ui/xi-menus-popup.gtkbuilder.h:74 msgid "Browse in BibleMap.org" msgstr "Consulter la carte sur BibleMap.org" -#: ../ui/xi-menus.glade.h:100 ../ui/xi-menus-popup.gtkbuilder.h:74 +#: ../ui/xi-menus.glade.h:100 ../ui/xi-menus-popup.gtkbuilder.h:75 msgid "Unlock This Module" msgstr "Déverrouiller ce module" -#: ../ui/xi-menus.glade.h:101 ../ui/xi-menus-popup.gtkbuilder.h:75 +#: ../ui/xi-menus.glade.h:101 ../ui/xi-menus-popup.gtkbuilder.h:76 msgid "Display Book Heading" msgstr "Affiche l’entête du livre" -#: ../ui/xi-menus.glade.h:102 ../ui/xi-menus-popup.gtkbuilder.h:76 +#: ../ui/xi-menus.glade.h:102 ../ui/xi-menus-popup.gtkbuilder.h:77 msgid "Display Chapter Heading" msgstr "Affiche l’entête du chapitre" -#: ../ui/xi-menus.glade.h:103 ../ui/xi-menus-popup.gtkbuilder.h:77 +#: ../ui/xi-menus.glade.h:103 ../ui/xi-menus-popup.gtkbuilder.h:78 msgid "Rename Pers.Comm." msgstr "Renommer le com. perso." -#: ../ui/xi-menus.glade.h:104 ../ui/xi-menus-popup.gtkbuilder.h:78 +#: ../ui/xi-menus.glade.h:104 ../ui/xi-menus-popup.gtkbuilder.h:79 msgid "Dump Pers.Comm." msgstr "Quitter le Com. Perso." -#: ../ui/xi-menus.glade.h:105 ../ui/xi-menus-popup.gtkbuilder.h:79 +#: ../ui/xi-menus.glade.h:105 ../ui/xi-menus-popup.gtkbuilder.h:80 msgid "Read Selection Aloud" msgstr "Synthèse vocale du texte sélectionné" -#: ../ui/xi-menus.glade.h:106 ../ui/xi-menus-popup.gtkbuilder.h:94 +#: ../ui/xi-menus.glade.h:106 ../ui/xi-menus-popup.gtkbuilder.h:96 msgid "Save these results as a single bookmark" msgstr "Enregistre ces résultats sous un seul signet" -#: ../ui/xi-menus.glade.h:107 ../ui/xi-menus-popup.gtkbuilder.h:93 +#: ../ui/xi-menus.glade.h:107 ../ui/xi-menus-popup.gtkbuilder.h:95 msgid "Save list as a single bookmark" msgstr "Enregistrer la liste sous un seul signet" -#: ../ui/xi-menus.glade.h:108 ../ui/xi-menus-popup.gtkbuilder.h:96 +#: ../ui/xi-menus.glade.h:108 ../ui/xi-menus-popup.gtkbuilder.h:98 msgid "Save these results as a series of bookmarks in their own folder" msgstr "" "Enregistre ces résultats sous une série de signets dans leur propre dossier" -#: ../ui/xi-menus.glade.h:109 ../ui/xi-menus-popup.gtkbuilder.h:95 +#: ../ui/xi-menus.glade.h:109 ../ui/xi-menus-popup.gtkbuilder.h:97 msgid "Save list as a series of bookmarks" msgstr "Enregistrer la liste dans une série de signets" -#: ../ui/xi-menus.glade.h:110 ../ui/xi-menus-popup.gtkbuilder.h:98 +#: ../ui/xi-menus.glade.h:110 ../ui/xi-menus-popup.gtkbuilder.h:100 msgid "" "Provide a dialog in which to paste a line of verse references, to fill the " "verse list." @@ -5430,21 +5455,21 @@ msgstr "" "Remplit la liste de versets au moyen d’une boîte de dialogue dans laquelle " "sera collée une ligne de références de versets." -#: ../ui/xi-menus.glade.h:111 ../ui/xi-menus-popup.gtkbuilder.h:97 +#: ../ui/xi-menus.glade.h:111 ../ui/xi-menus-popup.gtkbuilder.h:99 msgid "Populate verse list" msgstr "Remplir la liste de versets" -#: ../ui/xi-menus.glade.h:112 ../ui/xi-menus-popup.gtkbuilder.h:100 +#: ../ui/xi-menus.glade.h:112 ../ui/xi-menus-popup.gtkbuilder.h:102 msgid "Push the entire verse list contents directly into the history list." msgstr "" "Place le contenu entier de la liste de versets dans l’historique de " "consultation." -#: ../ui/xi-menus.glade.h:113 ../ui/xi-menus-popup.gtkbuilder.h:99 +#: ../ui/xi-menus.glade.h:113 ../ui/xi-menus-popup.gtkbuilder.h:101 msgid "Preload history from verse list" msgstr "Charger la liste de versets dans l’historique" -#: ../ui/xi-menus.glade.h:114 ../ui/xi-menus-popup.gtkbuilder.h:102 +#: ../ui/xi-menus.glade.h:114 ../ui/xi-menus-popup.gtkbuilder.h:104 msgid "" "Send this verse list via BibleSync to others, if you are in Personal or " "Speaker mode." @@ -5452,11 +5477,11 @@ msgstr "" "Envoie cette liste de versets via BibleSync si vous êtes en mode Personnel " "ou Intervenant." -#: ../ui/xi-menus.glade.h:115 ../ui/xi-menus-popup.gtkbuilder.h:101 +#: ../ui/xi-menus.glade.h:115 ../ui/xi-menus-popup.gtkbuilder.h:103 msgid "Send list via BibleSync" msgstr "Envoyer la liste via BibleSync" -#: ../ui/xi-menus.glade.h:116 ../ui/xi-menus-popup.gtkbuilder.h:103 +#: ../ui/xi-menus.glade.h:116 ../ui/xi-menus-popup.gtkbuilder.h:105 msgid "Export List" msgstr "Exporter la liste" @@ -5556,82 +5581,100 @@ msgstr "" msgid "Open in a separate window" msgstr "Ouvrir dans une fenêtre séparée" -#: ../ui/xi-menus.glade.h:143 ../ui/xi-menus-popup.gtkbuilder.h:81 +#: ../ui/xi-menus.glade.h:143 ../ui/xi-menus-popup.gtkbuilder.h:82 msgid "Create a new simple prayer list" msgstr "Crée une nouvelle liste simple de prières" -#: ../ui/xi-menus.glade.h:144 ../ui/xi-menus-popup.gtkbuilder.h:80 +#: ../ui/xi-menus.glade.h:144 ../ui/xi-menus-popup.gtkbuilder.h:81 msgid "Simple" msgstr "Liste simple" -#: ../ui/xi-menus.glade.h:145 ../ui/xi-menus-popup.gtkbuilder.h:83 +#: ../ui/xi-menus.glade.h:145 ../ui/xi-menus-popup.gtkbuilder.h:84 msgid "Create a new subject prayer list" msgstr "Crée une nouvelle liste de prières organisée par sujets" -#: ../ui/xi-menus.glade.h:146 ../ui/xi-menus-popup.gtkbuilder.h:82 +#: ../ui/xi-menus.glade.h:146 ../ui/xi-menus-popup.gtkbuilder.h:83 msgid "Subject" msgstr "Liste ordonnée par sujet" -#: ../ui/xi-menus.glade.h:147 ../ui/xi-menus-popup.gtkbuilder.h:85 +#: ../ui/xi-menus.glade.h:147 ../ui/xi-menus-popup.gtkbuilder.h:86 msgid "Create a new monthly journal" msgstr "Crée un nouveau journal mensuel" -#: ../ui/xi-menus.glade.h:148 ../ui/xi-menus-popup.gtkbuilder.h:84 +#: ../ui/xi-menus.glade.h:148 ../ui/xi-menus-popup.gtkbuilder.h:85 msgid "Monthly" msgstr "Mensuel" -#: ../ui/xi-menus.glade.h:149 ../ui/xi-menus-popup.gtkbuilder.h:87 +#: ../ui/xi-menus.glade.h:149 ../ui/xi-menus-popup.gtkbuilder.h:88 msgid "Create a new daily journal" msgstr "Crée un nouveau journal quotidien" -#: ../ui/xi-menus.glade.h:150 ../ui/xi-menus-popup.gtkbuilder.h:86 +#: ../ui/xi-menus.glade.h:150 ../ui/xi-menus-popup.gtkbuilder.h:87 msgid "Daily" msgstr "Quotidien" -#: ../ui/xi-menus.glade.h:151 ../ui/xi-menus-popup.gtkbuilder.h:89 +#: ../ui/xi-menus.glade.h:151 ../ui/xi-menus-popup.gtkbuilder.h:90 msgid "Create a new outlined topic" msgstr "Crée un nouveau thème structuré hiérarchiquement" -#: ../ui/xi-menus.glade.h:152 ../ui/xi-menus-popup.gtkbuilder.h:88 +#: ../ui/xi-menus.glade.h:152 ../ui/xi-menus-popup.gtkbuilder.h:89 msgid "Outlined" msgstr "Thème structuré" -#: ../ui/xi-menus.glade.h:153 ../ui/xi-menus-popup.gtkbuilder.h:91 +#: ../ui/xi-menus.glade.h:153 ../ui/xi-menus-popup.gtkbuilder.h:92 msgid "Create a new book/chapter outline" msgstr "Crée un nouvelle trame organisée par Livre/Chapitre de la Bible" -#: ../ui/xi-menus.glade.h:154 ../ui/xi-menus-popup.gtkbuilder.h:90 +#: ../ui/xi-menus.glade.h:154 ../ui/xi-menus-popup.gtkbuilder.h:91 msgid "Book/Chapter" msgstr "Trame Livre/Chapitre" -#: ../ui/xi-menus.glade.h:155 ../ui/xi-menus-popup.gtkbuilder.h:92 +#: ../ui/xi-menus.glade.h:155 ../ui/xi-menus-popup.gtkbuilder.h:93 msgid "Open module in editor or plain display window" msgstr "Ouvre le module dans l’éditeur ou en lecture dans une fenêtre séparée" -#: ../ui/xi-menus.glade.h:156 ../ui/xi-menus-popup.gtkbuilder.h:24 +#: ../ui/xi-menus.glade.h:156 ../ui/xi-menus-popup.gtkbuilder.h:94 +msgid "Open this prayer list in the editor" +msgstr "Ouvre cette liste de prière dans l’éditeur" + +#: ../ui/xi-menus.glade.h:157 +msgid "Open selected module in a separate window" +msgstr "Ouvrir le module sélectionné dans une nouvelle fenêtre" + +#: ../ui/xi-menus.glade.h:158 ../ui/xi-menus-popup.gtkbuilder.h:36 +msgid "Open this personal commentary in the editor" +msgstr "Ouvre le Commentaire Personnel dans l’éditeur" + +#: ../ui/xi-menus.glade.h:159 ../ui/xi-menus-popup.gtkbuilder.h:24 msgid "Add a sub-item" msgstr "Ajoute un sous-élément" -#: ../ui/xi-menus.glade.h:157 ../ui/xi-menus-popup.gtkbuilder.h:23 +#: ../ui/xi-menus.glade.h:160 ../ui/xi-menus-popup.gtkbuilder.h:23 msgid "Add Sub-Item" msgstr "Ajouter un sous-élément" -#: ../ui/xi-menus.glade.h:158 ../ui/xi-menus-popup.gtkbuilder.h:26 +#: ../ui/xi-menus.glade.h:161 ../ui/xi-menus-popup.gtkbuilder.h:26 msgid "Add an item" msgstr "Ajouter un élément" -#: ../ui/xi-menus.glade.h:159 ../ui/xi-menus-popup.gtkbuilder.h:25 +#: ../ui/xi-menus.glade.h:162 ../ui/xi-menus-popup.gtkbuilder.h:25 msgid "Add Item" msgstr "Ajouter un élément" -#: ../ui/xi-menus.glade.h:160 ../ui/xi-menus-popup.gtkbuilder.h:28 +#: ../ui/xi-menus.glade.h:163 ../ui/xi-menus-popup.gtkbuilder.h:28 msgid "Remove this item" msgstr "Supprimer cet élément :" -#: ../ui/xi-menus.glade.h:162 ../ui/xi-menus-popup.gtkbuilder.h:30 +#: ../ui/xi-menus.glade.h:165 ../ui/xi-menus-popup.gtkbuilder.h:30 msgid "Edit this item" msgstr "Éditer cet élément" +#~ msgid "Folder Name" +#~ msgstr "Nom du dossier" + +#~ msgid "Folder name: " +#~ msgstr "Nom du dossier : " + #, c-format #~ msgid "language: %s" #~ msgstr "la langue : %s" diff --git a/po/xiphos.pot b/po/xiphos.pot index 4d5f8bbdd..d65759a13 100644 --- a/po/xiphos.pot +++ b/po/xiphos.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-03-11 22:00+0100\n" +"POT-Creation-Date: 2026-03-20 18:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -168,7 +168,7 @@ msgid "If you don't save, changes will be permanently lost." msgstr "" #: ../src/editor/slib-editor.c:1071 ../src/editor/webkit_editor.c:1236 -#: ../ui/xi-menus.glade.h:63 ../ui/xi-menus-popup.gtkbuilder.h:39 +#: ../ui/xi-menus.glade.h:63 ../ui/xi-menus-popup.gtkbuilder.h:40 msgid "File" msgstr "" @@ -225,13 +225,13 @@ msgid "Daily Devotion" msgstr "" #: ../src/gtk/about_modules.c:458 ../src/gtk/mod_mgr.c:1616 -#: ../src/gtk/utilities.c:609 ../src/main/sidebar.cc:1085 +#: ../src/gtk/utilities.c:612 ../src/main/sidebar.cc:1085 #: ../src/main/sidebar.cc:1087 msgid "Maps" msgstr "" #: ../src/gtk/about_modules.c:460 ../src/gtk/mod_mgr.c:1622 -#: ../src/gtk/utilities.c:615 ../src/main/sidebar.cc:1096 +#: ../src/gtk/utilities.c:618 ../src/main/sidebar.cc:1096 #: ../src/main/sidebar.cc:1098 msgid "Images" msgstr "" @@ -442,87 +442,93 @@ msgid "" "us The SWORD Project." msgstr "" -#. info->stock_icon = GTK_STOCK_OPEN; -#: ../src/gtk/bookmark_dialog.c:163 ../src/gtk/bookmarks_menu.c:361 -#: ../src/gtk/bookmarks_menu.c:653 ../src/gtk/bookmarks_menu.c:753 -#: ../src/gtk/bookmarks_treeview.c:138 ../ui/editor_studypad.xml.h:15 -#: ../ui/xi-menus.glade.h:60 ../ui/xi-menus-popup.gtkbuilder.h:36 -msgid "Bookmark" -msgstr "" - -#: ../src/gtk/bookmark_dialog.c:165 ../src/gtk/bookmarks_menu.c:755 -#: ../src/gtk/bookmarks_treeview.c:139 -msgid "Enter Folder Name" +#: ../src/gtk/bookmark_dialog.c:178 +msgid "New Tag" msgstr "" -#: ../src/gtk/bookmark_dialog.c:167 ../src/gtk/bookmarks_menu.c:757 -msgid "Folder Name" -msgstr "" - -#: ../src/gtk/bookmark_dialog.c:168 ../src/gtk/bookmarks_menu.c:758 -#: ../src/gtk/bookmarks_treeview.c:141 -msgid "Folder: " +#: ../src/gtk/bookmarks_menu.c:208 +msgid "Specify bookmarks file" msgstr "" -#: ../src/gtk/bookmarks_menu.c:200 -msgid "Specify bookmarks file" +#: ../src/gtk/bookmarks_menu.c:372 +msgid "Edit Tag" msgstr "" -#: ../src/gtk/bookmarks_menu.c:350 ../ui/xi-menus.glade.h:65 +#: ../src/gtk/bookmarks_menu.c:413 ../ui/xi-menus.glade.h:65 #: ../ui/xi-menus-popup.gtkbuilder.h:29 msgid "Edit" msgstr "" -#: ../src/gtk/bookmarks_menu.c:364 -msgid "Folder name: " +#: ../src/gtk/bookmarks_menu.c:414 ../src/gtk/bookmarks_menu.c:681 +#: ../src/gtk/bookmarks_treeview.c:139 ../ui/editor_studypad.xml.h:15 +#: ../ui/xi-menus.glade.h:60 ../ui/xi-menus-popup.gtkbuilder.h:37 +msgid "Bookmark" msgstr "" -#: ../src/gtk/bookmarks_menu.c:367 +#: ../src/gtk/bookmarks_menu.c:416 msgid "Bookmark name: " msgstr "" -#: ../src/gtk/bookmarks_menu.c:370 ../src/gtk/bookmarks_menu.c:661 +#: ../src/gtk/bookmarks_menu.c:420 ../src/gtk/bookmarks_menu.c:689 msgid "Verse: " msgstr "" -#: ../src/gtk/bookmarks_menu.c:371 ../src/gtk/bookmarks_menu.c:662 +#: ../src/gtk/bookmarks_menu.c:421 ../src/gtk/bookmarks_menu.c:690 msgid "Module: " msgstr "" -#: ../src/gtk/bookmarks_menu.c:493 +#: ../src/gtk/bookmarks_menu.c:521 msgid "Remove the selected folder" msgstr "" -#: ../src/gtk/bookmarks_menu.c:494 +#: ../src/gtk/bookmarks_menu.c:522 msgid "(and all its contents)?" msgstr "" -#: ../src/gtk/bookmarks_menu.c:498 +#: ../src/gtk/bookmarks_menu.c:526 msgid "Remove the selected bookmark" msgstr "" -#: ../src/gtk/bookmarks_menu.c:654 +#: ../src/gtk/bookmarks_menu.c:682 msgid "Add" msgstr "" -#: ../src/gtk/bookmarks_menu.c:660 +#: ../src/gtk/bookmarks_menu.c:688 msgid "Label: " msgstr "" -#: ../src/gtk/bookmarks_treeview.c:102 ../src/gtk/export_bookmarks.c:172 +#: ../src/gtk/bookmarks_menu.c:788 ../ui/bookmarks.glade.h:4 +#: ../ui/bookmarks.gtkbuilder.h:4 ../ui/xi-menus.glade.h:122 +#: ../ui/xi-menus-popup.gtkbuilder.h:5 +msgid "New Folder" +msgstr "" + +#: ../src/gtk/bookmarks_menu.c:901 +msgid "Choose folder color" +msgstr "" + +#: ../src/gtk/bookmarks_treeview.c:103 ../src/gtk/export_bookmarks.c:172 #: ../src/gtk/export_bookmarks.c:229 #, c-format msgid "Search result: %s" msgstr "" -#: ../src/gtk/bookmarks_treeview.c:747 +#: ../src/gtk/bookmarks_treeview.c:140 +msgid "Enter Folder Name" +msgstr "" + +#: ../src/gtk/bookmarks_treeview.c:142 +msgid "Folder: " +msgstr "" + +#: ../src/gtk/bookmarks_treeview.c:834 msgid "" "Opening a multi-reference bookmark in\n" "separate tabs is not supported." msgstr "" -#: ../src/gtk/bookmarks_treeview.c:850 ../src/gtk/sidebar.c:1480 -#: ../src/gtk/sidebar.c:1532 +#: ../src/gtk/bookmarks_treeview.c:1115 ../src/gtk/sidebar.c:1540 +#: ../src/gtk/sidebar.c:1592 msgid "Bookmarks" msgstr "" @@ -563,24 +569,24 @@ msgstr "" msgid "Close _without Saving" msgstr "" -#: ../src/gtk/dictlex.c:378 +#: ../src/gtk/dictlex.c:379 msgid "Do sidebar search for this Strong's number" msgstr "" -#: ../src/gtk/dictlex.c:402 +#: ../src/gtk/dictlex.c:403 msgid "Go back in history" msgstr "" -#: ../src/gtk/dictlex.c:417 +#: ../src/gtk/dictlex.c:418 msgid "Go forward in history" msgstr "" -#: ../src/gtk/dictlex.c:623 +#: ../src/gtk/dictlex.c:628 msgid "Click to choose a date" msgstr "" #: ../src/gtk/export_bookmarks.c:175 ../src/gtk/export_bookmarks.c:232 -#: ../src/gtk/sidebar.c:1502 ../src/gtk/sidebar.c:1550 +#: ../src/gtk/sidebar.c:1562 ../src/gtk/sidebar.c:1610 #, c-format msgid "Verse List" msgstr "" @@ -718,8 +724,8 @@ msgstr "" msgid "Open a new tab" msgstr "" -#: ../src/gtk/main_window.c:1164 ../src/gtk/sidebar.c:578 -#: ../src/gtk/sidebar.c:583 ../src/main/sidebar.cc:655 +#: ../src/gtk/main_window.c:1164 ../src/gtk/sidebar.c:579 +#: ../src/gtk/sidebar.c:596 ../src/main/sidebar.cc:655 #: ../src/main/sidebar.cc:1020 ../src/main/sidebar.cc:1021 #: ../src/main/sidebar.cc:1022 msgid "Standard View" @@ -871,7 +877,7 @@ msgstr "" msgid "Removing" msgstr "" -#: ../src/gtk/mod_mgr.c:193 ../ui/xi-menus.glade.h:161 +#: ../src/gtk/mod_mgr.c:193 ../ui/xi-menus.glade.h:164 #: ../ui/xi-menus-popup.gtkbuilder.h:27 msgid "Remove" msgstr "" @@ -1024,9 +1030,9 @@ msgstr "" #: ../src/gtk/mod_mgr.c:1190 ../src/gtk/mod_mgr.c:1192 #: ../src/gtk/mod_mgr.c:1302 ../src/gtk/mod_mgr.c:1335 -#: ../src/gtk/mod_mgr.c:1337 ../src/gtk/utilities.c:429 -#: ../src/gtk/utilities.c:492 ../src/gtk/utilities.c:494 -#: ../src/gtk/utilities.c:985 ../src/main/sidebar.cc:807 +#: ../src/gtk/mod_mgr.c:1337 ../src/gtk/utilities.c:432 +#: ../src/gtk/utilities.c:495 ../src/gtk/utilities.c:497 +#: ../src/gtk/utilities.c:988 ../src/main/sidebar.cc:807 #: ../src/main/sidebar.cc:878 ../src/main/sidebar.cc:880 msgid "Unknown" msgstr "" @@ -1044,39 +1050,39 @@ msgid "" "Module Type" msgstr "" -#: ../src/gtk/mod_mgr.c:1580 ../src/gtk/utilities.c:571 +#: ../src/gtk/mod_mgr.c:1580 ../src/gtk/utilities.c:574 #: ../src/main/sidebar.cc:1004 ../src/main/sidebar.cc:1006 msgid "Biblical Texts" msgstr "" -#: ../src/gtk/mod_mgr.c:1586 ../src/gtk/utilities.c:577 +#: ../src/gtk/mod_mgr.c:1586 ../src/gtk/utilities.c:580 #: ../src/main/sidebar.cc:666 ../src/main/sidebar.cc:1030 #: ../src/main/sidebar.cc:1032 msgid "Commentaries" msgstr "" -#: ../src/gtk/mod_mgr.c:1592 ../src/gtk/utilities.c:584 +#: ../src/gtk/mod_mgr.c:1592 ../src/gtk/utilities.c:587 #: ../src/main/sidebar.cc:1041 ../src/main/sidebar.cc:1043 msgid "Dictionaries" msgstr "" -#: ../src/gtk/mod_mgr.c:1598 ../src/gtk/utilities.c:590 +#: ../src/gtk/mod_mgr.c:1598 ../src/gtk/utilities.c:593 #: ../src/main/sidebar.cc:1052 ../src/main/sidebar.cc:1054 msgid "Glossaries" msgstr "" -#: ../src/gtk/mod_mgr.c:1604 ../src/gtk/utilities.c:597 +#: ../src/gtk/mod_mgr.c:1604 ../src/gtk/utilities.c:600 #: ../src/main/sidebar.cc:1063 ../src/main/sidebar.cc:1065 msgid "Daily Devotionals" msgstr "" -#: ../src/gtk/mod_mgr.c:1610 ../src/gtk/utilities.c:603 +#: ../src/gtk/mod_mgr.c:1610 ../src/gtk/utilities.c:606 #: ../src/main/sidebar.cc:674 ../src/main/sidebar.cc:1074 #: ../src/main/sidebar.cc:1076 msgid "General Books" msgstr "" -#: ../src/gtk/mod_mgr.c:1628 ../src/gtk/utilities.c:621 +#: ../src/gtk/mod_mgr.c:1628 ../src/gtk/utilities.c:624 #: ../src/main/sidebar.cc:1107 ../src/main/sidebar.cc:1109 msgid "Cult/Unorthodox" msgstr "" @@ -1095,8 +1101,8 @@ msgstr "" msgid "Uninstalled" msgstr "" -#: ../src/gtk/mod_mgr.c:1653 ../src/gtk/sidebar.c:594 -#: ../src/gtk/utilities.c:629 ../src/main/prayerlists.cc:233 +#: ../src/gtk/mod_mgr.c:1653 ../src/gtk/sidebar.c:607 +#: ../src/gtk/utilities.c:632 ../src/main/prayerlists.cc:233 #: ../src/main/sidebar.cc:1118 ../src/main/sidebar.cc:1120 msgid "Prayer List/Journal" msgstr "" @@ -1158,7 +1164,7 @@ msgid "Choose" msgstr "" #: ../src/gtk/mod_mgr.c:2025 ../src/gtk/preferences_dialog.c:2254 -#: ../src/gtk/sidebar.c:1512 ../src/gtk/sidebar.c:1558 +#: ../src/gtk/sidebar.c:1572 ../src/gtk/sidebar.c:1618 msgid "Modules" msgstr "" @@ -1287,12 +1293,12 @@ msgid "Detach/Attach" msgstr "" #: ../src/gtk/parallel_view.c:117 ../ui/xi-menus.glade.h:68 -#: ../ui/xi-menus-popup.gtkbuilder.h:43 +#: ../ui/xi-menus-popup.gtkbuilder.h:44 msgid "Module Options" msgstr "" -#: ../src/gtk/parallel_view.c:216 ../src/gtk/sidebar.c:578 -#: ../src/gtk/sidebar.c:583 ../src/gtk/tabbed_browser.c:239 +#: ../src/gtk/parallel_view.c:216 ../src/gtk/sidebar.c:579 +#: ../src/gtk/sidebar.c:596 ../src/gtk/tabbed_browser.c:239 #: ../src/main/sidebar.cc:638 ../src/main/sidebar.cc:1012 #: ../src/main/sidebar.cc:1013 ../src/main/sidebar.cc:1014 msgid "Parallel View" @@ -1326,7 +1332,7 @@ msgstr "" msgid "Disabled" msgstr "" -#: ../src/gtk/preferences_dialog.c:1005 ../src/main/xml.c:96 +#: ../src/gtk/preferences_dialog.c:1005 ../src/main/xml.c:97 msgid "Personal" msgstr "" @@ -1517,7 +1523,7 @@ msgstr "" msgid "Module is neither Bible nor commentary" msgstr "" -#: ../src/gtk/search_dialog.c:1212 ../src/gtk/sidebar.c:946 +#: ../src/gtk/search_dialog.c:1212 ../src/gtk/sidebar.c:959 msgid "BibleSync is not active for transmit." msgstr "" @@ -1595,23 +1601,23 @@ msgstr "" msgid "Upper" msgstr "" -#: ../src/gtk/sidebar.c:806 +#: ../src/gtk/sidebar.c:819 msgid "Open module in editor?" msgstr "" -#: ../src/gtk/sidebar.c:807 +#: ../src/gtk/sidebar.c:820 msgid "If no, it will open for display only." msgstr "" -#: ../src/gtk/sidebar.c:907 +#: ../src/gtk/sidebar.c:920 msgid "Paste verse references" msgstr "" -#: ../src/gtk/sidebar.c:909 +#: ../src/gtk/sidebar.c:922 msgid "List:" msgstr "" -#: ../src/gtk/sidebar.c:1491 ../src/gtk/sidebar.c:1541 +#: ../src/gtk/sidebar.c:1551 ../src/gtk/sidebar.c:1601 msgid "Search" msgstr "" @@ -1641,55 +1647,55 @@ msgstr "" msgid "Remove the selected item" msgstr "" -#: ../src/gtk/utilities.c:80 +#: ../src/gtk/utilities.c:81 msgid "January" msgstr "" -#: ../src/gtk/utilities.c:81 +#: ../src/gtk/utilities.c:82 msgid "February" msgstr "" -#: ../src/gtk/utilities.c:82 +#: ../src/gtk/utilities.c:83 msgid "March" msgstr "" -#: ../src/gtk/utilities.c:83 +#: ../src/gtk/utilities.c:84 msgid "April" msgstr "" -#: ../src/gtk/utilities.c:84 +#: ../src/gtk/utilities.c:85 msgid "May" msgstr "" -#: ../src/gtk/utilities.c:85 +#: ../src/gtk/utilities.c:86 msgid "June" msgstr "" -#: ../src/gtk/utilities.c:86 +#: ../src/gtk/utilities.c:87 msgid "July" msgstr "" -#: ../src/gtk/utilities.c:87 +#: ../src/gtk/utilities.c:88 msgid "August" msgstr "" -#: ../src/gtk/utilities.c:88 +#: ../src/gtk/utilities.c:89 msgid "September" msgstr "" -#: ../src/gtk/utilities.c:89 +#: ../src/gtk/utilities.c:90 msgid "October" msgstr "" -#: ../src/gtk/utilities.c:90 +#: ../src/gtk/utilities.c:91 msgid "November" msgstr "" -#: ../src/gtk/utilities.c:91 +#: ../src/gtk/utilities.c:92 msgid "December" msgstr "" -#: ../src/gtk/utilities.c:2021 +#: ../src/gtk/utilities.c:2024 msgid "" "An image file's size could not be determined.\n" "Xiphos cannot resize images to fit window." @@ -1789,20 +1795,20 @@ msgid "" "UUID: " msgstr "" -#: ../src/main/display.cc:89 +#: ../src/main/display.cc:90 msgid "" "

This module has no content at this point.
" msgstr "" -#: ../src/main/display.cc:259 +#: ../src/main/display.cc:260 #, c-format msgid "" "Improperly encoded personal annotation label:\n" "'%s'" msgstr "" -#: ../src/main/display.cc:1214 ../src/main/display.cc:1271 -#: ../src/main/display.cc:1312 ../ui/export-dialog.glade.h:14 +#: ../src/main/display.cc:1215 ../src/main/display.cc:1272 +#: ../src/main/display.cc:1313 ../ui/export-dialog.glade.h:14 #: ../ui/export-dialog.gtkbuilder.h:14 msgid "Chapter" msgstr "" @@ -1811,23 +1817,23 @@ msgstr "" msgid "Xiphos does not understand more than one argument." msgstr "" -#: ../src/main/main.c:258 +#: ../src/main/main.c:280 msgid "Initiating HTML" msgstr "" -#: ../src/main/main.c:263 +#: ../src/main/main.c:285 msgid "Building Interface" msgstr "" -#: ../src/main/main.c:266 +#: ../src/main/main.c:288 msgid "Starting Sword" msgstr "" -#: ../src/main/main.c:269 +#: ../src/main/main.c:291 msgid "Loading Settings" msgstr "" -#: ../src/main/main.c:272 +#: ../src/main/main.c:294 msgid "Displaying Xiphos" msgstr "" @@ -1866,69 +1872,69 @@ msgid "Unknown parallel module: " msgstr "" #: ../src/main/parallel_view.cc:361 ../ui/xi-menus.glade.h:73 -#: ../ui/xi-menus-popup.gtkbuilder.h:48 +#: ../ui/xi-menus-popup.gtkbuilder.h:49 msgid "Strong's Numbers" msgstr "" #: ../src/main/parallel_view.cc:370 ../ui/search-dialog.glade.h:102 #: ../ui/search-dialog.gtkbuilder.h:101 ../ui/xi-menus.glade.h:76 -#: ../ui/xi-menus-popup.gtkbuilder.h:51 +#: ../ui/xi-menus-popup.gtkbuilder.h:52 msgid "Footnotes" msgstr "" #: ../src/main/parallel_view.cc:379 ../ui/search-dialog.glade.h:99 #: ../ui/search-dialog.gtkbuilder.h:98 ../ui/xi-menus.glade.h:75 -#: ../ui/xi-menus-popup.gtkbuilder.h:50 +#: ../ui/xi-menus-popup.gtkbuilder.h:51 msgid "Morphological Tags" msgstr "" #: ../src/main/parallel_view.cc:388 ../ui/xi-menus.glade.h:81 -#: ../ui/xi-menus-popup.gtkbuilder.h:55 +#: ../ui/xi-menus-popup.gtkbuilder.h:56 msgid "Hebrew Vowel Points" msgstr "" #: ../src/main/parallel_view.cc:397 ../ui/xi-menus.glade.h:82 -#: ../ui/xi-menus-popup.gtkbuilder.h:56 +#: ../ui/xi-menus-popup.gtkbuilder.h:57 msgid "Hebrew Cantillation" msgstr "" #: ../src/main/parallel_view.cc:406 ../ui/xi-menus.glade.h:80 -#: ../ui/xi-menus-popup.gtkbuilder.h:54 +#: ../ui/xi-menus-popup.gtkbuilder.h:55 msgid "Greek Accents" msgstr "" #: ../src/main/parallel_view.cc:415 ../ui/xi-menus.glade.h:77 -#: ../ui/xi-menus-popup.gtkbuilder.h:52 +#: ../ui/xi-menus-popup.gtkbuilder.h:53 msgid "Cross-references" msgstr "" #: ../src/main/parallel_view.cc:424 ../ui/xi-menus.glade.h:74 -#: ../ui/xi-menus-popup.gtkbuilder.h:49 +#: ../ui/xi-menus-popup.gtkbuilder.h:50 msgid "Lemmas" msgstr "" #: ../src/main/parallel_view.cc:433 ../ui/xi-menus.glade.h:70 -#: ../ui/xi-menus-popup.gtkbuilder.h:45 +#: ../ui/xi-menus-popup.gtkbuilder.h:46 msgid "Headings" msgstr "" #: ../src/main/parallel_view.cc:443 ../ui/xi-menus.glade.h:71 -#: ../ui/xi-menus-popup.gtkbuilder.h:46 +#: ../ui/xi-menus-popup.gtkbuilder.h:47 msgid "Italic Headings" msgstr "" #: ../src/main/parallel_view.cc:453 ../src/main/parallel_view.cc:542 -#: ../ui/xi-menus.glade.h:91 ../ui/xi-menus-popup.gtkbuilder.h:65 +#: ../ui/xi-menus.glade.h:91 ../ui/xi-menus-popup.gtkbuilder.h:66 msgid "Morpheme Segmentation" msgstr "" #: ../src/main/parallel_view.cc:462 ../ui/xi-menus.glade.h:72 -#: ../ui/xi-menus-popup.gtkbuilder.h:47 +#: ../ui/xi-menus-popup.gtkbuilder.h:48 msgid "Words of Christ in Red" msgstr "" #: ../src/main/parallel_view.cc:471 ../ui/xi-menus.glade.h:83 -#: ../ui/xi-menus-popup.gtkbuilder.h:57 +#: ../ui/xi-menus-popup.gtkbuilder.h:58 msgid "Transliteration" msgstr "" @@ -1937,32 +1943,32 @@ msgid "Textual Variants" msgstr "" #: ../src/main/parallel_view.cc:488 ../ui/xi-menus.glade.h:85 -#: ../ui/xi-menus-popup.gtkbuilder.h:59 +#: ../ui/xi-menus-popup.gtkbuilder.h:60 msgid "Primary Reading" msgstr "" #: ../src/main/parallel_view.cc:497 ../ui/xi-menus.glade.h:86 -#: ../ui/xi-menus-popup.gtkbuilder.h:60 +#: ../ui/xi-menus-popup.gtkbuilder.h:61 msgid "Secondary Reading" msgstr "" #: ../src/main/parallel_view.cc:506 ../ui/xi-menus.glade.h:87 -#: ../ui/xi-menus-popup.gtkbuilder.h:61 +#: ../ui/xi-menus-popup.gtkbuilder.h:62 msgid "All Readings" msgstr "" #: ../src/main/parallel_view.cc:515 ../ui/xi-menus.glade.h:88 -#: ../ui/xi-menus-popup.gtkbuilder.h:62 +#: ../ui/xi-menus-popup.gtkbuilder.h:63 msgid "Transliterated Forms" msgstr "" #: ../src/main/parallel_view.cc:524 ../ui/xi-menus.glade.h:89 -#: ../ui/xi-menus-popup.gtkbuilder.h:63 +#: ../ui/xi-menus-popup.gtkbuilder.h:64 msgid "Enumerations" msgstr "" #: ../src/main/parallel_view.cc:533 ../ui/xi-menus.glade.h:90 -#: ../ui/xi-menus-popup.gtkbuilder.h:64 +#: ../ui/xi-menus-popup.gtkbuilder.h:65 msgid "Glosses" msgstr "" @@ -2339,7 +2345,7 @@ msgstr "" msgid "Book names and menus may not be translated." msgstr "" -#: ../src/main/sword.cc:1137 ../src/main/sword.cc:1324 +#: ../src/main/sword.cc:1136 ../src/main/sword.cc:1324 #, c-format msgid "" "Module %s has companion modules:\n" @@ -2347,7 +2353,7 @@ msgid "" "Would you like to open these as well?%s" msgstr "" -#: ../src/main/sword.cc:1141 ../src/main/sword.cc:1328 +#: ../src/main/sword.cc:1140 ../src/main/sword.cc:1328 msgid "" "\n" "\n" @@ -2399,67 +2405,67 @@ msgstr "" msgid "Show %s in main window" msgstr "" -#: ../src/main/xml.c:87 ../src/main/xml.c:443 ../src/main/xml.c:574 +#: ../src/main/xml.c:88 ../src/main/xml.c:500 ../src/main/xml.c:631 #, c-format msgid "Document not created successfully. \n" msgstr "" -#: ../src/main/xml.c:99 +#: ../src/main/xml.c:100 msgid "What must I do to be saved?" msgstr "" -#: ../src/main/xml.c:100 ../src/main/xml.c:101 +#: ../src/main/xml.c:101 ../src/main/xml.c:102 msgid "Acts 16:31" msgstr "" -#: ../src/main/xml.c:102 ../src/main/xml.c:103 +#: ../src/main/xml.c:103 ../src/main/xml.c:104 msgid "Eph 2:8,9" msgstr "" -#: ../src/main/xml.c:104 ../src/main/xml.c:105 +#: ../src/main/xml.c:105 ../src/main/xml.c:106 msgid "Romans 1:16" msgstr "" -#: ../src/main/xml.c:107 +#: ../src/main/xml.c:108 msgid "What is the Gospel?" msgstr "" -#: ../src/main/xml.c:108 ../src/main/xml.c:109 +#: ../src/main/xml.c:109 ../src/main/xml.c:110 msgid "1 Cor 15:1-4" msgstr "" -#: ../src/main/xml.c:238 ../src/main/xml.c:384 ../src/main/xml.c:1504 +#: ../src/main/xml.c:295 ../src/main/xml.c:441 ../src/main/xml.c:1561 #, c-format msgid "Document not parsed successfully. \n" msgstr "" -#: ../src/main/xml.c:244 ../src/main/xml.c:390 ../src/main/xml.c:410 -#: ../src/main/xml.c:1061 ../src/main/xml.c:1391 ../src/main/xml.c:1587 +#: ../src/main/xml.c:301 ../src/main/xml.c:447 ../src/main/xml.c:467 +#: ../src/main/xml.c:1118 ../src/main/xml.c:1448 ../src/main/xml.c:1644 #, c-format msgid "empty document \n" msgstr "" -#: ../src/main/xml.c:250 +#: ../src/main/xml.c:307 #, c-format msgid "wrong type, root node != SwordBookmarks\n" msgstr "" -#: ../src/main/xml.c:396 +#: ../src/main/xml.c:453 #, c-format msgid "wrong type, root node != Copy_Export\n" msgstr "" -#: ../src/main/xml.c:473 +#: ../src/main/xml.c:530 #, c-format msgid "%s
%s
Chapter %d

" msgstr "" -#: ../src/main/xml.c:477 +#: ../src/main/xml.c:534 #, c-format msgid "
Chapter %d

" msgstr "" -#: ../src/main/xml.c:480 +#: ../src/main/xml.c:537 #, c-format msgid "" "%s\n" @@ -2468,7 +2474,7 @@ msgid "" "\n" msgstr "" -#: ../src/main/xml.c:483 +#: ../src/main/xml.c:540 #, c-format msgid "" "\n" @@ -2477,101 +2483,101 @@ msgid "" "\n" msgstr "" -#: ../src/main/xml.c:492 +#: ../src/main/xml.c:549 #, c-format msgid "%s%s: %s Chapter %d

" msgstr "" -#: ../src/main/xml.c:495 +#: ../src/main/xml.c:552 #, c-format msgid "" "%s: %s Chapter %d\n" "\n" msgstr "" -#: ../src/main/xml.c:503 +#: ../src/main/xml.c:560 #, c-format msgid "  [%d]" msgstr "" -#: ../src/main/xml.c:506 +#: ../src/main/xml.c:563 #, c-format msgid " [%d]" msgstr "" -#: ../src/main/xml.c:515 +#: ../src/main/xml.c:572 #, c-format msgid "%s%s (%s %d:%d%s)" msgstr "" -#: ../src/main/xml.c:518 +#: ../src/main/xml.c:575 #, c-format msgid "%s(%s %d:%d%s)%s " msgstr "" -#: ../src/main/xml.c:520 +#: ../src/main/xml.c:577 #, c-format msgid "%s (%s %d:%d%s)" msgstr "" -#: ../src/main/xml.c:523 +#: ../src/main/xml.c:580 #, c-format msgid "(%s %d:%d%s) %s" msgstr "" -#: ../src/main/xml.c:531 +#: ../src/main/xml.c:588 #, c-format msgid " %s%s" msgstr "" -#: ../src/main/xml.c:533 ../src/main/xml.c:537 +#: ../src/main/xml.c:590 ../src/main/xml.c:594 #, c-format msgid "%s(%s %d:%d-%d%s)" msgstr "" -#: ../src/main/xml.c:535 +#: ../src/main/xml.c:592 #, c-format msgid "(%s %d:%d-%d%s)
" msgstr "" -#: ../src/main/xml.c:540 +#: ../src/main/xml.c:597 #, c-format msgid "(%s %d:%d-%d%s)\n" msgstr "" -#: ../src/main/xml.c:589 +#: ../src/main/xml.c:646 msgid "Old Testament" msgstr "" -#: ../src/main/xml.c:591 +#: ../src/main/xml.c:648 msgid "Gen - Mal" msgstr "" -#: ../src/main/xml.c:597 +#: ../src/main/xml.c:654 msgid "New Testament" msgstr "" -#: ../src/main/xml.c:599 +#: ../src/main/xml.c:656 msgid "Mat - Rev" msgstr "" -#: ../src/main/xml.c:608 +#: ../src/main/xml.c:665 msgid "Sample Module List" msgstr "" -#: ../src/main/xml.c:1067 ../src/main/xml.c:1397 +#: ../src/main/xml.c:1124 ../src/main/xml.c:1454 #, c-format msgid "wrong type, root node != %s\n" msgstr "" -#: ../src/main/xml.c:1549 +#: ../src/main/xml.c:1606 #, c-format msgid "" "Save of settings failed! stat %d, size %d\n" "%s" msgstr "" -#: ../src/main/xml.c:1551 +#: ../src/main/xml.c:1608 msgid "Attempting to revert to previous save." msgstr "" @@ -2587,11 +2593,6 @@ msgstr "" msgid "Create new folder" msgstr "" -#: ../ui/bookmarks.glade.h:4 ../ui/bookmarks.gtkbuilder.h:4 -#: ../ui/xi-menus.glade.h:122 ../ui/xi-menus-popup.gtkbuilder.h:5 -msgid "New Folder" -msgstr "" - #: ../ui/bookmarks.glade.h:5 ../ui/bookmarks.gtkbuilder.h:3 msgid "New ..." msgstr "" @@ -2632,6 +2633,30 @@ msgstr "" msgid "Bookmark Folder Treeview" msgstr "" +#: ../ui/folder.gtkbuilder.h:1 +msgid "Folder" +msgstr "" + +#: ../ui/folder.gtkbuilder.h:2 +msgid "Name:" +msgstr "" + +#: ../ui/folder.gtkbuilder.h:3 +msgid "Tag color:" +msgstr "" + +#: ../ui/folder.gtkbuilder.h:4 +msgid "Choose a highlight color for this tag group" +msgstr "" + +#: ../ui/folder.gtkbuilder.h:5 +msgid "No color" +msgstr "" + +#: ../ui/folder.gtkbuilder.h:6 +msgid "Remove tag color from this folder" +msgstr "" + #: ../ui/editor_link_dialog.gtkbuilder.h:2 msgid "Test Link" msgstr "" @@ -2738,7 +2763,7 @@ msgid "New Document" msgstr "" #: ../ui/export-dialog.glade.h:1 ../ui/export-dialog.gtkbuilder.h:1 -#: ../ui/xi-menus.glade.h:62 ../ui/xi-menus-popup.gtkbuilder.h:38 +#: ../ui/xi-menus.glade.h:62 ../ui/xi-menus-popup.gtkbuilder.h:39 msgid "Copy/Export Passage" msgstr "" @@ -4902,27 +4927,27 @@ msgstr "" msgid "Learn about Xiphos" msgstr "" -#: ../ui/xi-menus.glade.h:61 ../ui/xi-menus-popup.gtkbuilder.h:37 +#: ../ui/xi-menus.glade.h:61 ../ui/xi-menus-popup.gtkbuilder.h:38 msgid "Annotate Verse" msgstr "" -#: ../ui/xi-menus.glade.h:64 ../ui/xi-menus-popup.gtkbuilder.h:40 +#: ../ui/xi-menus.glade.h:64 ../ui/xi-menus-popup.gtkbuilder.h:41 msgid "Open Module" msgstr "" -#: ../ui/xi-menus.glade.h:66 ../ui/xi-menus-popup.gtkbuilder.h:41 +#: ../ui/xi-menus.glade.h:66 ../ui/xi-menus-popup.gtkbuilder.h:42 msgid "Note" msgstr "" -#: ../ui/xi-menus.glade.h:67 ../ui/xi-menus-popup.gtkbuilder.h:42 +#: ../ui/xi-menus.glade.h:67 ../ui/xi-menus-popup.gtkbuilder.h:43 msgid "Open in editor" msgstr "" -#: ../ui/xi-menus.glade.h:69 ../ui/xi-menus-popup.gtkbuilder.h:44 +#: ../ui/xi-menus.glade.h:69 ../ui/xi-menus-popup.gtkbuilder.h:45 msgid "Verse Per Line" msgstr "" -#: ../ui/xi-menus.glade.h:78 ../ui/xi-menus-popup.gtkbuilder.h:53 +#: ../ui/xi-menus.glade.h:78 ../ui/xi-menus-popup.gtkbuilder.h:54 msgid "Footnote/Cross-ref Markers" msgstr "" @@ -4930,111 +4955,111 @@ msgstr "" msgid "Show non-anonymous markers e.g. \"*n23\"" msgstr "" -#: ../ui/xi-menus.glade.h:84 ../ui/xi-menus-popup.gtkbuilder.h:58 +#: ../ui/xi-menus.glade.h:84 ../ui/xi-menus-popup.gtkbuilder.h:59 msgid "Variants" msgstr "" -#: ../ui/xi-menus.glade.h:92 ../ui/xi-menus-popup.gtkbuilder.h:66 +#: ../ui/xi-menus.glade.h:92 ../ui/xi-menus-popup.gtkbuilder.h:67 msgid "Image Content" msgstr "" -#: ../ui/xi-menus.glade.h:93 ../ui/xi-menus-popup.gtkbuilder.h:67 +#: ../ui/xi-menus.glade.h:93 ../ui/xi-menus-popup.gtkbuilder.h:68 msgid "Respect Font Faces" msgstr "" -#: ../ui/xi-menus.glade.h:94 ../ui/xi-menus-popup.gtkbuilder.h:68 +#: ../ui/xi-menus.glade.h:94 ../ui/xi-menus-popup.gtkbuilder.h:69 msgid "Display chapter numbers" msgstr "" -#: ../ui/xi-menus.glade.h:95 ../ui/xi-menus-popup.gtkbuilder.h:69 +#: ../ui/xi-menus.glade.h:95 ../ui/xi-menus-popup.gtkbuilder.h:70 msgid "Commentary by Chapter" msgstr "" -#: ../ui/xi-menus.glade.h:96 ../ui/xi-menus-popup.gtkbuilder.h:70 +#: ../ui/xi-menus.glade.h:96 ../ui/xi-menus-popup.gtkbuilder.h:71 msgid "Doublespace" msgstr "" -#: ../ui/xi-menus.glade.h:97 ../ui/xi-menus-popup.gtkbuilder.h:71 +#: ../ui/xi-menus.glade.h:97 ../ui/xi-menus-popup.gtkbuilder.h:72 msgid "Lookup Selection" msgstr "" -#: ../ui/xi-menus.glade.h:98 ../ui/xi-menus-popup.gtkbuilder.h:72 +#: ../ui/xi-menus.glade.h:98 ../ui/xi-menus-popup.gtkbuilder.h:73 msgid "Use Current Dictionary" msgstr "" -#: ../ui/xi-menus.glade.h:99 ../ui/xi-menus-popup.gtkbuilder.h:73 +#: ../ui/xi-menus.glade.h:99 ../ui/xi-menus-popup.gtkbuilder.h:74 msgid "Browse in BibleMap.org" msgstr "" -#: ../ui/xi-menus.glade.h:100 ../ui/xi-menus-popup.gtkbuilder.h:74 +#: ../ui/xi-menus.glade.h:100 ../ui/xi-menus-popup.gtkbuilder.h:75 msgid "Unlock This Module" msgstr "" -#: ../ui/xi-menus.glade.h:101 ../ui/xi-menus-popup.gtkbuilder.h:75 +#: ../ui/xi-menus.glade.h:101 ../ui/xi-menus-popup.gtkbuilder.h:76 msgid "Display Book Heading" msgstr "" -#: ../ui/xi-menus.glade.h:102 ../ui/xi-menus-popup.gtkbuilder.h:76 +#: ../ui/xi-menus.glade.h:102 ../ui/xi-menus-popup.gtkbuilder.h:77 msgid "Display Chapter Heading" msgstr "" -#: ../ui/xi-menus.glade.h:103 ../ui/xi-menus-popup.gtkbuilder.h:77 +#: ../ui/xi-menus.glade.h:103 ../ui/xi-menus-popup.gtkbuilder.h:78 msgid "Rename Pers.Comm." msgstr "" -#: ../ui/xi-menus.glade.h:104 ../ui/xi-menus-popup.gtkbuilder.h:78 +#: ../ui/xi-menus.glade.h:104 ../ui/xi-menus-popup.gtkbuilder.h:79 msgid "Dump Pers.Comm." msgstr "" -#: ../ui/xi-menus.glade.h:105 ../ui/xi-menus-popup.gtkbuilder.h:79 +#: ../ui/xi-menus.glade.h:105 ../ui/xi-menus-popup.gtkbuilder.h:80 msgid "Read Selection Aloud" msgstr "" -#: ../ui/xi-menus.glade.h:106 ../ui/xi-menus-popup.gtkbuilder.h:94 +#: ../ui/xi-menus.glade.h:106 ../ui/xi-menus-popup.gtkbuilder.h:96 msgid "Save these results as a single bookmark" msgstr "" -#: ../ui/xi-menus.glade.h:107 ../ui/xi-menus-popup.gtkbuilder.h:93 +#: ../ui/xi-menus.glade.h:107 ../ui/xi-menus-popup.gtkbuilder.h:95 msgid "Save list as a single bookmark" msgstr "" -#: ../ui/xi-menus.glade.h:108 ../ui/xi-menus-popup.gtkbuilder.h:96 +#: ../ui/xi-menus.glade.h:108 ../ui/xi-menus-popup.gtkbuilder.h:98 msgid "Save these results as a series of bookmarks in their own folder" msgstr "" -#: ../ui/xi-menus.glade.h:109 ../ui/xi-menus-popup.gtkbuilder.h:95 +#: ../ui/xi-menus.glade.h:109 ../ui/xi-menus-popup.gtkbuilder.h:97 msgid "Save list as a series of bookmarks" msgstr "" -#: ../ui/xi-menus.glade.h:110 ../ui/xi-menus-popup.gtkbuilder.h:98 +#: ../ui/xi-menus.glade.h:110 ../ui/xi-menus-popup.gtkbuilder.h:100 msgid "" "Provide a dialog in which to paste a line of verse references, to fill the " "verse list." msgstr "" -#: ../ui/xi-menus.glade.h:111 ../ui/xi-menus-popup.gtkbuilder.h:97 +#: ../ui/xi-menus.glade.h:111 ../ui/xi-menus-popup.gtkbuilder.h:99 msgid "Populate verse list" msgstr "" -#: ../ui/xi-menus.glade.h:112 ../ui/xi-menus-popup.gtkbuilder.h:100 +#: ../ui/xi-menus.glade.h:112 ../ui/xi-menus-popup.gtkbuilder.h:102 msgid "Push the entire verse list contents directly into the history list." msgstr "" -#: ../ui/xi-menus.glade.h:113 ../ui/xi-menus-popup.gtkbuilder.h:99 +#: ../ui/xi-menus.glade.h:113 ../ui/xi-menus-popup.gtkbuilder.h:101 msgid "Preload history from verse list" msgstr "" -#: ../ui/xi-menus.glade.h:114 ../ui/xi-menus-popup.gtkbuilder.h:102 +#: ../ui/xi-menus.glade.h:114 ../ui/xi-menus-popup.gtkbuilder.h:104 msgid "" "Send this verse list via BibleSync to others, if you are in Personal or " "Speaker mode." msgstr "" -#: ../ui/xi-menus.glade.h:115 ../ui/xi-menus-popup.gtkbuilder.h:101 +#: ../ui/xi-menus.glade.h:115 ../ui/xi-menus-popup.gtkbuilder.h:103 msgid "Send list via BibleSync" msgstr "" -#: ../ui/xi-menus.glade.h:116 ../ui/xi-menus-popup.gtkbuilder.h:103 +#: ../ui/xi-menus.glade.h:116 ../ui/xi-menus-popup.gtkbuilder.h:105 msgid "Export List" msgstr "" @@ -5132,78 +5157,90 @@ msgstr "" msgid "Open in a separate window" msgstr "" -#: ../ui/xi-menus.glade.h:143 ../ui/xi-menus-popup.gtkbuilder.h:81 +#: ../ui/xi-menus.glade.h:143 ../ui/xi-menus-popup.gtkbuilder.h:82 msgid "Create a new simple prayer list" msgstr "" -#: ../ui/xi-menus.glade.h:144 ../ui/xi-menus-popup.gtkbuilder.h:80 +#: ../ui/xi-menus.glade.h:144 ../ui/xi-menus-popup.gtkbuilder.h:81 msgid "Simple" msgstr "" -#: ../ui/xi-menus.glade.h:145 ../ui/xi-menus-popup.gtkbuilder.h:83 +#: ../ui/xi-menus.glade.h:145 ../ui/xi-menus-popup.gtkbuilder.h:84 msgid "Create a new subject prayer list" msgstr "" -#: ../ui/xi-menus.glade.h:146 ../ui/xi-menus-popup.gtkbuilder.h:82 +#: ../ui/xi-menus.glade.h:146 ../ui/xi-menus-popup.gtkbuilder.h:83 msgid "Subject" msgstr "" -#: ../ui/xi-menus.glade.h:147 ../ui/xi-menus-popup.gtkbuilder.h:85 +#: ../ui/xi-menus.glade.h:147 ../ui/xi-menus-popup.gtkbuilder.h:86 msgid "Create a new monthly journal" msgstr "" -#: ../ui/xi-menus.glade.h:148 ../ui/xi-menus-popup.gtkbuilder.h:84 +#: ../ui/xi-menus.glade.h:148 ../ui/xi-menus-popup.gtkbuilder.h:85 msgid "Monthly" msgstr "" -#: ../ui/xi-menus.glade.h:149 ../ui/xi-menus-popup.gtkbuilder.h:87 +#: ../ui/xi-menus.glade.h:149 ../ui/xi-menus-popup.gtkbuilder.h:88 msgid "Create a new daily journal" msgstr "" -#: ../ui/xi-menus.glade.h:150 ../ui/xi-menus-popup.gtkbuilder.h:86 +#: ../ui/xi-menus.glade.h:150 ../ui/xi-menus-popup.gtkbuilder.h:87 msgid "Daily" msgstr "" -#: ../ui/xi-menus.glade.h:151 ../ui/xi-menus-popup.gtkbuilder.h:89 +#: ../ui/xi-menus.glade.h:151 ../ui/xi-menus-popup.gtkbuilder.h:90 msgid "Create a new outlined topic" msgstr "" -#: ../ui/xi-menus.glade.h:152 ../ui/xi-menus-popup.gtkbuilder.h:88 +#: ../ui/xi-menus.glade.h:152 ../ui/xi-menus-popup.gtkbuilder.h:89 msgid "Outlined" msgstr "" -#: ../ui/xi-menus.glade.h:153 ../ui/xi-menus-popup.gtkbuilder.h:91 +#: ../ui/xi-menus.glade.h:153 ../ui/xi-menus-popup.gtkbuilder.h:92 msgid "Create a new book/chapter outline" msgstr "" -#: ../ui/xi-menus.glade.h:154 ../ui/xi-menus-popup.gtkbuilder.h:90 +#: ../ui/xi-menus.glade.h:154 ../ui/xi-menus-popup.gtkbuilder.h:91 msgid "Book/Chapter" msgstr "" -#: ../ui/xi-menus.glade.h:155 ../ui/xi-menus-popup.gtkbuilder.h:92 +#: ../ui/xi-menus.glade.h:155 ../ui/xi-menus-popup.gtkbuilder.h:93 msgid "Open module in editor or plain display window" msgstr "" -#: ../ui/xi-menus.glade.h:156 ../ui/xi-menus-popup.gtkbuilder.h:24 +#: ../ui/xi-menus.glade.h:156 ../ui/xi-menus-popup.gtkbuilder.h:94 +msgid "Open this prayer list in the editor" +msgstr "" + +#: ../ui/xi-menus.glade.h:157 +msgid "Open selected module in a separate window" +msgstr "" + +#: ../ui/xi-menus.glade.h:158 ../ui/xi-menus-popup.gtkbuilder.h:36 +msgid "Open this personal commentary in the editor" +msgstr "" + +#: ../ui/xi-menus.glade.h:159 ../ui/xi-menus-popup.gtkbuilder.h:24 msgid "Add a sub-item" msgstr "" -#: ../ui/xi-menus.glade.h:157 ../ui/xi-menus-popup.gtkbuilder.h:23 +#: ../ui/xi-menus.glade.h:160 ../ui/xi-menus-popup.gtkbuilder.h:23 msgid "Add Sub-Item" msgstr "" -#: ../ui/xi-menus.glade.h:158 ../ui/xi-menus-popup.gtkbuilder.h:26 +#: ../ui/xi-menus.glade.h:161 ../ui/xi-menus-popup.gtkbuilder.h:26 msgid "Add an item" msgstr "" -#: ../ui/xi-menus.glade.h:159 ../ui/xi-menus-popup.gtkbuilder.h:25 +#: ../ui/xi-menus.glade.h:162 ../ui/xi-menus-popup.gtkbuilder.h:25 msgid "Add Item" msgstr "" -#: ../ui/xi-menus.glade.h:160 ../ui/xi-menus-popup.gtkbuilder.h:28 +#: ../ui/xi-menus.glade.h:163 ../ui/xi-menus-popup.gtkbuilder.h:28 msgid "Remove this item" msgstr "" -#: ../ui/xi-menus.glade.h:162 ../ui/xi-menus-popup.gtkbuilder.h:30 +#: ../ui/xi-menus.glade.h:165 ../ui/xi-menus-popup.gtkbuilder.h:30 msgid "Edit this item" msgstr "" diff --git a/src/gtk/bookmark_dialog.c b/src/gtk/bookmark_dialog.c index 824c1eeb2..56cde37c7 100644 --- a/src/gtk/bookmark_dialog.c +++ b/src/gtk/bookmark_dialog.c @@ -33,6 +33,7 @@ #include "gui/bookmarks_treeview.h" #include "gui/dialog.h" #include "gui/utilities.h" +#include "gui/widgets.h" #include "main/display.hh" #include "main/sword.h" @@ -147,56 +148,81 @@ static void add_folder_button(void) GtkTreeIter iter; BOOKMARK_DATA *data; GtkTreeSelection *selection; - char *t; - gint test; - GS_DIALOG *info; - GString *str; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); if (!gtk_tree_selection_get_selected(selection, NULL, &selected)) return; - t = "|"; - str = g_string_new(""); - info = gui_new_dialog(); - //info->stock_icon = GTK_STOCK_OPEN; - info->title = _("Bookmark"); - g_string_printf(str, "%s", - _("Enter Folder Name")); - info->label_top = str->str; - info->text1 = g_strdup(_("Folder Name")); - info->label1 = _("Folder: "); - info->ok = TRUE; - info->cancel = TRUE; + gchar *glade_file = gui_general_user_file("folder" UI_SUFFIX, TRUE); + if (!glade_file) return; - data = g_new(BOOKMARK_DATA, 1); - /*** open dialog to get name for new folder ***/ - test = gui_gs_dialog(info); - if (test == GS_OK) { - char *buf = g_strdelimit(info->text1, t, ' '); - data->caption = g_strdup(buf); - data->key = NULL; - data->module = NULL; - data->module_desc = NULL; - data->description = NULL; +#ifdef USE_GTKBUILDER + GtkBuilder *gxml = gtk_builder_new(); + gtk_builder_add_from_file(gxml, glade_file, NULL); +#else + GladeXML *gxml = glade_xml_new(glade_file, NULL, NULL); +#endif + g_free(glade_file); + + GtkWidget *entry = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_entry_name")); + GtkWidget *dialog = GTK_WIDGET(UI_GET_ITEM(gxml, "dialog_folder")); +#ifdef USE_GTKBUILDER + GtkWidget *colorbtn = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_color_button")); + GtkWidget *clearbtn = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_clear_color")); + if (!dialog || !entry || !colorbtn || !clearbtn) { + g_object_unref(gxml); + return; + } +#else + if (!dialog || !entry) { + return; + } +#endif + + gtk_window_set_title(GTK_WINDOW(dialog), _("New Tag")); + gtk_entry_set_text(GTK_ENTRY(entry), ""); +#ifdef USE_GTKBUILDER + g_signal_connect_swapped(clearbtn, "clicked", + G_CALLBACK(gtk_widget_set_sensitive), colorbtn); +#endif + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { + const gchar *name = gtk_entry_get_text(GTK_ENTRY(entry)); + gchar *color = NULL; +#if defined(USE_GTKBUILDER) && GTK_CHECK_VERSION(3, 4, 0) + if (gtk_widget_is_sensitive(colorbtn)) { + GdkRGBA rgba; + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(colorbtn), &rgba); + if (rgba.red < 0.99 || rgba.green < 0.99 || rgba.blue < 0.99) + color = g_strdup_printf("#%02X%02X%02X", + (guint)(rgba.red * 255), + (guint)(rgba.green * 255), + (guint)(rgba.blue * 255)); + } +#endif + data = g_new0(BOOKMARK_DATA, 1); + data->caption = g_strdelimit(g_strdup(name), "/|><.'`\"", ' '); + data->color = color; data->is_leaf = FALSE; - data->opened = bm_pixbufs->pixbuf_opened; - data->closed = bm_pixbufs->pixbuf_closed; + data->opened = bm_pixbufs->pixbuf_opened; + data->closed = bm_pixbufs->pixbuf_closed; gui_add_item_to_tree(&iter, &selected, data); bookmarks_changed = TRUE; gui_save_bookmarks(NULL, NULL); - g_free(data->caption); + /* expand and select the new folder */ GtkTreePath *path = - gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter); - gtk_tree_view_expand_to_path(GTK_TREE_VIEW(treeview), - path); + gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iter); + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(treeview), path); gtk_tree_selection_select_path(selection, path); gtk_tree_path_free(path); + g_free(data->caption); + g_free(data->color); + g_free(data); } - g_free(data); - g_free(info->text1); - g_free(info); - g_string_free(str, TRUE); + gtk_widget_destroy(dialog); +#ifdef USE_GTKBUILDER + g_object_unref(gxml); +#endif } /****************************************************************************** @@ -219,15 +245,13 @@ void on_dialog_response(GtkDialog *dialog, gint response_id, gpointer user_data) { switch (response_id) { - case GTK_RESPONSE_CANCEL: /* cancel button pressed */ - case GTK_RESPONSE_NONE: /* dialog destroyed */ - gtk_widget_destroy(GTK_WIDGET(dialog)); + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_NONE: break; - case GTK_RESPONSE_OK: /* add button pressed */ + case GTK_RESPONSE_OK: add_bookmark_button(); - gtk_widget_destroy(GTK_WIDGET(dialog)); break; - case GTK_RESPONSE_ACCEPT: /* add folder pressed */ + case GTK_RESPONSE_ACCEPT: add_folder_button(); break; } @@ -441,8 +465,6 @@ static GtkWidget *_create_bookmark_dialog(gchar *label, /* lookup the root widget */ bookmark_dialog = UI_GET_ITEM(gxml, "dialog"); - g_signal_connect(bookmark_dialog, "response", - G_CALLBACK(on_dialog_response), NULL); /* treeview */ treeview = UI_GET_ITEM(gxml, "treeview"); @@ -581,7 +603,22 @@ void gui_bookmark_dialog(gchar *label, gchar *module_name, gchar *key) _create_bookmark_dialog(label, module_name, key); if (!dialog) return; - gtk_dialog_run(GTK_DIALOG(dialog)); + gint response; + while (TRUE) { + response = gtk_dialog_run(GTK_DIALOG(dialog)); + if (response == GTK_RESPONSE_ACCEPT) { + /* New folder — keep dialog open */ + add_folder_button(); + } else if (response == GTK_RESPONSE_OK) { + /* Add bookmark — close dialog */ + add_bookmark_button(); + break; + } else { + /* Cancel or destroy */ + break; + } + } + gtk_widget_destroy(dialog); } /****************************************************************************** diff --git a/src/gtk/bookmarks_menu.c b/src/gtk/bookmarks_menu.c index 66fd28e24..2e6fef474 100644 --- a/src/gtk/bookmarks_menu.c +++ b/src/gtk/bookmarks_menu.c @@ -50,8 +50,8 @@ #include "gui/widgets.h" #include "main/settings.h" -#include "main/sidebar.h" #include "main/sword.h" +#include "main/sidebar.h" #include "main/xml.h" #include "main/module_dialogs.h" #include "main/url.hh" @@ -90,12 +90,12 @@ static void save_treeview_to_xml_bookmarks(GtkTreeIter *iter, xmlNodePtr root_node = NULL; xmlNodePtr cur_node = NULL; xmlDocPtr root_doc; - // xmlAttrPtr root_attr; gchar *caption = NULL; gchar *key = NULL; gchar *module = NULL; gchar *mod_desc = NULL; gchar *description = NULL; + gchar *color = NULL; if (!bookmarks_changed) return; @@ -104,7 +104,6 @@ static void save_treeview_to_xml_bookmarks(GtkTreeIter *iter, if (root_doc != NULL) { root_node = xmlNewNode(NULL, (const xmlChar *)"SwordBookmarks"); - //root_attr = xmlNewProp(root_node, (const xmlChar *)"syntaxVersion", (const xmlChar *)"1"); xmlDocSetRootElement(root_doc, root_node); @@ -112,24 +111,31 @@ static void save_treeview_to_xml_bookmarks(GtkTreeIter *iter, do { gtk_tree_model_get(GTK_TREE_MODEL(model), iter, - 2, &caption, - 3, &key, - 4, &module, - 5, &mod_desc, 6, &description, -1); + COL_CAPTION, &caption, + COL_KEY, &key, + COL_MODULE, &module, + COL_MODULE_DESC, &mod_desc, + COL_DESCRIPTION, &description, + COL_COLOR, &color, + -1); if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(model), iter)) { - cur_node = - xml_add_folder_to_parent(root_node, caption); + /* folder node — write color attribute when present */ + cur_node = xml_add_folder_to_parent_colored(root_node, + caption, + color); utilities_parse_treeview(cur_node, iter, GTK_TREE_MODEL(model)); - } else + } else { xml_add_bookmark_to_parent(root_node, description, key, module, mod_desc); + } g_free(caption); g_free(key); g_free(module); g_free(mod_desc); g_free(description); + g_free(color); } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), iter)); xmlSaveFormatFile(filename, root_doc, 1); @@ -167,7 +173,9 @@ static void add_item_to_tree(GtkTreeIter *iter, GtkTreeIter *parent, COL_KEY, data->key, COL_MODULE, data->module, COL_MODULE_DESC, data->module_desc, - COL_DESCRIPTION, data->description, -1); + COL_DESCRIPTION, data->description, + COL_COLOR, data->color, + -1); } /****************************************************************************** @@ -333,99 +341,132 @@ G_MODULE_EXPORT void on_dialog_activate(GtkMenuItem *menuitem, G_MODULE_EXPORT void on_edit_item_activate(GtkMenuItem *menuitem, gpointer user_data) { - GS_DIALOG *info; - gint test; GtkTreeSelection *selection; GtkTreeIter selected; - // GtkTreeIter iter; - gchar *caption = NULL; - gchar *key = NULL; - gchar *module = NULL; - gchar *mod_desc = NULL; - gchar *description = NULL; - gboolean is_leaf; - GString *str; - - str = g_string_new(NULL); - g_string_printf(str, "%s", _("Edit")); + gchar *caption = NULL, *key = NULL, *module = NULL; + gchar *mod_desc = NULL, *description = NULL, *current_color = NULL; selection = gtk_tree_view_get_selection(bookmark_tree); if (!gtk_tree_selection_get_selected(selection, NULL, &selected)) return; gtk_tree_model_get(GTK_TREE_MODEL(model), &selected, - 2, &caption, - 3, &key, - 4, &module, 5, &mod_desc, 6, &description, -1); + COL_CAPTION, &caption, COL_KEY, &key, + COL_MODULE, &module, COL_MODULE_DESC, &mod_desc, + COL_DESCRIPTION, &description, + COL_COLOR, ¤t_color, -1); - info = gui_new_dialog(); - info->title = _("Bookmark"); - info->label_top = str->str; if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(model), &selected)) { - info->label1 = _("Folder name: "); - is_leaf = FALSE; + /* --- Folder: use the dedicated folder dialog --- */ + gchar *glade_file = gui_general_user_file("folder" UI_SUFFIX, TRUE); + if (!glade_file) goto cleanup; +#ifdef USE_GTKBUILDER + GtkBuilder *gxml = gtk_builder_new(); + gtk_builder_add_from_file(gxml, glade_file, NULL); +#else + GladeXML *gxml = glade_xml_new(glade_file, NULL, NULL); +#endif + GtkWidget *dialog = GTK_WIDGET(UI_GET_ITEM(gxml, "dialog_folder")); + GtkWidget *entry = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_entry_name")); +#ifdef USE_GTKBUILDER + GtkWidget *colorbtn = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_color_button")); + GtkWidget *clearbtn = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_clear_color")); + if (!dialog || !entry || !colorbtn || !clearbtn) { + g_object_unref(gxml); goto cleanup; + } +#else + if (!dialog || !entry) goto cleanup; +#endif + gtk_window_set_title(GTK_WINDOW(dialog), _("Edit Tag")); + gtk_entry_set_text(GTK_ENTRY(entry), caption ? caption : ""); +#if defined(USE_GTKBUILDER) && GTK_CHECK_VERSION(3, 4, 0) + if (current_color && *current_color) { + GdkRGBA rgba; + if (gdk_rgba_parse(&rgba, current_color)) + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(colorbtn), &rgba); + } +#endif +#ifdef USE_GTKBUILDER + g_signal_connect_swapped(clearbtn, "clicked", + G_CALLBACK(gtk_widget_set_sensitive), colorbtn); +#endif + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { + const gchar *name = gtk_entry_get_text(GTK_ENTRY(entry)); + gchar *new_color = NULL; +#ifdef USE_GTKBUILDER + if (gtk_widget_is_sensitive(colorbtn)) { +#if GTK_CHECK_VERSION(3, 4, 0) + GdkRGBA rgba; + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(colorbtn), &rgba); + if (rgba.red < 0.99 || rgba.green < 0.99 || rgba.blue < 0.99) + new_color = g_strdup_printf("#%02X%02X%02X", + (guint)(rgba.red * 255), + (guint)(rgba.green * 255), + (guint)(rgba.blue * 255)); +#endif + } +#endif + gchar *new_caption = g_strdelimit(g_strdup(name), "/|><.'`\"", ' '); + bookmarks_changed = TRUE; + gtk_tree_store_set(GTK_TREE_STORE(model), &selected, + COL_CAPTION, new_caption, + COL_COLOR, new_color, -1); + gui_save_bookmarks(NULL, NULL); + main_display_bible(NULL, settings.currentverse); + g_free(new_caption); + g_free(new_color); + } + gtk_widget_destroy(dialog); +#ifdef USE_GTKBUILDER + g_object_unref(gxml); +#endif } else { - info->label1 = _("Bookmark name: "); - info->text2 = g_strdup(key); - info->text3 = g_strdup(module); - info->label2 = _("Verse: "); - info->label3 = _("Module: "); - is_leaf = TRUE; - } - - info->text1 = g_strdup(caption); - info->ok = TRUE; - info->cancel = TRUE; - - test = gui_gs_dialog(info); - if (test == GS_OK) { - BOOKMARK_DATA *data = g_new(BOOKMARK_DATA, 1); - data->caption = info->text1; - data->key = NULL; - data->module = NULL; - data->module_desc = NULL; - data->description = NULL; - if (is_leaf) { - data->opened = bm_pixbufs->pixbuf_helpdoc; - data->closed = NULL; - data->key = info->text2; - data->module = info->text3; - data->module_desc = - g_strdup(main_get_module_description(info->text3)); - if ((strlen(description) > 1) || (strcmp(caption, info->text1))) { - data->description = info->text1; - } else - data->description = NULL; - data->is_leaf = TRUE; - } else { - data->opened = bm_pixbufs->pixbuf_opened; - data->closed = bm_pixbufs->pixbuf_closed; - data->is_leaf = FALSE; + /* --- Leaf bookmark: generic dialog --- */ + GS_DIALOG *info = gui_new_dialog(); + GString *str = g_string_new(NULL); + g_string_printf(str, "%s", _("Edit")); + info->title = _("Bookmark"); + info->label_top = str->str; + info->label1 = _("Bookmark name: "); + info->text1 = g_strdup(caption); + info->text2 = g_strdup(key); + info->text3 = g_strdup(module); + info->label2 = _("Verse: "); + info->label3 = _("Module: "); + info->ok = TRUE; + info->cancel = TRUE; + if (gui_gs_dialog(info) == GS_OK) { + BOOKMARK_DATA *data = g_new0(BOOKMARK_DATA, 1); + data->caption = info->text1; + data->key = info->text2; + data->module = info->text3; + data->module_desc = g_strdup(main_get_module_description(info->text3)); + data->description = ((description && strlen(description) > 1) || + (caption && strcmp(caption, info->text1))) + ? info->text1 : NULL; + data->is_leaf = TRUE; + data->opened = bm_pixbufs->pixbuf_helpdoc; + gtk_tree_store_set(GTK_TREE_STORE(model), &selected, + COL_OPEN_PIXBUF, data->opened, + COL_CLOSED_PIXBUF, data->closed, + COL_CAPTION, data->caption, + COL_KEY, data->key, + COL_MODULE, data->module, + COL_MODULE_DESC, data->module_desc, + COL_DESCRIPTION, data->description, -1); + bookmarks_changed = TRUE; + gui_save_bookmarks(NULL, NULL); + g_free(data->module_desc); + g_free(data); } - - gtk_tree_store_set(GTK_TREE_STORE(model), &selected, - COL_OPEN_PIXBUF, data->opened, - COL_CLOSED_PIXBUF, data->closed, - COL_CAPTION, data->caption, - COL_KEY, data->key, - COL_MODULE, data->module, - COL_MODULE_DESC, data->module_desc, - COL_DESCRIPTION, data->description, -1); - bookmarks_changed = TRUE; - gui_save_bookmarks(NULL, NULL); - g_free(data); + g_free(info->text1); + if (info->text2) g_free(info->text2); + if (info->text3) g_free(info->text3); + g_free(info); + g_string_free(str, TRUE); } - g_free(info->text1); // we used g_strdup() - if (info->text2) - g_free(info->text2); - if (info->text3) - g_free(info->text3); - g_free(info); - g_free(caption); - g_free(key); - g_free(module); - g_free(mod_desc); - g_free(description); - g_string_free(str, TRUE); +cleanup: + g_free(caption); g_free(key); g_free(module); + g_free(mod_desc); g_free(description); g_free(current_color); } //dialog_export_bookmarks_response_cb @@ -674,6 +715,7 @@ void on_add_bookmark_activate(GtkMenuItem *menuitem, gpointer user_data) data->description = NULL; else data->description = info->text1; + data->color = NULL; /* bookmark leaves never have a color */ data->is_leaf = TRUE; data->opened = bm_pixbufs->pixbuf_helpdoc; data->closed = NULL; @@ -734,53 +776,75 @@ G_MODULE_EXPORT void on_new_folder_activate(GtkMenuItem *menuitem, { GtkTreeIter selected; GtkTreeIter iter; - // gchar *caption = NULL; - // gchar *key = NULL; - // gchar *module = NULL; - char *t; - gint test; - GS_DIALOG *info; BOOKMARK_DATA *data; - GString *str; if (!gtk_tree_selection_get_selected(current_selection, NULL, &selected)) return; - t = "/|><.'`\""; - str = g_string_new(""); - info = gui_new_dialog(); - //info->stock_icon = GTK_STOCK_OPEN; - info->title = _("Bookmark"); - g_string_printf(str, "%s", - _("Enter Folder Name")); - info->label_top = str->str; - info->text1 = g_strdup(_("Folder Name")); - info->label1 = _("Folder: "); - info->ok = TRUE; - info->cancel = TRUE; + gchar *glade_file = gui_general_user_file("folder" UI_SUFFIX, TRUE); + g_return_if_fail(glade_file != NULL); +#ifdef USE_GTKBUILDER + GtkBuilder *gxml = gtk_builder_new(); + gtk_builder_add_from_file(gxml, glade_file, NULL); +#else + GladeXML *gxml = glade_xml_new(glade_file, NULL, NULL); +#endif + g_free(glade_file); - data = g_new(BOOKMARK_DATA, 1); - /*** open dialog to get name for new folder ***/ - test = gui_gs_dialog(info); - if (test == GS_OK) { - char *buf = g_strdelimit(info->text1, t, ' '); - data->caption = g_strdup(buf); - data->key = NULL; - data->module = NULL; - data->module_desc = NULL; - data->description = NULL; + GtkWidget *dialog = GTK_WIDGET(UI_GET_ITEM(gxml, "dialog_folder")); + GtkWidget *entry = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_entry_name")); +#ifdef USE_GTKBUILDER + GtkWidget *colorbtn = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_color_button")); + GtkWidget *clearbtn = GTK_WIDGET(UI_GET_ITEM(gxml, "folder_clear_color")); + if (!dialog || !entry || !colorbtn || !clearbtn) { + g_printerr("ERROR: dialog_folder widgets not found\n"); + g_object_unref(gxml); + return; + } +#else + if (!dialog || !entry) { + return; + } +#endif + + gtk_window_set_title(GTK_WINDOW(dialog), _("New Folder")); + gtk_entry_set_text(GTK_ENTRY(entry), ""); + +#ifdef USE_GTKBUILDER + g_signal_connect_swapped(clearbtn, "clicked", + G_CALLBACK(gtk_widget_set_sensitive), colorbtn); +#endif + + gint response = gtk_dialog_run(GTK_DIALOG(dialog)); + if (response == GTK_RESPONSE_OK) { + const gchar *name = gtk_entry_get_text(GTK_ENTRY(entry)); + gchar *color = NULL; +#if defined(USE_GTKBUILDER) && GTK_CHECK_VERSION(3, 4, 0) + if (gtk_widget_is_sensitive(colorbtn)) { + GdkRGBA rgba; + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(colorbtn), &rgba); + if (rgba.red < 0.99 || rgba.green < 0.99 || rgba.blue < 0.99) + color = g_strdup_printf("#%02X%02X%02X", + (guint)(rgba.red * 255), + (guint)(rgba.green * 255), + (guint)(rgba.blue * 255)); + } +#endif + data = g_new0(BOOKMARK_DATA, 1); + data->caption = g_strdelimit(g_strdup(name), "/|><.'`\"", ' '); + data->color = color; data->is_leaf = FALSE; - data->opened = bm_pixbufs->pixbuf_opened; - data->closed = bm_pixbufs->pixbuf_closed; - add_item_to_tree(&iter, &selected, data); + data->opened = bm_pixbufs->pixbuf_opened; + data->closed = bm_pixbufs->pixbuf_closed; bookmarks_changed = TRUE; + add_item_to_tree(&iter, &selected, data); gui_save_bookmarks(NULL, NULL); g_free(data->caption); + g_free(data->color); + g_free(data); } - g_free(data); - g_free(info->text1); - g_free(info); - g_string_free(str, TRUE); + gtk_widget_destroy(dialog); + g_object_unref(gxml); } /****************************************************************************** @@ -842,6 +906,53 @@ G_MODULE_EXPORT void on_open_in_tab_activate(GtkMenuItem *menuitem, * void */ +#if GTK_CHECK_VERSION(3, 4, 0) +G_MODULE_EXPORT void on_set_tag_color_activate(GtkMenuItem *menuitem, + gpointer user_data) +{ + GtkTreeIter selected; + gchar *color = NULL; + GtkTreeSelection *selection = gtk_tree_view_get_selection(bookmark_tree); + + if (!gtk_tree_selection_get_selected(selection, NULL, &selected)) + return; + + /* Only folders get a color */ + if (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(model), &selected)) + return; + + GtkWidget *dialog = gtk_color_chooser_dialog_new( + _("Choose folder color"), GTK_WINDOW(widgets.app)); + + /* Pre-load existing color if any */ + gtk_tree_model_get(GTK_TREE_MODEL(model), &selected, + COL_COLOR, &color, -1); + if (color && *color) { + GdkRGBA rgba; + if (gdk_rgba_parse(&rgba, color)) + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(dialog), &rgba); + } + g_free(color); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { + GdkRGBA rgba; + gchar *hex; + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &rgba); + hex = g_strdup_printf("#%02X%02X%02X", + (guint)(rgba.red * 255), + (guint)(rgba.green * 255), + (guint)(rgba.blue * 255)); + bookmarks_changed = TRUE; + gtk_tree_store_set(GTK_TREE_STORE(model), &selected, + COL_COLOR, hex, -1); + g_free(hex); + gui_save_bookmarks(NULL, NULL); + main_display_bible(NULL, settings.currentverse); + } + gtk_widget_destroy(dialog); +} +#endif + void gui_create_bookmark_menu(void) { gchar *glade_file; @@ -872,7 +983,8 @@ void gui_create_bookmark_menu(void) menu.delete = UI_GET_ITEM(gxml, "delete_item"); menu.reorder = UI_GET_ITEM(gxml, "allow_reordering"); menu.bibletime = UI_GET_ITEM(gxml, "import_bibletime_bookmarks1"); - menu.remove = UI_GET_ITEM(gxml, "remove_folder"); + menu.remove = UI_GET_ITEM(gxml, "remove_folder"); + menu.set_color = UI_GET_ITEM(gxml, "set_tag_color"); gtk_widget_set_sensitive(menu.in_tab, FALSE); gtk_widget_set_sensitive(menu.in_dialog, FALSE); diff --git a/src/gtk/bookmarks_treeview.c b/src/gtk/bookmarks_treeview.c index 91b70dff7..31714d266 100644 --- a/src/gtk/bookmarks_treeview.c +++ b/src/gtk/bookmarks_treeview.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -203,6 +204,7 @@ void gui_verselist_to_bookmarks(GList *verses, gint save_as_single) static void get_xml_folder_data(xmlNodePtr cur, BOOKMARK_DATA *data) { xmlChar *folder; + gchar *color; folder = xmlGetProp(cur, (const xmlChar *)"caption"); data->caption = g_strdup((char *)folder); @@ -213,6 +215,12 @@ static void get_xml_folder_data(xmlNodePtr cur, BOOKMARK_DATA *data) data->is_leaf = FALSE; data->opened = bm_pixbufs->pixbuf_opened; data->closed = bm_pixbufs->pixbuf_closed; + + /* color is optional — NULL when the folder has no tag color assigned */ + color = xml_get_folder_color(cur); + data->color = color ? g_strdup(color) : NULL; + if (color) + xmlFree((xmlChar *)color); } /****************************************************************************** @@ -261,6 +269,7 @@ static void get_xml_bookmark_data(xmlNodePtr cur, BOOKMARK_DATA *data) data->description = g_strdup((char *)description); data->module_desc = g_strdup((char *)mod_desc); data->is_leaf = TRUE; + data->color = NULL; /* leaves (bookmarks) never carry a color */ } /****************************************************************************** @@ -291,6 +300,8 @@ static void free_bookmark_data(BOOKMARK_DATA *data) g_free(data->module_desc); if (data->description) g_free(data->description); + if (data->color) + g_free(data->color); } /****************************************************************************** @@ -322,7 +333,9 @@ void gui_add_item_to_tree(GtkTreeIter *iter, GtkTreeIter *parent, COL_KEY, data->key, COL_MODULE, data->module, COL_MODULE_DESC, data->module_desc, - COL_DESCRIPTION, data->description, -1); + COL_DESCRIPTION, data->description, + COL_COLOR, data->color, + -1); } /****************************************************************************** @@ -578,6 +591,60 @@ static void create_pixbufs(void) * void */ +/* Creates a round color swatch pixbuf using Cairo (14x14 px) */ +#ifdef USE_GTK_3 +static GdkPixbuf *make_color_dot(const gchar *hex_color) +{ + const gint SIZE = 14; + cairo_surface_t *surface; + cairo_t *cr; + GdkPixbuf *pixbuf; + GdkRGBA rgba; + + if (!hex_color || !*hex_color) + return NULL; + if (!gdk_rgba_parse(&rgba, hex_color)) + return NULL; + + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, SIZE, SIZE); + cr = cairo_create(surface); + + /* transparent background */ + cairo_set_source_rgba(cr, 0, 0, 0, 0); + cairo_paint(cr); + + /* filled circle */ + cairo_set_source_rgba(cr, rgba.red, rgba.green, rgba.blue, 1.0); + cairo_arc(cr, SIZE/2.0, SIZE/2.0, SIZE/2.0 - 1, 0, 2 * G_PI); + cairo_fill_preserve(cr); + + /* thin dark border */ + cairo_set_source_rgba(cr, 0, 0, 0, 0.35); + cairo_set_line_width(cr, 1.0); + cairo_stroke(cr); + + cairo_destroy(cr); + pixbuf = gdk_pixbuf_get_from_surface(surface, 0, 0, SIZE, SIZE); + cairo_surface_destroy(surface); + return pixbuf; +} + +/* Cell data function: generates the color dot pixbuf on the fly */ +static void color_dot_cell_func(GtkTreeViewColumn *col, + GtkCellRenderer *renderer, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + gchar *color = NULL; + GdkPixbuf *dot = NULL; + gtk_tree_model_get(tree_model, iter, COL_COLOR, &color, -1); + dot = make_color_dot(color); + g_object_set(renderer, "pixbuf", dot, NULL); + if (dot) g_object_unref(dot); + g_free(color); +} +#endif void gui_add_columns(GtkTreeView *tree) { GtkTreeViewColumn *column; @@ -592,6 +659,16 @@ void gui_add_columns(GtkTreeView *tree) "pixbuf-expander-open", COL_OPEN_PIXBUF, "pixbuf-expander-closed", COL_CLOSED_PIXBUF, NULL); + +#ifdef USE_GTK_3 + /* Color dot renderer — round swatch drawn with Cairo */ + renderer = GTK_CELL_RENDERER(gtk_cell_renderer_pixbuf_new()); + gtk_tree_view_column_pack_start(column, renderer, FALSE); + gtk_tree_view_column_set_cell_data_func(column, renderer, + color_dot_cell_func, + NULL, NULL); +#endif + /* Caption renderer */ renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new()); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_set_attributes(column, renderer, @@ -653,12 +730,14 @@ static GtkTreeModel *create_model(void) { /* create tree store */ model = gtk_tree_store_new(N_COLUMNS, - GDK_TYPE_PIXBUF, - GDK_TYPE_PIXBUF, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING); + GDK_TYPE_PIXBUF, /* COL_OPEN_PIXBUF */ + GDK_TYPE_PIXBUF, /* COL_CLOSED_PIXBUF */ + G_TYPE_STRING, /* COL_CAPTION */ + G_TYPE_STRING, /* COL_KEY */ + G_TYPE_STRING, /* COL_MODULE */ + G_TYPE_STRING, /* COL_MODULE_DESC */ + G_TYPE_STRING, /* COL_DESCRIPTION */ + G_TYPE_STRING); /* COL_COLOR */ return GTK_TREE_MODEL(model); } @@ -680,6 +759,13 @@ static GtkTreeModel *create_model(void) * void */ +static void lambda_open_url(GtkMenuItem *item, gpointer data) +{ + const gchar *url = (const gchar *)g_object_get_data(G_OBJECT(item), "url"); + if (url) + main_url_handler(url, TRUE); +} + static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { @@ -690,6 +776,7 @@ static gboolean button_release_event(GtkWidget *widget, gchar *key = NULL; gchar *module = NULL; gchar *mod_desc = NULL; + gchar *range_start = NULL; gchar *description = NULL; button_one = FALSE; @@ -781,34 +868,131 @@ static gboolean button_release_event(GtkWidget *widget, } if (is_selected) { if (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(model), &selected) && key != NULL) { - // might have an abbrev. get the real. const gchar *real_mod = main_abbrev_to_name(module); - gchar *url = NULL; - - if (!strcmp(module, "studypad")) - url = - g_strdup_printf("passagestudy.jsp?action=showStudypad&" - "type=9&value=%s&module=%s", - main_url_encode(key), - main_url_encode((real_mod - ? real_mod - : module))); - - else if (button_one) - url = - g_strdup_printf("passagestudy.jsp?action=showBookmark&" - "type=%s&value=%s&module=%s", - "currentTab", - main_url_encode(key), - main_url_encode((real_mod - ? real_mod - : module))); - if (url) { + /* multi if contains ";", "-" (range) or comma between verse numbers */ + gboolean multi = (strchr(key, ';') != NULL); + gboolean is_range = FALSE; + if (strchr(key, '-')) { + /* verse range: navigate to first verse directly */ + const gchar *colon = strchr(key, ':'); + const gchar *dash = strchr(key, '-'); + if (colon && dash && dash > colon) { + is_range = TRUE; + range_start = g_strndup(key, dash - key); + } + } + if (!multi && strchr(key, ',')) { + /* check if comma separates verses: "Eph 2:8,9" */ + const gchar *colon = strchr(key, ':'); + const gchar *comma = strchr(key, ','); + if (colon && comma && comma > colon) + multi = TRUE; + } + + if (is_range && button_one && range_start) { + /* navigate directly to first verse of range */ + gchar *url = g_strdup_printf( + "passagestudy.jsp?action=showBookmark&" + "type=%s&value=%s&module=%s", + "currentTab", + main_url_encode(range_start), + main_url_encode((real_mod ? real_mod : module))); main_url_handler(url, TRUE); g_free(url); + g_free(range_start); + range_start = NULL; + } else if (multi && button_one) { + /* split on ";" first, then expand "book ch:v1,v2" */ + GList *refs = NULL; + gchar **semis = g_strsplit(key, ";", -1); + gchar *last_book = NULL; + for (gint si = 0; semis[si]; si++) { + gchar *part = g_strstrip(semis[si]); + if (!*part) continue; + gchar *full_part; + /* if no space in part but has colon, prepend last book */ + if (last_book && strchr(part, ':') && !strchr(part, ' ')) + full_part = g_strdup_printf("%s %s", last_book, part); + else { + full_part = g_strdup(part); + /* extract book name: before last space before colon */ + const gchar *col = strchr(full_part, ':'); + if (col) { + const gchar *sp = col; + while (sp > full_part && *sp != ' ') sp--; + if (sp > full_part) { + g_free(last_book); + last_book = g_strndup(full_part, sp - full_part); + } + } + } + /* handle comma-separated verses */ + const gchar *colon = strchr(full_part, ':'); + const gchar *comma = strchr(full_part, ','); + if (colon && comma && comma > colon) { + gchar *prefix = g_strndup(full_part, colon - full_part + 1); + gchar **vnums = g_strsplit(colon + 1, ",", -1); + for (gint vi = 0; vnums[vi]; vi++) { + gchar *vn = g_strstrip(vnums[vi]); + if (*vn) + refs = g_list_append(refs, + g_strdup_printf("%s%s", prefix, vn)); + } + g_strfreev(vnums); + g_free(prefix); + } else { + refs = g_list_append(refs, g_strdup(full_part)); + } + g_free(full_part); + } + g_free(last_book); + g_strfreev(semis); + GtkWidget *popup = gtk_menu_new(); + for (GList *l = refs; l; l = l->next) { + gchar *ref = (gchar *)l->data; + GtkWidget *item = gtk_menu_item_new_with_label(ref); + gchar *url = g_strdup_printf( + "passagestudy.jsp?action=showBookmark&" + "type=%s&value=%s&module=%s", + "currentTab", + main_url_encode(ref), + main_url_encode((real_mod ? real_mod : module))); + g_object_set_data_full(G_OBJECT(item), "url", url, g_free); + g_signal_connect(item, "activate", + G_CALLBACK(lambda_open_url), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(popup), item); + } + g_list_free_full(refs, g_free); + gtk_widget_show_all(popup); +#if GTK_CHECK_VERSION(3, 22, 0) + gtk_menu_popup_at_pointer(GTK_MENU(popup), NULL); +#else + gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL, 1, + gtk_get_current_event_time()); +#endif + } else { + gchar *url = NULL; + if (!strcmp(module, "studypad")) + url = g_strdup_printf( + "passagestudy.jsp?action=showStudypad&" + "type=9&value=%s&module=%s", + main_url_encode(key), + main_url_encode((real_mod ? real_mod : module))); + else if (button_one) + url = g_strdup_printf( + "passagestudy.jsp?action=showBookmark&" + "type=%s&value=%s&module=%s", + "currentTab", + main_url_encode(key), + main_url_encode((real_mod ? real_mod : module))); + if (url) { + main_url_handler(url, TRUE); + g_free(url); + } } } g_free(caption); + g_free(range_start); g_free(key); g_free(module); } @@ -831,6 +1015,87 @@ static gboolean button_release_event(GtkWidget *widget, * GtkWidget* */ +/** + * bookmark_get_tag_color_for_key: + * @osiskey: a verse key string, e.g. "Gen 1:1" + * + * Walks the bookmark GtkTreeStore and returns the color of the + * first tag-group folder that contains a bookmark matching @osiskey. + * Returns NULL if none found. Caller must g_free() the result. + */ +static void debug_dump_recursive(GtkTreeIter *parent, int depth) +{ + GtkTreeIter child; + if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(model), &child, parent)) + return; + do { + gchar *caption = NULL, *color = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(model), &child, + COL_CAPTION, &caption, COL_COLOR, &color, -1); + debug_dump_recursive(&child, depth + 1); + g_free(caption); g_free(color); + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &child)); +} + +void bookmark_debug_dump_colors(void) +{ + GtkTreeIter root; + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &root)) { + } + debug_dump_recursive(&root, 0); +} + + +gchar *bookmark_get_tag_color_for_key(const gchar *osiskey) +{ + GtkTreeIter folder, child; + gchar *color = NULL; + + if (!osiskey || !model) + return NULL; + + /* iterate top-level folders */ + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &folder)) + return NULL; + + do { + gchar *folder_color = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(model), &folder, + COL_COLOR, &folder_color, -1); + if (!folder_color || !*folder_color) { + g_free(folder_color); + continue; + } + /* scan children of this colored folder */ + if (gtk_tree_model_iter_children(GTK_TREE_MODEL(model), + &child, &folder)) { + do { + gchar *key = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(model), + &child, + COL_KEY, &key, -1); + /* compare case-insensitively; + * also try stripping trailing spaces */ + gchar *k = key ? g_strstrip(g_strdup(key)) : NULL; + gchar *q = osiskey ? g_strstrip(g_strdup(osiskey)) : NULL; + gboolean match = (k && q && !g_ascii_strcasecmp(k, q)); + g_free(k); g_free(q); + if (match) { + color = g_strdup(folder_color); + g_free(key); + g_free(folder_color); + return color; + } + g_free(key); + } while (gtk_tree_model_iter_next( + GTK_TREE_MODEL(model), &child)); + } + g_free(folder_color); + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &folder)); + + return NULL; +} + GtkWidget *gui_create_bookmark_tree(void) { GtkWidget *tree; @@ -858,6 +1123,7 @@ GtkWidget *gui_create_bookmark_tree(void) GINT_TO_POINTER(0)); use_dialog = FALSE; bookmark_tree = GTK_TREE_VIEW(tree); + gtk_tree_view_set_reorderable(bookmark_tree, TRUE); g_signal_connect(model, "row-changed", G_CALLBACK(row_changed), NULL); diff --git a/src/gtk/utilities.c b/src/gtk/utilities.c index bba3588f1..2a6b357bd 100644 --- a/src/gtk/utilities.c +++ b/src/gtk/utilities.c @@ -55,6 +55,7 @@ #include "main/sword.h" #include "main/url.hh" #include "main/xml.h" +#include "gui/bookmarks_treeview.h" #ifdef WIN32 #undef DATADIR @@ -141,32 +142,34 @@ void utilities_parse_treeview(xmlNodePtr parent, GtkTreeIter *tree_parent, gchar *module = NULL; gchar *mod_desc = NULL; gchar *description = NULL; - + gchar *color = NULL; gtk_tree_model_iter_children(GTK_TREE_MODEL(model), &child, tree_parent); - do { gtk_tree_model_get(GTK_TREE_MODEL(model), &child, - 2, &caption, - 3, &key, - 4, &module, - 5, &mod_desc, 6, &description, -1); + COL_CAPTION, &caption, + COL_KEY, &key, + COL_MODULE, &module, + COL_MODULE_DESC, &mod_desc, + COL_DESCRIPTION, &description, + COL_COLOR, &color, + -1); if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(model), &child)) { - cur_node = xml_add_folder_to_parent(parent, - caption); + cur_node = xml_add_folder_to_parent_colored(parent, + caption, + color); utilities_parse_treeview(cur_node, &child, model); - } else xml_add_bookmark_to_parent(parent, description, key, module, mod_desc); - g_free(caption); g_free(key); g_free(module); g_free(mod_desc); g_free(description); + g_free(color); } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &child)); } diff --git a/src/gui/bookmarks_menu.h b/src/gui/bookmarks_menu.h index 0a62b7969..41d1109ce 100644 --- a/src/gui/bookmarks_menu.h +++ b/src/gui/bookmarks_menu.h @@ -41,6 +41,7 @@ struct _bookmark_menu GtkWidget *bibletime; GtkWidget *rr_submenu; GtkWidget *remove; + GtkWidget *set_color; }; typedef struct _bookmark_menu BOOKMARK_MENU; extern BOOKMARK_MENU menu; @@ -75,6 +76,9 @@ void on_insert_bookmark_activate(GtkMenuItem *menuitem, gpointer user_data); void on_new_folder_activate(GtkMenuItem *menuitem, gpointer user_data); +#if GTK_CHECK_VERSION(3, 4, 0) +void on_set_tag_color_activate(GtkMenuItem *menuitem, gpointer user_data); +#endif void on_open_in_tab_activate(GtkMenuItem *menuitem, gpointer user_data); diff --git a/src/gui/bookmarks_treeview.h b/src/gui/bookmarks_treeview.h index f7be52e60..7464737b7 100644 --- a/src/gui/bookmarks_treeview.h +++ b/src/gui/bookmarks_treeview.h @@ -27,6 +27,7 @@ extern "C" { #endif #include #include + enum { COL_OPEN_PIXBUF, COL_CLOSED_PIXBUF, @@ -35,6 +36,8 @@ enum { COL_MODULE, COL_MODULE_DESC, COL_DESCRIPTION, + COL_COLOR, /* hex color string for tag groups, e.g. "#378ADD" + * NULL or "" means no color assigned (plain bookmark folder) */ N_COLUMNS }; @@ -53,6 +56,7 @@ struct _bookmark_data gchar *module; gchar *module_desc; gchar *description; + gchar *color; /* hex color string for folders/tag groups, NULL for leaves */ gboolean is_leaf; GdkPixbuf *opened; GdkPixbuf *closed; @@ -69,6 +73,8 @@ void gui_add_item_to_tree(GtkTreeIter *iter, GtkTreeIter *parent, void gui_verselist_to_bookmarks(GList *verses, gint save_as_single); GtkWidget *gui_create_bookmark_tree(void); +void bookmark_debug_dump_colors(void); +gchar *bookmark_get_tag_color_for_key(const gchar *osiskey); void gui_parse_bookmarks(GtkTreeView *tree, const xmlChar *file, GtkTreeIter *parent); GtkWidget *gui_create_dialog_add_bookmark(gchar *label, diff --git a/src/main/display.cc b/src/main/display.cc index 53484cabd..afc366060 100644 --- a/src/main/display.cc +++ b/src/main/display.cc @@ -51,6 +51,7 @@ #include "main/xml.h" #include "gui/utilities.h" +#include "gui/bookmarks_treeview.h" #include "gui/widgets.h" #include "gui/dialog.h" @@ -1350,6 +1351,157 @@ GTKChapDisp::getVerseAfter(SWModule &imodule) } } +/* Returns white or black depending on background luminance */ +static const char *text_color_for_bg(const gchar *hex_color) +{ + if (!hex_color || hex_color[0] != '#' || strlen(hex_color) < 7) + return "#000000"; + int r = 0, g = 0, b = 0; + sscanf(hex_color + 1, "%02x%02x%02x", &r, &g, &b); + /* relative luminance (ITU-R BT.709) */ + double lum = 0.2126 * r + 0.7152 * g + 0.0722 * b; + return (lum < 128.0) ? "#FFFFFF" : "#000000"; +} + +/* Returns the tag color for a given VerseKey by comparing OSIS refs. + * Walks the GtkTreeStore directly from C++. */ +static gchar *get_tag_color_for_versekey(VerseKey *vk) +{ + extern GtkTreeStore *model; + if (!model || !vk) return NULL; + + gchar *osisref = g_strdup_printf("%s.%d.%d", + vk->getOSISBookName(), + vk->getChapter(), + vk->getVerse()); + + GtkTreeIter root; + if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &root)) { + g_free(osisref); return NULL; + } + + GQueue *stack = g_queue_new(); + GQueue *colors = g_queue_new(); + GtkTreeIter child; + if (gtk_tree_model_iter_children(GTK_TREE_MODEL(model), &child, &root)) { + do { + GtkTreeIter *copy = g_new(GtkTreeIter, 1); + *copy = child; + g_queue_push_tail(stack, copy); + g_queue_push_tail(colors, NULL); + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &child)); + } + + gchar *result = NULL; + while (!g_queue_is_empty(stack) && !result) { + GtkTreeIter *iter = (GtkTreeIter *)g_queue_pop_head(stack); + gchar *inherited = (gchar *)g_queue_pop_head(colors); + gchar *node_color = NULL, *node_key = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(model), iter, + COL_COLOR, &node_color, + COL_KEY, &node_key, -1); + const gchar *effective = (node_color && *node_color) + ? node_color : inherited; + if (node_key) { + /* handle multi-reference keys with ranges, semicolons, commas */ + gchar **parts = g_strsplit(node_key, ";", -1); + gchar *last_book_chap = NULL; + for (gint pi = 0; parts[pi] && !result; pi++) { + gchar *part = g_strstrip(parts[pi]); + if (!*part) continue; + /* resolve partial ref: "16:36" -> "Acts 16:36" */ + gchar *full_part; + if (last_book_chap && !strchr(part, ' ') && strchr(part, ':')) + full_part = g_strdup_printf("%s %s", last_book_chap, part); + else + full_part = g_strdup(part); + /* check for verse range: "1 Cor 15:1-4" */ + const gchar *col = strchr(full_part, ':'); + const gchar *dash = col ? strchr(col, '-') : NULL; + if (col && dash) { + /* range: check if curVerse is between start and end */ + gchar *range_ref = g_strndup(full_part, dash - full_part); + VerseKey vk_start; + vk_start.setLocale(vk->getLocale()); + vk_start.setText(range_ref); + g_free(range_ref); + int verse_end = atoi(dash + 1); + /* compare numerically */ + gboolean same_book = !strcmp(vk->getOSISBookName(), + vk_start.getOSISBookName()); + if (same_book && + vk->getChapter() == vk_start.getChapter() && + vk->getVerse() >= vk_start.getVerse() && + vk->getVerse() <= verse_end && + effective) + result = g_strdup(effective); + } else { + /* handle comma-separated verses */ + gchar **verses = g_strsplit(full_part, ",", -1); + gchar *book_chapter = NULL; + for (gint vi = 0; verses[vi] && !result; vi++) { + gchar *v = g_strstrip(verses[vi]); + gchar *full_ref; + if (strchr(v, ' ') || strchr(v, '.') || !book_chapter) + full_ref = g_strdup(v); + else + full_ref = g_strdup_printf("%s:%s", book_chapter, v); + VerseKey vk2; + vk2.setLocale(vk->getLocale()); + vk2.setText(full_ref); + gchar *ref2 = g_strdup_printf("%s.%d.%d", + vk2.getOSISBookName(), + vk2.getChapter(), + vk2.getVerse()); + if (!g_ascii_strcasecmp(osisref, ref2) && effective) + result = g_strdup(effective); + if (!book_chapter && strchr(full_ref, ':')) { + gchar *colon = strrchr(full_ref, ':'); + book_chapter = g_strndup(full_ref, colon - full_ref); + } + g_free(ref2); + g_free(full_ref); + } + g_strfreev(verses); + g_free(book_chapter); + } + /* update last_book_chap for partial ref resolution */ + if (col) { + const gchar *sp = col; + while (sp > full_part && *sp != ' ') sp--; + if (sp > full_part) { + g_free(last_book_chap); + last_book_chap = g_strndup(full_part, sp - full_part); + } + } + g_free(full_part); + } + g_free(last_book_chap); + g_strfreev(parts); + g_free(node_key); + } else { + if (gtk_tree_model_iter_children(GTK_TREE_MODEL(model), + &child, iter)) { + do { + GtkTreeIter *copy = g_new(GtkTreeIter, 1); + *copy = child; + g_queue_push_tail(stack, copy); + g_queue_push_tail(colors, + effective ? g_strdup(effective) : NULL); + } while (gtk_tree_model_iter_next( + GTK_TREE_MODEL(model), &child)); + } + } + g_free(node_color); + g_free(inherited); + g_free(iter); + } + g_queue_free_full(stack, g_free); + g_queue_free_full(colors, g_free); + g_free(osisref); + return result; +} + char GTKChapDisp::display(SWModule &imodule) { @@ -1486,10 +1638,23 @@ GTKChapDisp::display(SWModule &imodule) // special contrasty highlighting marked_element *e; + gchar *tag_color = get_tag_color_for_versekey(key); + /* tag-group color highlight */ + if (tag_color) { + const char *fg = text_color_for_bg(tag_color); + buf = g_strdup_printf( + "", + tag_color, fg, tag_color); + swbuf.append(buf); + g_free(buf); + } + if (((e = marked_cache_check(key->getVerse())) && settings.annotate_highlight) || ((key->getVerse() == curVerse) && - settings.versehighlight)) { + settings.versehighlight && !tag_color)) { buf = g_strdup_printf( "" "", @@ -1572,6 +1737,13 @@ GTKChapDisp::display(SWModule &imodule) ReadAloud(curVerse, rework->str); } + /* close tag-group color span */ + if (tag_color) { + swbuf.append(""); + g_free(tag_color); + tag_color = NULL; + } + if (settings.versestyle) { if ((key->getVerse() != curVerse) || (!settings.versehighlight && diff --git a/src/main/main.c b/src/main/main.c index ef18f02b1..155ac597c 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -251,6 +251,28 @@ int main(int argc, char *argv[]) */ settings_init(argc, argv, newconfigs, newbookmarks); + /* Phase 2: backup bookmarks.xml once on first run after upgrade. + * The backup is skipped if it already exists. */ + { + gchar *bm = g_strdup_printf("%s/bookmarks/bookmarks.xml", + settings.gSwordDir); + gchar *bmbak = g_strdup_printf("%s/bookmarks/bookmarks.xml.bak", + settings.gSwordDir); + if (g_file_test(bm, G_FILE_TEST_EXISTS) && + !g_file_test(bmbak, G_FILE_TEST_EXISTS)) { + GError *err = NULL; + GFile *src_f = g_file_new_for_path(bm); + GFile *dst_f = g_file_new_for_path(bmbak); + g_file_copy(src_f, dst_f, + G_FILE_COPY_NONE, NULL, NULL, NULL, &err); + if (err) g_error_free(err); + g_object_unref(src_f); + g_object_unref(dst_f); + } + g_free(bm); + g_free(bmbak); + } + gui_init(argc, argv); gui_splash_init(); diff --git a/src/main/settings.c b/src/main/settings.c index 1c9b9c3ca..83e17329e 100644 --- a/src/main/settings.c +++ b/src/main/settings.c @@ -182,9 +182,10 @@ int settings_init(int argc, char **argv, int new_configs, g_free(sword_dir); /* moved here from crud locations in backend. */ - main_init_language_map(); language_init(); + main_init_language_map(); + gui_init(argc, argv); init_bookmarks(new_bookmarks); diff --git a/src/main/xml.c b/src/main/xml.c index 4bd694779..1587d0d1b 100644 --- a/src/main/xml.c +++ b/src/main/xml.c @@ -24,6 +24,7 @@ #endif #include +#include #include #include #include @@ -141,6 +142,62 @@ xmlNodePtr xml_add_folder_to_parent(xmlNodePtr parent, gchar *caption) return cur_node; } +/****************************************************************************** + * Name + * xml_add_folder_to_parent_colored + * + * Synopsis + * #include "main/xml.h" + * + * xmlNodePtr xml_add_folder_to_parent_colored(xmlNodePtr parent, + * gchar *caption, + * const gchar *color) + * + * Description + * Like xml_add_folder_to_parent() but also writes the optional "color" + * attribute (e.g. "#378ADD") used by tag groups. Pass NULL or "" to + * omit the attribute (behaves identically to the plain variant). + * + * Return value + * xmlNodePtr - the new Folder node + */ + +xmlNodePtr xml_add_folder_to_parent_colored(xmlNodePtr parent, + gchar *caption, + const gchar *color) +{ + xmlNodePtr cur_node = xml_add_folder_to_parent(parent, caption); + + if (color && *color) + (void)xmlNewProp(cur_node, + (const xmlChar *)"color", + (const xmlChar *)color); + return cur_node; +} + +/****************************************************************************** + * Name + * xml_get_folder_color + * + * Synopsis + * #include "main/xml.h" + * + * gchar *xml_get_folder_color(xmlNodePtr node) + * + * Description + * Returns the "color" attribute of a Folder node, or NULL when absent. + * The caller must free the returned string with xmlFree() (it is an + * xmlChar * cast to gchar *). + * + * Return value + * gchar * (xmlChar * underneath) — caller must xmlFree(), or NULL + */ + +gchar *xml_get_folder_color(xmlNodePtr node) +{ + return (gchar *)xmlGetProp(node, (const xmlChar *)"color"); +} + /****************************************************************************** * Name * xml_add_bookmark_to_parent diff --git a/src/main/xml.h b/src/main/xml.h index eb3d84ff4..143cb6778 100644 --- a/src/main/xml.h +++ b/src/main/xml.h @@ -32,6 +32,10 @@ void xml_add_new_section_to_settings_doc(char *section); void xml_new_bookmark_file(void); xmlNodePtr xml_add_folder_to_parent(xmlNodePtr parent, gchar *caption); +xmlNodePtr xml_add_folder_to_parent_colored(xmlNodePtr parent, + gchar *caption, + const gchar *color); +gchar *xml_get_folder_color(xmlNodePtr node); void xml_add_bookmark_to_parent(xmlNodePtr parent, gchar *caption, gchar *key, gchar *module, const gchar *mod_desc); diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 0079ef804..045a106a4 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -21,6 +21,7 @@ if (NOT GTK2) # Gtk3 only stuff install (FILES bookmarks.gtkbuilder + folder.gtkbuilder editor_link_dialog.gtkbuilder export-dialog.gtkbuilder markverse.gtkbuilder @@ -40,6 +41,7 @@ else (NOT GTK2) # Gtk2 only stuff install (FILES bookmarks.glade + folder.glade editor_link_dialog.glade export-dialog.glade markverse.glade diff --git a/ui/folder.gtkbuilder b/ui/folder.gtkbuilder new file mode 100644 index 000000000..15ab50b7e --- /dev/null +++ b/ui/folder.gtkbuilder @@ -0,0 +1,152 @@ + + + + + False + False + Folder + 320 + 150 + dialog + + + True + False + vertical + 8 + 10 + + + True + False + end + + + gtk-cancel + True + True + True + + + False + False + 0 + + + + + gtk-ok + True + True + True + + + False + False + 1 + + + + + False + True + end + 0 + + + + + True + False + 8 + + + True + False + Name: + 0 + + + False + False + 0 + + + + + True + True + True + + + True + True + 1 + + + + + False + True + 1 + + + + + True + False + 8 + + + True + False + Tag color: + 0 + + + False + False + 0 + + + + + True + True + Choose a highlight color for this tag group + False + + + False + False + 1 + + + + + No color + True + True + Remove tag color from this folder + + + False + False + 2 + + + + + False + True + 2 + + + + + + folder_cancel + folder_ok + + + diff --git a/win32/xc-xiphos-win.sh b/win32/xc-xiphos-win.sh index 53cb6c5c8..f27a02993 100755 --- a/win32/xc-xiphos-win.sh +++ b/win32/xc-xiphos-win.sh @@ -81,7 +81,8 @@ trap 'exit 1' ERR function do_build { bits="${1}" mkdir -p win${bits} && cd win${bits} - cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/mingw/toolchain-mingw${bits}.cmake -DGTK2=ON -DCONSOLE=OFF "${XIPHOS_PATH}" + if [ "${bits}" = "32" ]; then GTK_OPT="-DGTK2=ON"; else GTK_OPT=""; fi + cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/mingw/toolchain-mingw${bits}.cmake ${GTK_OPT} -DGTKTVEDITOR=ON -DCONSOLE=OFF "${XIPHOS_PATH}" make VERBOSE=1 make mhelp-epub-{C,fa,fr,it} package cd ..