From df8f1d512c60a96f9041f9663b3fdc2db51cba33 Mon Sep 17 00:00:00 2001 From: "Roberto C. Sanchez" Date: Tue, 21 Oct 2014 22:48:35 -0400 Subject: Imported Upstream version 2.8.1 --- .../bookshelfmodel/btbookshelffiltermodel.cpp | 23 +- .../bookshelfmodel/btbookshelffiltermodel.h | 2 +- src/backend/bookshelfmodel/btbookshelfmodel.cpp | 125 +-- src/backend/bookshelfmodel/btbookshelfmodel.h | 110 ++- .../bookshelfmodel/btbookshelftreemodel.cpp | 79 +- src/backend/bookshelfmodel/btbookshelftreemodel.h | 64 +- src/backend/bookshelfmodel/categoryitem.cpp | 6 +- src/backend/bookshelfmodel/categoryitem.h | 2 +- src/backend/bookshelfmodel/indexingitem.cpp | 2 +- src/backend/bookshelfmodel/indexingitem.h | 2 +- src/backend/bookshelfmodel/item.cpp | 2 +- src/backend/bookshelfmodel/item.h | 2 +- src/backend/bookshelfmodel/languageitem.cpp | 4 +- src/backend/bookshelfmodel/languageitem.h | 2 +- src/backend/bookshelfmodel/moduleitem.cpp | 2 +- src/backend/bookshelfmodel/moduleitem.h | 8 +- src/backend/btinstallbackend.cpp | 301 +++++++ src/backend/btinstallbackend.h | 71 ++ src/backend/btmoduletreeitem.cpp | 7 +- src/backend/btmoduletreeitem.h | 42 +- src/backend/config/cbtconfig.cpp | 50 +- src/backend/config/cbtconfig.h | 19 +- src/backend/cswordmodulesearch.cpp | 101 +-- src/backend/cswordmodulesearch.h | 99 ++- src/backend/drivers/cswordbiblemoduleinfo.cpp | 190 ++--- src/backend/drivers/cswordbiblemoduleinfo.h | 140 ++- src/backend/drivers/cswordbookmoduleinfo.cpp | 37 +- src/backend/drivers/cswordbookmoduleinfo.h | 64 +- src/backend/drivers/cswordcommentarymoduleinfo.cpp | 27 +- src/backend/drivers/cswordcommentarymoduleinfo.h | 46 +- src/backend/drivers/cswordlexiconmoduleinfo.cpp | 92 +- src/backend/drivers/cswordlexiconmoduleinfo.h | 73 +- src/backend/drivers/cswordmoduleinfo.cpp | 422 ++++++---- src/backend/drivers/cswordmoduleinfo.h | 275 +++--- src/backend/filters/bt_gbfhtml.cpp | 292 ------- src/backend/filters/bt_gbfhtml.h | 50 -- src/backend/filters/bt_osishtml.cpp | 593 ------------- src/backend/filters/bt_osishtml.h | 70 -- src/backend/filters/bt_plainhtml.cpp | 69 -- src/backend/filters/bt_plainhtml.h | 34 - src/backend/filters/bt_teihtml.cpp | 143 ---- src/backend/filters/bt_teihtml.h | 34 - src/backend/filters/bt_thmlhtml.cpp | 385 --------- src/backend/filters/bt_thmlhtml.h | 54 -- src/backend/filters/bt_thmlplain.cpp | 220 ----- src/backend/filters/bt_thmlplain.h | 30 - src/backend/filters/gbftohtml.cpp | 289 +++++++ src/backend/filters/gbftohtml.h | 61 ++ src/backend/filters/osismorphsegmentation.cpp | 4 +- src/backend/filters/osismorphsegmentation.h | 2 +- src/backend/filters/osistohtml.cpp | 595 +++++++++++++ src/backend/filters/osistohtml.h | 75 ++ src/backend/filters/plaintohtml.cpp | 69 ++ src/backend/filters/plaintohtml.h | 40 + src/backend/filters/teitohtml.cpp | 150 ++++ src/backend/filters/teitohtml.h | 37 + src/backend/filters/thmltohtml.cpp | 392 +++++++++ src/backend/filters/thmltohtml.h | 62 ++ src/backend/filters/thmltoplain.cpp | 222 +++++ src/backend/filters/thmltoplain.h | 33 + src/backend/keys/cswordkey.cpp | 74 +- src/backend/keys/cswordkey.h | 91 +- src/backend/keys/cswordldkey.cpp | 40 +- src/backend/keys/cswordldkey.h | 36 +- src/backend/keys/cswordtreekey.cpp | 41 +- src/backend/keys/cswordtreekey.h | 35 +- src/backend/keys/cswordversekey.cpp | 112 ++- src/backend/keys/cswordversekey.h | 55 +- src/backend/managers/btstringmgr.cpp | 2 +- src/backend/managers/btstringmgr.h | 2 +- src/backend/managers/cdisplaytemplatemgr.cpp | 69 +- src/backend/managers/cdisplaytemplatemgr.h | 119 +-- src/backend/managers/clanguagemgr.cpp | 28 +- src/backend/managers/clanguagemgr.h | 57 +- src/backend/managers/cswordbackend.cpp | 197 ++--- src/backend/managers/cswordbackend.h | 173 ++-- src/backend/managers/referencemanager.cpp | 46 +- src/backend/managers/referencemanager.h | 17 +- src/backend/rendering/cbookdisplay.cpp | 32 +- src/backend/rendering/cbookdisplay.h | 39 +- src/backend/rendering/cchapterdisplay.cpp | 21 +- src/backend/rendering/cchapterdisplay.h | 29 +- src/backend/rendering/cdisplayrendering.cpp | 24 +- src/backend/rendering/cdisplayrendering.h | 10 +- src/backend/rendering/centrydisplay.cpp | 16 +- src/backend/rendering/centrydisplay.h | 27 +- src/backend/rendering/chtmlexportrendering.cpp | 85 +- src/backend/rendering/chtmlexportrendering.h | 18 +- .../rendering/cplaintextexportrendering.cpp | 32 +- src/backend/rendering/cplaintextexportrendering.h | 10 +- src/backend/rendering/ctextrendering.cpp | 90 +- src/backend/rendering/ctextrendering.h | 49 +- src/bibletime.cpp | 204 +++-- src/bibletime.h | 277 ++++-- src/bibletime_dbus.cpp | 21 +- src/bibletime_dbus_adaptor.cpp | 2 +- src/bibletime_dbus_adaptor.h | 12 +- src/bibletime_init.cpp | 800 ++++++++++++------ src/bibletime_slots.cpp | 276 +++--- src/bibletimeapp.cpp | 32 +- src/bibletimeapp.h | 21 +- src/btglobal.h | 53 ++ src/frontend/bookmarks/btbookmarkfolder.cpp | 140 +++ src/frontend/bookmarks/btbookmarkfolder.h | 50 ++ src/frontend/bookmarks/btbookmarkitem.cpp | 149 ++++ src/frontend/bookmarks/btbookmarkitem.h | 76 ++ src/frontend/bookmarks/btbookmarkitembase.cpp | 21 + src/frontend/bookmarks/btbookmarkitembase.h | 62 ++ src/frontend/bookmarks/btbookmarkloader.cpp | 177 ++++ src/frontend/bookmarks/btbookmarkloader.h | 46 + src/frontend/bookmarks/bteditbookmarkdialog.cpp | 78 ++ src/frontend/bookmarks/bteditbookmarkdialog.h | 62 ++ src/frontend/bookmarks/cbookmarkindex.cpp | 937 +++++++++++++++++++++ src/frontend/bookmarks/cbookmarkindex.h | 214 +++++ src/frontend/bookshelfmanager/btconfigdialog.cpp | 48 +- src/frontend/bookshelfmanager/btconfigdialog.h | 33 +- src/frontend/bookshelfmanager/btinstallmgr.cpp | 9 +- src/frontend/bookshelfmanager/btinstallmgr.h | 41 +- .../bookshelfmanager/btmodulemanagerdialog.cpp | 12 +- .../bookshelfmanager/btmodulemanagerdialog.h | 4 +- .../cswordsetupinstallsourcesdialog.cpp | 15 +- .../cswordsetupinstallsourcesdialog.h | 2 +- .../bookshelfmanager/indexpage/btindexpage.cpp | 59 +- .../bookshelfmanager/indexpage/btindexpage.h | 27 +- .../installpage/btinstallmodulechooserdialog.cpp | 164 ++-- .../installpage/btinstallmodulechooserdialog.h | 50 +- .../btinstallmodulechooserdialogmodel.cpp | 136 +++ .../btinstallmodulechooserdialogmodel.h | 44 + .../bookshelfmanager/installpage/btinstallpage.cpp | 423 ++++++++-- .../bookshelfmanager/installpage/btinstallpage.h | 65 +- .../installpage/btinstallpagemodel.cpp | 87 ++ .../installpage/btinstallpagemodel.h | 33 + .../installpage/btinstallpageworkswidget.cpp | 140 +++ .../installpage/btinstallpageworkswidget.h | 59 ++ .../installpage/btinstallpathdialog.cpp | 21 +- .../installpage/btinstallpathdialog.h | 2 +- .../installpage/btinstallprogressdialog.cpp | 117 ++- .../installpage/btinstallprogressdialog.h | 9 +- .../installpage/btinstallthread.cpp | 28 +- .../bookshelfmanager/installpage/btinstallthread.h | 12 +- .../installpage/btrefreshprogressdialog.cpp | 62 ++ .../installpage/btrefreshprogressdialog.h | 38 + .../bookshelfmanager/installpage/btsourcearea.cpp | 282 ------- .../bookshelfmanager/installpage/btsourcearea.h | 96 --- .../installpage/btsourcewidget.cpp | 399 --------- .../bookshelfmanager/installpage/btsourcewidget.h | 86 -- src/frontend/bookshelfmanager/instbackend.cpp | 312 ------- src/frontend/bookshelfmanager/instbackend.h | 74 -- .../bookshelfmanager/removepage/btremovepage.cpp | 143 +++- .../bookshelfmanager/removepage/btremovepage.h | 33 +- .../removepage/btremovepagetreemodel.cpp | 7 +- .../removepage/btremovepagetreemodel.h | 4 +- src/frontend/btaboutdialog.cpp | 274 ++++++ src/frontend/btaboutdialog.h | 49 ++ src/frontend/btaboutmoduledialog.cpp | 38 +- src/frontend/btaboutmoduledialog.h | 18 +- src/frontend/btbookshelfdockwidget.cpp | 323 +++---- src/frontend/btbookshelfdockwidget.h | 67 +- src/frontend/btbookshelfgroupingmenu.cpp | 113 +++ src/frontend/btbookshelfgroupingmenu.h | 53 ++ src/frontend/btbookshelfview.cpp | 108 +++ src/frontend/btbookshelfview.h | 43 + src/frontend/btbookshelfwidget.cpp | 203 +++++ src/frontend/btbookshelfwidget.h | 116 +++ src/frontend/btmenuview.cpp | 227 +++-- src/frontend/btmenuview.h | 107 ++- src/frontend/btmodulechooserdialog.cpp | 65 ++ src/frontend/btmodulechooserdialog.h | 48 ++ src/frontend/btmoduleindexdialog.cpp | 103 +++ src/frontend/btmoduleindexdialog.h | 65 ++ src/frontend/btopenworkaction.cpp | 111 +++ src/frontend/btopenworkaction.h | 82 ++ src/frontend/cdragdrop.cpp | 11 +- src/frontend/cdragdrop.h | 34 +- src/frontend/cexportmanager.cpp | 165 ++-- src/frontend/cexportmanager.h | 76 +- src/frontend/cinfodisplay.cpp | 82 +- src/frontend/cinfodisplay.h | 4 +- src/frontend/cinputdialog.cpp | 88 -- src/frontend/cinputdialog.h | 41 - src/frontend/cmdiarea.cpp | 91 +- src/frontend/cmdiarea.h | 16 +- src/frontend/cmodulechooserdialog.cpp | 147 ---- src/frontend/cmodulechooserdialog.h | 107 --- src/frontend/cmoduleindexdialog.cpp | 99 --- src/frontend/cmoduleindexdialog.h | 56 -- src/frontend/cprinter.cpp | 25 +- src/frontend/cprinter.h | 11 +- src/frontend/crossrefrendering.cpp | 18 +- src/frontend/crossrefrendering.h | 10 +- src/frontend/display/btcolorwidget.cpp | 2 +- src/frontend/display/btcolorwidget.h | 5 +- src/frontend/display/btfontsizewidget.cpp | 6 +- src/frontend/display/btfontsizewidget.h | 6 +- src/frontend/display/bthtml.js | 2 +- src/frontend/display/bthtmlfindtext.cpp | 6 +- src/frontend/display/bthtmlfindtext.h | 3 +- src/frontend/display/bthtmlfindtext.ui | 2 +- src/frontend/display/bthtmljsobject.cpp | 26 +- src/frontend/display/bthtmljsobject.h | 7 +- src/frontend/display/bthtmlreaddisplay.cpp | 102 ++- src/frontend/display/bthtmlreaddisplay.h | 7 +- src/frontend/display/cdisplay.cpp | 13 +- src/frontend/display/cdisplay.h | 22 +- src/frontend/display/chtmlwritedisplay.cpp | 176 ++-- src/frontend/display/chtmlwritedisplay.h | 16 +- src/frontend/display/cplainwritedisplay.cpp | 25 +- src/frontend/display/cplainwritedisplay.h | 20 +- src/frontend/display/creaddisplay.cpp | 12 +- src/frontend/display/creaddisplay.h | 8 +- src/frontend/display/cwritedisplay.cpp | 2 +- src/frontend/display/cwritedisplay.h | 2 +- src/frontend/displaywindow/btactioncollection.cpp | 20 +- src/frontend/displaywindow/btactioncollection.h | 2 +- .../displaywindow/btdisplaysettingsbutton.cpp | 14 +- .../displaywindow/btdisplaysettingsbutton.h | 22 +- src/frontend/displaywindow/btmodulechooserbar.cpp | 39 +- src/frontend/displaywindow/btmodulechooserbar.h | 21 +- .../displaywindow/btmodulechooserbutton.cpp | 3 +- src/frontend/displaywindow/btmodulechooserbutton.h | 2 +- src/frontend/displaywindow/bttextwindowheader.cpp | 19 +- src/frontend/displaywindow/bttextwindowheader.h | 19 +- .../displaywindow/bttextwindowheaderwidget.cpp | 3 +- .../displaywindow/bttextwindowheaderwidget.h | 2 +- .../displaywindow/bttoolbarpopupaction.cpp | 15 +- src/frontend/displaywindow/bttoolbarpopupaction.h | 5 +- src/frontend/displaywindow/btwindowmodulechooser.h | 12 +- src/frontend/displaywindow/cbiblereadwindow.cpp | 47 +- src/frontend/displaywindow/cbiblereadwindow.h | 4 +- src/frontend/displaywindow/cbookreadwindow.cpp | 59 +- src/frontend/displaywindow/cbookreadwindow.h | 4 +- .../displaywindow/ccommentaryreadwindow.cpp | 35 +- src/frontend/displaywindow/ccommentaryreadwindow.h | 4 +- src/frontend/displaywindow/cdisplaywindow.cpp | 161 ++-- src/frontend/displaywindow/cdisplaywindow.h | 120 ++- .../displaywindow/cdisplaywindowfactory.cpp | 33 +- src/frontend/displaywindow/cdisplaywindowfactory.h | 6 +- src/frontend/displaywindow/chtmlwritewindow.cpp | 105 +-- src/frontend/displaywindow/chtmlwritewindow.h | 35 +- src/frontend/displaywindow/clexiconreadwindow.cpp | 68 +- src/frontend/displaywindow/clexiconreadwindow.h | 27 +- src/frontend/displaywindow/cplainwritewindow.cpp | 172 ++-- src/frontend/displaywindow/cplainwritewindow.h | 28 +- src/frontend/displaywindow/creadwindow.cpp | 15 +- src/frontend/displaywindow/creadwindow.h | 18 +- src/frontend/displaywindow/cwritewindow.cpp | 10 +- src/frontend/displaywindow/cwritewindow.h | 33 +- src/frontend/htmldialogs/btaboutdialog.cpp | 249 ------ src/frontend/htmldialogs/btaboutdialog.h | 29 - src/frontend/htmldialogs/bttabhtmldialog.cpp | 125 --- src/frontend/htmldialogs/bttabhtmldialog.h | 87 -- src/frontend/keychooser/bthistory.cpp | 4 +- src/frontend/keychooser/bthistory.h | 2 +- src/frontend/keychooser/cbookkeychooser.cpp | 34 +- src/frontend/keychooser/cbookkeychooser.h | 16 +- src/frontend/keychooser/cbooktreechooser.cpp | 34 +- src/frontend/keychooser/cbooktreechooser.h | 35 +- src/frontend/keychooser/ckeychooser.cpp | 52 +- src/frontend/keychooser/ckeychooser.h | 57 +- src/frontend/keychooser/ckeychooserwidget.cpp | 12 +- src/frontend/keychooser/ckeychooserwidget.h | 23 +- src/frontend/keychooser/clexiconkeychooser.cpp | 67 +- src/frontend/keychooser/clexiconkeychooser.h | 34 +- src/frontend/keychooser/cscrollbutton.cpp | 2 +- src/frontend/keychooser/cscrollbutton.h | 8 +- src/frontend/keychooser/cscrollerwidgetset.cpp | 2 +- src/frontend/keychooser/cscrollerwidgetset.h | 7 +- .../versekeychooser/btbiblekeywidget.cpp | 293 +++++++ .../keychooser/versekeychooser/btbiblekeywidget.h | 94 +++ .../versekeychooser/btdropdownchooserbutton.cpp | 14 +- .../versekeychooser/btdropdownchooserbutton.h | 16 +- .../keychooser/versekeychooser/btversekeymenu.cpp | 2 +- .../keychooser/versekeychooser/btversekeymenu.h | 2 +- .../versekeychooser/cbiblekeychooser.cpp | 51 +- .../keychooser/versekeychooser/cbiblekeychooser.h | 33 +- .../versekeychooser/ckeyreferencewidget.cpp | 297 ------- .../versekeychooser/ckeyreferencewidget.h | 92 -- .../mainindex/bookmarks/btbookmarkfolder.cpp | 140 --- .../mainindex/bookmarks/btbookmarkfolder.h | 50 -- .../mainindex/bookmarks/btbookmarkitem.cpp | 150 ---- src/frontend/mainindex/bookmarks/btbookmarkitem.h | 66 -- .../mainindex/bookmarks/btbookmarkitembase.cpp | 39 - .../mainindex/bookmarks/btbookmarkitembase.h | 61 -- .../mainindex/bookmarks/btbookmarkloader.cpp | 172 ---- .../mainindex/bookmarks/btbookmarkloader.h | 46 - .../mainindex/bookmarks/cbookmarkindex.cpp | 895 -------------------- src/frontend/mainindex/bookmarks/cbookmarkindex.h | 207 ----- src/frontend/mainindex/btbookshelfview.cpp | 108 --- src/frontend/mainindex/btbookshelfview.h | 43 - src/frontend/profile/cprofile.cpp | 2 +- src/frontend/profile/cprofile.h | 2 +- src/frontend/profile/cprofilemgr.cpp | 4 +- src/frontend/profile/cprofilemgr.h | 4 +- src/frontend/profile/cprofilewindow.cpp | 2 +- src/frontend/profile/cprofilewindow.h | 2 +- .../analysis/csearchanalysisdialog.cpp | 14 +- .../searchdialog/analysis/csearchanalysisdialog.h | 13 +- .../searchdialog/analysis/csearchanalysisitem.cpp | 36 +- .../searchdialog/analysis/csearchanalysisitem.h | 13 +- .../analysis/csearchanalysislegenditem.cpp | 13 +- .../analysis/csearchanalysislegenditem.h | 19 +- .../searchdialog/analysis/csearchanalysisscene.cpp | 80 +- .../searchdialog/analysis/csearchanalysisscene.h | 22 +- .../searchdialog/analysis/csearchanalysisview.cpp | 2 +- .../searchdialog/analysis/csearchanalysisview.h | 12 +- .../searchdialog/btsearchmodulechooserdialog.cpp | 58 ++ .../searchdialog/btsearchmodulechooserdialog.h | 45 + src/frontend/searchdialog/btsearchoptionsarea.cpp | 188 ++--- src/frontend/searchdialog/btsearchoptionsarea.h | 15 +- src/frontend/searchdialog/btsearchresultarea.cpp | 245 +++--- src/frontend/searchdialog/btsearchresultarea.h | 145 ++-- .../searchdialog/btsearchsyntaxhelpdialog.cpp | 229 +++++ .../searchdialog/btsearchsyntaxhelpdialog.h | 40 + src/frontend/searchdialog/chistorycombobox.cpp | 2 +- src/frontend/searchdialog/chistorycombobox.h | 2 +- src/frontend/searchdialog/cmoduleresultview.cpp | 130 +-- src/frontend/searchdialog/cmoduleresultview.h | 22 +- src/frontend/searchdialog/crangechooserdialog.cpp | 2 +- src/frontend/searchdialog/crangechooserdialog.h | 2 +- src/frontend/searchdialog/csearchdialog.cpp | 135 ++- src/frontend/searchdialog/csearchdialog.h | 62 +- .../searchdialog/csearchmodulechooserdialog.cpp | 56 -- .../searchdialog/csearchmodulechooserdialog.h | 38 - src/frontend/searchdialog/csearchresultview.cpp | 61 +- src/frontend/searchdialog/csearchresultview.h | 27 +- src/frontend/settingsdialogs/btfontsettings.cpp | 164 ++++ src/frontend/settingsdialogs/btfontsettings.h | 62 ++ .../settingsdialogs/btlanguagesettings.cpp | 145 ++++ src/frontend/settingsdialogs/btlanguagesettings.h | 60 ++ src/frontend/settingsdialogs/btshortcutsdialog.cpp | 3 +- src/frontend/settingsdialogs/btshortcutsdialog.h | 2 +- src/frontend/settingsdialogs/btshortcutseditor.cpp | 6 +- src/frontend/settingsdialogs/btshortcutseditor.h | 4 +- .../settingsdialogs/cacceleratorsettings.cpp | 41 +- .../settingsdialogs/cacceleratorsettings.h | 16 +- .../settingsdialogs/cconfigurationdialog.cpp | 16 +- .../settingsdialogs/cconfigurationdialog.h | 8 +- src/frontend/settingsdialogs/cdisplaysettings.cpp | 37 +- src/frontend/settingsdialogs/cdisplaysettings.h | 13 +- src/frontend/settingsdialogs/cfontchooser.cpp | 2 +- src/frontend/settingsdialogs/cfontchooser.h | 2 +- src/frontend/settingsdialogs/clanguagesettings.cpp | 266 ------ src/frontend/settingsdialogs/clanguagesettings.h | 58 -- src/frontend/settingsdialogs/clistwidget.cpp | 2 +- src/frontend/settingsdialogs/clistwidget.h | 2 +- src/frontend/settingsdialogs/cswordsettings.cpp | 50 +- src/frontend/settingsdialogs/cswordsettings.h | 17 +- src/frontend/tips/bttipdialog.cpp | 193 +++++ src/frontend/tips/bttipdialog.h | 62 ++ src/main.cpp | 187 +++- src/tests/backend/config/cbtconfig_test.cpp | 34 - src/tests/bibletime_test.cpp | 20 - src/tests/bibletime_test.h | 28 - src/util/btsignal.h | 40 + src/util/cpointers.cpp | 53 -- src/util/cpointers.h | 115 --- src/util/cresmgr.cpp | 59 +- src/util/cresmgr.h | 24 +- src/util/dialogutil.cpp | 3 +- src/util/dialogutil.h | 2 +- src/util/directory.cpp | 122 ++- src/util/directory.h | 58 +- src/util/exceptions.h | 2 +- src/util/macros.h | 61 ++ src/util/migrationutil.cpp | 92 -- src/util/migrationutil.h | 38 - src/util/tool.cpp | 185 ++-- src/util/tool.h | 51 +- 368 files changed, 15011 insertions(+), 12892 deletions(-) create mode 100644 src/backend/btinstallbackend.cpp create mode 100644 src/backend/btinstallbackend.h delete mode 100644 src/backend/filters/bt_gbfhtml.cpp delete mode 100644 src/backend/filters/bt_gbfhtml.h delete mode 100644 src/backend/filters/bt_osishtml.cpp delete mode 100644 src/backend/filters/bt_osishtml.h delete mode 100644 src/backend/filters/bt_plainhtml.cpp delete mode 100644 src/backend/filters/bt_plainhtml.h delete mode 100644 src/backend/filters/bt_teihtml.cpp delete mode 100644 src/backend/filters/bt_teihtml.h delete mode 100644 src/backend/filters/bt_thmlhtml.cpp delete mode 100644 src/backend/filters/bt_thmlhtml.h delete mode 100644 src/backend/filters/bt_thmlplain.cpp delete mode 100644 src/backend/filters/bt_thmlplain.h create mode 100644 src/backend/filters/gbftohtml.cpp create mode 100644 src/backend/filters/gbftohtml.h create mode 100644 src/backend/filters/osistohtml.cpp create mode 100644 src/backend/filters/osistohtml.h create mode 100644 src/backend/filters/plaintohtml.cpp create mode 100644 src/backend/filters/plaintohtml.h create mode 100644 src/backend/filters/teitohtml.cpp create mode 100644 src/backend/filters/teitohtml.h create mode 100644 src/backend/filters/thmltohtml.cpp create mode 100644 src/backend/filters/thmltohtml.h create mode 100644 src/backend/filters/thmltoplain.cpp create mode 100644 src/backend/filters/thmltoplain.h create mode 100644 src/btglobal.h create mode 100644 src/frontend/bookmarks/btbookmarkfolder.cpp create mode 100644 src/frontend/bookmarks/btbookmarkfolder.h create mode 100644 src/frontend/bookmarks/btbookmarkitem.cpp create mode 100644 src/frontend/bookmarks/btbookmarkitem.h create mode 100644 src/frontend/bookmarks/btbookmarkitembase.cpp create mode 100644 src/frontend/bookmarks/btbookmarkitembase.h create mode 100644 src/frontend/bookmarks/btbookmarkloader.cpp create mode 100644 src/frontend/bookmarks/btbookmarkloader.h create mode 100644 src/frontend/bookmarks/bteditbookmarkdialog.cpp create mode 100644 src/frontend/bookmarks/bteditbookmarkdialog.h create mode 100644 src/frontend/bookmarks/cbookmarkindex.cpp create mode 100644 src/frontend/bookmarks/cbookmarkindex.h create mode 100644 src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp create mode 100644 src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h create mode 100644 src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp create mode 100644 src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h create mode 100644 src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp create mode 100644 src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h create mode 100644 src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp create mode 100644 src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h delete mode 100644 src/frontend/bookshelfmanager/installpage/btsourcearea.cpp delete mode 100644 src/frontend/bookshelfmanager/installpage/btsourcearea.h delete mode 100644 src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp delete mode 100644 src/frontend/bookshelfmanager/installpage/btsourcewidget.h delete mode 100644 src/frontend/bookshelfmanager/instbackend.cpp delete mode 100644 src/frontend/bookshelfmanager/instbackend.h create mode 100644 src/frontend/btaboutdialog.cpp create mode 100644 src/frontend/btaboutdialog.h create mode 100644 src/frontend/btbookshelfgroupingmenu.cpp create mode 100644 src/frontend/btbookshelfgroupingmenu.h create mode 100644 src/frontend/btbookshelfview.cpp create mode 100644 src/frontend/btbookshelfview.h create mode 100644 src/frontend/btbookshelfwidget.cpp create mode 100644 src/frontend/btbookshelfwidget.h create mode 100644 src/frontend/btmodulechooserdialog.cpp create mode 100644 src/frontend/btmodulechooserdialog.h create mode 100644 src/frontend/btmoduleindexdialog.cpp create mode 100644 src/frontend/btmoduleindexdialog.h create mode 100644 src/frontend/btopenworkaction.cpp create mode 100644 src/frontend/btopenworkaction.h delete mode 100644 src/frontend/cinputdialog.cpp delete mode 100644 src/frontend/cinputdialog.h delete mode 100644 src/frontend/cmodulechooserdialog.cpp delete mode 100644 src/frontend/cmodulechooserdialog.h delete mode 100644 src/frontend/cmoduleindexdialog.cpp delete mode 100644 src/frontend/cmoduleindexdialog.h delete mode 100644 src/frontend/htmldialogs/btaboutdialog.cpp delete mode 100644 src/frontend/htmldialogs/btaboutdialog.h delete mode 100644 src/frontend/htmldialogs/bttabhtmldialog.cpp delete mode 100644 src/frontend/htmldialogs/bttabhtmldialog.h create mode 100644 src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp create mode 100644 src/frontend/keychooser/versekeychooser/btbiblekeywidget.h delete mode 100644 src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp delete mode 100644 src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkfolder.cpp delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkfolder.h delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkitem.cpp delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkitem.h delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkitembase.cpp delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkitembase.h delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkloader.cpp delete mode 100644 src/frontend/mainindex/bookmarks/btbookmarkloader.h delete mode 100644 src/frontend/mainindex/bookmarks/cbookmarkindex.cpp delete mode 100644 src/frontend/mainindex/bookmarks/cbookmarkindex.h delete mode 100644 src/frontend/mainindex/btbookshelfview.cpp delete mode 100644 src/frontend/mainindex/btbookshelfview.h create mode 100644 src/frontend/searchdialog/btsearchmodulechooserdialog.cpp create mode 100644 src/frontend/searchdialog/btsearchmodulechooserdialog.h create mode 100644 src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp create mode 100644 src/frontend/searchdialog/btsearchsyntaxhelpdialog.h delete mode 100644 src/frontend/searchdialog/csearchmodulechooserdialog.cpp delete mode 100644 src/frontend/searchdialog/csearchmodulechooserdialog.h create mode 100644 src/frontend/settingsdialogs/btfontsettings.cpp create mode 100644 src/frontend/settingsdialogs/btfontsettings.h create mode 100644 src/frontend/settingsdialogs/btlanguagesettings.cpp create mode 100644 src/frontend/settingsdialogs/btlanguagesettings.h delete mode 100644 src/frontend/settingsdialogs/clanguagesettings.cpp delete mode 100644 src/frontend/settingsdialogs/clanguagesettings.h create mode 100644 src/frontend/tips/bttipdialog.cpp create mode 100644 src/frontend/tips/bttipdialog.h delete mode 100644 src/tests/backend/config/cbtconfig_test.cpp delete mode 100644 src/tests/bibletime_test.cpp delete mode 100644 src/tests/bibletime_test.h create mode 100644 src/util/btsignal.h delete mode 100644 src/util/cpointers.cpp delete mode 100644 src/util/cpointers.h create mode 100644 src/util/macros.h delete mode 100644 src/util/migrationutil.cpp delete mode 100644 src/util/migrationutil.h (limited to 'src') diff --git a/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp b/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp index b896556..182d337 100644 --- a/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelffiltermodel.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -25,7 +25,7 @@ BtBookshelfFilterModel::BtBookshelfFilterModel(QObject *parent) m_categoryFilterRole(BtBookshelfModel::ModuleCategoryRole), m_categoryFilterColumn(0) { - // Intentionally empty + setDynamicSortFilter(true); } BtBookshelfFilterModel::~BtBookshelfFilterModel() { @@ -125,16 +125,13 @@ bool BtBookshelfFilterModel::filterAcceptsRow(int row, return true; } -bool BtBookshelfFilterModel::nameFilterAcceptsRow(int row, const QModelIndex &p) - const -{ - if (!m_enabled) return true; +bool BtBookshelfFilterModel::nameFilterAcceptsRow(int row, const QModelIndex &parent) const { if (m_nameFilter.isEmpty()) return true; const QAbstractItemModel *m(sourceModel()); Q_ASSERT(m != 0); - QModelIndex itemIndex(m->index(row, m_nameFilterColumn, p)); + QModelIndex itemIndex(m->index(row, m_nameFilterColumn, parent)); int numChildren(m->rowCount(itemIndex)); if (numChildren == 0) { QVariant data(m->data(itemIndex, m_nameFilterRole)); @@ -148,14 +145,14 @@ bool BtBookshelfFilterModel::nameFilterAcceptsRow(int row, const QModelIndex &p) } } -bool BtBookshelfFilterModel::hiddenFilterAcceptsRow(int row, - const QModelIndex &parent) const +bool BtBookshelfFilterModel::hiddenFilterAcceptsRow(int row, const QModelIndex &parent) const { if (m_showHidden && m_showShown) return true; typedef Qt::CheckState CS; QAbstractItemModel *m(sourceModel()); + Q_ASSERT(m != 0); QModelIndex itemIndex(m->index(row, m_hiddenFilterColumn, parent)); int numChildren(m->rowCount(itemIndex)); @@ -181,17 +178,13 @@ bool BtBookshelfFilterModel::categoryFilterAcceptsRow(int row, if (m_categoryFilter == CSwordModuleInfo::AllCategories) return true; QAbstractItemModel *m(sourceModel()); + Q_ASSERT(m != 0); QModelIndex itemIndex(m->index(row, m_categoryFilterColumn, parent)); int numChildren(m->rowCount(itemIndex)); if (numChildren == 0) { int cat = m->data(itemIndex, m_categoryFilterRole).toInt(); - if (m_categoryFilter.testFlag((CSwordModuleInfo::Category) cat)) { - return true; - } - else { - return false; - } + return m_categoryFilter.testFlag((CSwordModuleInfo::Category) cat); } else { for (int i(0); i < numChildren; i++) { diff --git a/src/backend/bookshelfmodel/btbookshelffiltermodel.h b/src/backend/bookshelfmodel/btbookshelffiltermodel.h index e440c69..55322ed 100644 --- a/src/backend/bookshelfmodel/btbookshelffiltermodel.h +++ b/src/backend/bookshelfmodel/btbookshelffiltermodel.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.cpp b/src/backend/bookshelfmodel/btbookshelfmodel.cpp index ccbb5a5..c6aab1b 100644 --- a/src/backend/bookshelfmodel/btbookshelfmodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelfmodel.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -12,9 +12,9 @@ #include "backend/bookshelfmodel/btbookshelfmodel.h" +#include #include -#include "util/cresmgr.h" -#include "util/directory.h" +#include "util/macros.h" BtBookshelfModel::BtBookshelfModel(QObject *parent) @@ -37,7 +37,7 @@ QVariant BtBookshelfModel::data(CSwordModuleInfo *module, int role) const { case ModuleNameRole: // Qt::DisplayRole return module->name(); case ModuleIconRole: // Qt::DecorationRole - return moduleIcon(module); + return CSwordModuleInfo::moduleIcon(module); case ModulePointerRole: return qVariantFromValue((void*) module); case ModuleCategoryRole: @@ -52,6 +52,8 @@ QVariant BtBookshelfModel::data(CSwordModuleInfo *module, int role) const { return module->hasIndex(); case ModuleIndexSizeRole: return (qulonglong) module->indexSize(); + case ModuleDescriptionRole: + return module->config(CSwordModuleInfo::Description); default: return QVariant(); } @@ -93,107 +95,6 @@ bool BtBookshelfModel::setData(const QModelIndex &index, const QVariant &value, return false; } -QIcon BtBookshelfModel::moduleIcon(const CSwordModuleInfo *m) { - namespace DU = util::directory; - - /// \todo Make CSwordModuleInfo::isLocked() const and remove const_cast: - CSwordModuleInfo *module(const_cast(m)); - - CSwordModuleInfo::Category cat(module->category()); - switch (cat) { - case CSwordModuleInfo::Bibles: - if (module->isLocked()) { - return DU::getIcon(CResMgr::modules::bible::icon_locked); - } - else { - return DU::getIcon(CResMgr::modules::bible::icon_unlocked); - } - case CSwordModuleInfo::Commentaries: - if (module->isLocked()) { - return DU::getIcon(CResMgr::modules::commentary::icon_locked); - } - else { - return DU::getIcon(CResMgr::modules::commentary::icon_unlocked); - } - case CSwordModuleInfo::Lexicons: - if (module->isLocked()) { - return DU::getIcon(CResMgr::modules::lexicon::icon_locked); - } - else { - return DU::getIcon(CResMgr::modules::lexicon::icon_unlocked); - } - case CSwordModuleInfo::Books: - if (module->isLocked()) { - return DU::getIcon(CResMgr::modules::book::icon_locked); - } - else { - return DU::getIcon(CResMgr::modules::book::icon_unlocked); - } - case CSwordModuleInfo::Cult: - case CSwordModuleInfo::Images: - case CSwordModuleInfo::DailyDevotional: - case CSwordModuleInfo::Glossary: - case CSwordModuleInfo::UnknownCategory: - default: - return categoryIcon(cat); - } -} - -QIcon BtBookshelfModel::categoryIcon(const CSwordModuleInfo::Category &category) { - namespace DU = util::directory; - - switch (category) { - case CSwordModuleInfo::Bibles: - return DU::getIcon(CResMgr::categories::bibles::icon); - case CSwordModuleInfo::Commentaries: - return DU::getIcon(CResMgr::categories::commentaries::icon); - case CSwordModuleInfo::Books: - return DU::getIcon(CResMgr::categories::books::icon); - case CSwordModuleInfo::Cult: - return DU::getIcon(CResMgr::categories::cults::icon); - case CSwordModuleInfo::Images: - return DU::getIcon(CResMgr::categories::images::icon); - case CSwordModuleInfo::DailyDevotional: - return DU::getIcon(CResMgr::categories::dailydevotional::icon); - case CSwordModuleInfo::Lexicons: - return DU::getIcon(CResMgr::categories::lexicons::icon); - case CSwordModuleInfo::Glossary: - return DU::getIcon(CResMgr::categories::glossary::icon); - case CSwordModuleInfo::UnknownCategory: - default: - return QIcon(); - } -} - -QString BtBookshelfModel::categoryName( - const CSwordModuleInfo::Category &category) { - switch (category) { - case CSwordModuleInfo::Bibles: - return tr("Bibles"); - case CSwordModuleInfo::Commentaries: - return tr("Commentaries"); - case CSwordModuleInfo::Books: - return tr("Books"); - case CSwordModuleInfo::Cult: - return tr("Cults/Unorthodox"); - case CSwordModuleInfo::Images: - return tr("Maps and Images"); - case CSwordModuleInfo::DailyDevotional: - return tr("Daily Devotionals"); - case CSwordModuleInfo::Lexicons: - return tr("Lexicons and Dictionaries"); - case CSwordModuleInfo::Glossary: - return tr("Glossaries"); - default: - return tr("Unknown"); - } -} - -QString BtBookshelfModel::languageName( - const CLanguageMgr::Language *language) { - return language->translatedName(); -} - void BtBookshelfModel::clear(bool destroy) { if (m_data.size() <= 0) return; @@ -217,6 +118,8 @@ void BtBookshelfModel::addModule(CSwordModuleInfo * const module) { this, SLOT(moduleHidden(bool))); connect(module, SIGNAL(hasIndexChanged(bool)), this, SLOT(moduleIndexed(bool))); + connect(module, SIGNAL(unlockedChanged(bool)), + this, SLOT(moduleUnlocked(bool))); endInsertRows(); } @@ -242,6 +145,8 @@ void BtBookshelfModel::addModules(const QSet &modules) { this, SLOT(moduleHidden(bool))); connect(module, SIGNAL(hasIndexChanged(bool)), this, SLOT(moduleIndexed(bool))); + connect(module, SIGNAL(unlockedChanged(bool)), + this, SLOT(moduleUnlocked(bool))); } endInsertRows(); } @@ -256,6 +161,8 @@ void BtBookshelfModel::removeModule(CSwordModuleInfo * const module, this, SLOT(moduleHidden(bool))); disconnect(module, SIGNAL(hasIndexChanged(bool)), this, SLOT(moduleIndexed(bool))); + disconnect(module, SIGNAL(unlockedChanged(bool)), + this, SLOT(moduleUnlocked(bool))); m_data.removeAt(index); endRemoveRows(); if (destroy) delete module; @@ -276,7 +183,7 @@ void BtBookshelfModel::removeModules(const QSet &modules, CSwordModuleInfo* BtBookshelfModel::getModule(const QString &name) const { Q_FOREACH(CSwordModuleInfo *module, m_data) { - if (module->name() == name) return module; + if (UNLIKELY(module->name() == name)) return module; } return 0; } @@ -293,6 +200,12 @@ void BtBookshelfModel::moduleIndexed(bool) { moduleDataChanged(static_cast(sender())); } +void BtBookshelfModel::moduleUnlocked(bool) { + Q_ASSERT(qobject_cast(sender()) != 0); + + moduleDataChanged(static_cast(sender())); +} + void BtBookshelfModel::moduleDataChanged(CSwordModuleInfo *module) { Q_ASSERT(m_data.count(module) == 1); diff --git a/src/backend/bookshelfmodel/btbookshelfmodel.h b/src/backend/bookshelfmodel/btbookshelfmodel.h index 735c655..20f2b3d 100644 --- a/src/backend/bookshelfmodel/btbookshelfmodel.h +++ b/src/backend/bookshelfmodel/btbookshelfmodel.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -18,6 +18,12 @@ #include "backend/drivers/cswordmoduleinfo.h" +/** + Implements a simple list model projecting CSwordModuleInfo instances. This model is mostly + implemented to provide an interface the the underlying data and to provide notifications + when modules are added, removed or changed. If you want to use a model for widgets, the + BtBookshelfTreeModel might be a better choice, since it also provides sorting and grouping. +*/ class BtBookshelfModel: public QAbstractListModel { Q_OBJECT public: @@ -31,55 +37,135 @@ class BtBookshelfModel: public QAbstractListModel { ModuleInstallPathRole = Qt::UserRole + 4, ModuleHasIndexRole = Qt::UserRole + 5, ModuleIndexSizeRole = Qt::UserRole + 6, + ModuleDescriptionRole = Qt::UserRole + 7, UserRole = Qt::UserRole + 100 }; + public: BtBookshelfModel(QObject *parent = 0); - virtual ~BtBookshelfModel(); + ~BtBookshelfModel(); - virtual int rowCount(const QModelIndex &parent) const; - virtual QVariant data(CSwordModuleInfo *module, int role) const; - virtual QVariant data(const QModelIndex &index, int role) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, + // Virtual methods implemented from QAbstractListModel: + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(CSwordModuleInfo *module, int role) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; bool setData(const QModelIndex &index, const QVariant &value, int role = ModuleHiddenRole); + /** + Given an index of this model, this method returns a pointer to the underlying + CSwordModuleInfo instance corresponding to the given index. + \param[in] index An index to this model. + */ inline CSwordModuleInfo *module(const QModelIndex &index) const { return (CSwordModuleInfo *) data(index, BtBookshelfModel::ModulePointerRole) .value(); } - static QIcon moduleIcon(const CSwordModuleInfo *module); - static QIcon categoryIcon(const CSwordModuleInfo::Category &category); - static QString categoryName(const CSwordModuleInfo::Category &category); - static QString languageName(const CLanguageMgr::Language *language); - + /** + Clears the data of the whole model by removing all items. + \param[in] destroy If true, all CSwordModuleInfo instances in this model are also + destroyed. + */ void clear(bool destroy = false); + + /** + Appends the given module to this model. + \param[in] module Module to add. + */ void addModule(CSwordModuleInfo * const module); + + /** + Appends the all the modules in the given set to this model. + \param[in] modules Set of modules to add. + */ void addModules(const QSet &modules); + + /** + Appends the all the modules in the given list to this model. + \param[in] modules Set of modules to add. + */ void addModules(const QList &modules); + + /** + Removes the given module from this model and optionally destroys it. + \param[in] module The module to remove from this model. + \param[in] destroy If true, the given CSwordModuleInfo instance is destroyed. + */ void removeModule(CSwordModuleInfo * const module, bool destroy = false); + + /** + Removes all modules from the given set from this model and optionally destroys + them. + \param[in] modules The set of modules to remove from this model. + \param[in] destroy If true, the given CSwordModuleInfo instances are destroyed. + */ void removeModules(const QSet &modules, bool destroy = false); + + /** + Removes all modules from the given list from this model and optionally destroys + them. + \param[in] modules The list of modules to remove from this model. + \param[in] destroy If true, the given CSwordModuleInfo instances are destroyed. + */ void removeModules(const QList &modules, bool destroy = false); + /** + Returns the first module found with the given name. + \param[in] name Name of the module to find. + */ CSwordModuleInfo* getModule(const QString &name) const; - inline const QList &modules() const { + + /** + Returns the list of handled modules as a list of CSwordModuleInfo* pointers. + */ + inline const QList &moduleList() const { return m_data; } protected slots: + /** + Slot DIRECTLY called by CSwordModuleInfo when the hidden status of the respective + module changes. + \param[in] hidden True, if the module was hidden; false, if the module was shown. + */ void moduleHidden(bool hidden); + + /** + Slot DIRECTLY called by CSwordModuleInfo when the indexed status of the respective + module changes. + \param[in] indexed True, if the module was indexed; false if the index was deleted. + */ void moduleIndexed(bool indexed); + /** + Slot DIRECTLY called by CSwordModuleInfo when the locked status of the respective + module changes. + \param[in] unlocked True, if the module was unlocked; false if the module was + locked. + */ + void moduleUnlocked(bool unlocked); + protected: + /** + Called internally when module data changes. This method emits any neccessary + signals for this model. + \pre The givem module is handled by this model. + \param[in] module The module that changed status. + */ void moduleDataChanged(CSwordModuleInfo *module); protected: + /** + The underlying data as a list of pointers to the respective CSwordModuleInfo + instances. + */ QList m_data; }; diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp index a2a988c..6444a81 100644 --- a/src/backend/bookshelfmodel/btbookshelftreemodel.cpp +++ b/src/backend/bookshelfmodel/btbookshelftreemodel.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,24 +13,50 @@ #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include +#include #include "backend/bookshelfmodel/categoryitem.h" #include "backend/bookshelfmodel/indexingitem.h" #include "backend/bookshelfmodel/languageitem.h" #include "backend/bookshelfmodel/moduleitem.h" +#include "backend/config/cbtconfig.h" +#include "util/macros.h" using namespace BookshelfModel; +bool BtBookshelfTreeModel::Grouping::loadFrom(const QString &configKey) { + Q_ASSERT(!configKey.isNull()); + QVariant v = CBTConfig::getConfig()->value(configKey); + (*this) = v.value(); + return v.canConvert(); +} + +void BtBookshelfTreeModel::Grouping::saveTo(const QString &configKey) const { + Q_ASSERT(!configKey.isNull()); + CBTConfig::getConfig()->setValue(configKey, QVariant::fromValue(*this)); +} + + BtBookshelfTreeModel::BtBookshelfTreeModel(QObject *parent) - : QAbstractItemModel(parent), m_sourceModel(0), m_rootItem(new RootItem), - m_defaultChecked(MODULE_HIDDEN), m_checkable(false) { - m_groupingOrder.push_back(GROUP_CATEGORY); - m_groupingOrder.push_back(GROUP_LANGUAGE); + : QAbstractItemModel(parent), m_sourceModel(0), m_rootItem(new RootItem), + m_defaultChecked(MODULE_HIDDEN), m_checkable(false) +{ + // Intentionally empty +} + +BtBookshelfTreeModel::BtBookshelfTreeModel(const QString &configKey, + QObject *parent) + : QAbstractItemModel(parent), m_sourceModel(0), m_rootItem(new RootItem), + m_groupingOrder(configKey), m_defaultChecked(MODULE_HIDDEN), + m_checkable(false) +{ + // Intentionally empty } BtBookshelfTreeModel::BtBookshelfTreeModel(const Grouping &g, QObject *parent) : QAbstractItemModel(parent), m_sourceModel(0), m_rootItem(new RootItem), - m_groupingOrder(g), m_defaultChecked(MODULE_HIDDEN), m_checkable(false) { + m_groupingOrder(g), m_defaultChecked(MODULE_HIDDEN), m_checkable(false) +{ // Intentionally empty } @@ -123,13 +149,14 @@ QVariant BtBookshelfTreeModel::data(CSwordModuleInfo *module, int role) const { bool BtBookshelfTreeModel::setData(const QModelIndex &itemIndex, const QVariant &value, int role) { + Q_ASSERT(itemIndex.isValid()); typedef QPair IP; Qt::CheckState newState; - if (role == Qt::CheckStateRole) { + if (LIKELY(role == Qt::CheckStateRole)) { bool ok; newState = (Qt::CheckState) value.toInt(&ok); - if (!ok) return false; + if (UNLIKELY(!ok)) return false; } else { return false; @@ -262,7 +289,9 @@ void BtBookshelfTreeModel::setSourceModel(QAbstractItemModel *sourceModel) { } } -void BtBookshelfTreeModel::setGroupingOrder(const Grouping &groupingOrder) { +void BtBookshelfTreeModel::setGroupingOrder(const Grouping &groupingOrder, + bool emitSignal) +{ if (m_groupingOrder == groupingOrder) return; m_groupingOrder = groupingOrder; @@ -291,6 +320,8 @@ void BtBookshelfTreeModel::setGroupingOrder(const Grouping &groupingOrder) { addModule(module, checked.contains(module)); } } + + if (emitSignal) emit groupingOrderChanged(groupingOrder); } void BtBookshelfTreeModel::setCheckable(bool checkable) { @@ -299,14 +330,29 @@ void BtBookshelfTreeModel::setCheckable(bool checkable) { if (m_sourceModel == 0) return; // Notify views that flags changed for all items: + resetData(); +} + +void BtBookshelfTreeModel::setCheckedModules(const QSet &modules) { + typedef ModuleItemMap::const_iterator MIMCI; + + for (MIMCI it(m_modules.constBegin()); it != m_modules.constEnd(); it++) { + if (modules.contains(it.key())) { + setData(getIndex(it.value()), Qt::Checked, Qt::CheckStateRole); + } else { + setData(getIndex(it.value()), Qt::Unchecked, Qt::CheckStateRole); + } + } +} + +void BtBookshelfTreeModel::resetData() { QModelIndexList queue; queue.append(QModelIndex()); do { QModelIndex parent(queue.takeFirst()); - int numChildren(rowCount(parent)); emit dataChanged(index(0, 0, parent), - index(numChildren - 1, 0, parent)); - for (int i(0); i < numChildren; i++) { + index(rowCount(parent) - 1, columnCount() - 1, parent)); + for (int i(0); i < rowCount(parent); i++) { QModelIndex childIndex(index(i, 0, parent)); if (rowCount(childIndex) > 0) { queue.append(childIndex); @@ -402,7 +448,7 @@ void BtBookshelfTreeModel::removeModule(CSwordModuleInfo *module) { } Item *BtBookshelfTreeModel::getItem(const QModelIndex &index) const { - if (index.isValid()) { + if (LIKELY(index.isValid())) { Item *item(static_cast(index.internalPointer())); Q_ASSERT(item != 0); return item; @@ -504,8 +550,7 @@ void BtBookshelfTreeModel::moduleDataChanged(const QModelIndex &topLeft, } } -void BtBookshelfTreeModel::moduleInserted(const QModelIndex &parent, int start, - int end) { +void BtBookshelfTreeModel::moduleInserted(const QModelIndex &parent, int start, int end) { typedef BtBookshelfModel BM; static const BM::ModuleRole PR(BM::ModulePointerRole); static const BM::ModuleRole HR(BM::ModuleHiddenRole); @@ -531,8 +576,7 @@ void BtBookshelfTreeModel::moduleInserted(const QModelIndex &parent, int start, } } -void BtBookshelfTreeModel::moduleRemoved(const QModelIndex &parent, int start, - int end) { +void BtBookshelfTreeModel::moduleRemoved(const QModelIndex &parent, int start, int end) { typedef BtBookshelfModel BM; static const BM::ModuleRole PR(BM::ModulePointerRole); @@ -557,6 +601,7 @@ QDataStream &operator<<(QDataStream &os, const BtBookshelfTreeModel::Grouping &o QDataStream &operator>>(QDataStream &is, BtBookshelfTreeModel::Grouping &o) { int s; is >> s; + o.clear(); for (int i(0); i < s; i++) { int g; is >> g; diff --git a/src/backend/bookshelfmodel/btbookshelftreemodel.h b/src/backend/bookshelfmodel/btbookshelftreemodel.h index 47ce672..2a28dd8 100644 --- a/src/backend/bookshelfmodel/btbookshelftreemodel.h +++ b/src/backend/bookshelfmodel/btbookshelftreemodel.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -36,7 +36,7 @@ class BtBookshelfTreeModel: public QAbstractItemModel { typedef QMap ModuleItemMap; typedef QMap SourceIndexMap; - public: + public: /* Types: */ enum ModuleRole { CheckStateRole = BtBookshelfModel::UserRole, UserRole = BtBookshelfModel::UserRole + 100 @@ -52,9 +52,31 @@ class BtBookshelfTreeModel: public QAbstractItemModel { MODULE_HIDDEN, /**< By default, check only added modules that are not hidden. */ MODULE_INDEXED /**< By default, check only added modules that are indexed. */ }; - typedef QList Grouping; + class Grouping: public QList { + public: + /** + \warning Be careful using this constructor! + */ + explicit inline Grouping(bool empty = false) { + if (empty) return; + push_back(GROUP_CATEGORY); + push_back(GROUP_LANGUAGE); + } + explicit inline Grouping(Group group) { push_back(group); } + explicit inline Grouping(const QString &configKey) { + loadFrom(configKey); + } + inline Grouping(const Grouping ©) + : QList(copy) {} + + bool loadFrom(const QString &configKey); + void saveTo(const QString &configKey) const; + }; + + public: /* Methods: */ BtBookshelfTreeModel(QObject *parent = 0); + BtBookshelfTreeModel(const QString &configKey, QObject *parent = 0); BtBookshelfTreeModel(const Grouping &grouping, QObject *parent = 0); virtual ~BtBookshelfTreeModel(); @@ -75,30 +97,31 @@ class BtBookshelfTreeModel: public QAbstractItemModel { virtual bool setData(const QModelIndex &index, const QVariant &value, int role); - void setSourceModel(QAbstractItemModel *sourceModel); - inline QAbstractItemModel *sourceModel() const { - return m_sourceModel; - } - void setGroupingOrder(const Grouping &groupingOrder); - inline Grouping groupingOrder() const { - return m_groupingOrder; + inline QAbstractItemModel *sourceModel() const { return m_sourceModel; } + inline const Grouping &groupingOrder() const { return m_groupingOrder; } + inline bool checkable() const { return m_checkable; } + inline CheckedBehavior defaultChecked() const { return m_defaultChecked; } + inline QList modules() const { return m_modules.keys(); } + inline const QSet &checkedModules() const { + return m_checkedModulesCache; } + + public slots: + void setSourceModel(QAbstractItemModel *sourceModel); + void setGroupingOrder(const BtBookshelfTreeModel::Grouping &groupingOrder, + bool emitSignal = true); void setCheckable(bool checkable); - inline bool checkable() const { - return m_checkable; - } inline void setDefaultChecked(CheckedBehavior b) { m_defaultChecked = b; } - inline CheckedBehavior defaultChecked() const { - return m_defaultChecked; - } + void setCheckedModules(const QSet &modules); - inline const QSet &checkedModules() const { - return m_checkedModulesCache; - } + signals: + void groupingOrderChanged(BtBookshelfTreeModel::Grouping newGrouping); + void moduleChecked(CSwordModuleInfo *module, bool checked); protected: + void resetData(); QVariant parentData(BookshelfModel::ModuleItem *item, int role) const; void addModule(CSwordModuleInfo *module, bool checked); void addModule(CSwordModuleInfo *module, QModelIndex parentIndex, @@ -132,9 +155,6 @@ class BtBookshelfTreeModel: public QAbstractItemModel { void moduleInserted(const QModelIndex &parent, int start, int end); void moduleRemoved(const QModelIndex &parent, int start, int end); - signals: - void moduleChecked(CSwordModuleInfo *module, bool checked); - protected: QAbstractItemModel *m_sourceModel; BookshelfModel::Item *m_rootItem; diff --git a/src/backend/bookshelfmodel/categoryitem.cpp b/src/backend/bookshelfmodel/categoryitem.cpp index 46905d7..aaf5566 100644 --- a/src/backend/bookshelfmodel/categoryitem.cpp +++ b/src/backend/bookshelfmodel/categoryitem.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -23,9 +23,9 @@ CategoryItem::CategoryItem(CSwordModuleInfo *module) QVariant CategoryItem::data(int role) const { switch (role) { case Qt::DisplayRole: - return BtBookshelfModel::categoryName(m_category); + return CSwordModuleInfo::categoryName(m_category); case Qt::DecorationRole: - return BtBookshelfModel::categoryIcon(m_category); + return CSwordModuleInfo::categoryIcon(m_category); default: return Item::data(role); } diff --git a/src/backend/bookshelfmodel/categoryitem.h b/src/backend/bookshelfmodel/categoryitem.h index 879895f..75d5a7c 100644 --- a/src/backend/bookshelfmodel/categoryitem.h +++ b/src/backend/bookshelfmodel/categoryitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/indexingitem.cpp b/src/backend/bookshelfmodel/indexingitem.cpp index 898096f..5491ca5 100644 --- a/src/backend/bookshelfmodel/indexingitem.cpp +++ b/src/backend/bookshelfmodel/indexingitem.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/indexingitem.h b/src/backend/bookshelfmodel/indexingitem.h index f30fb2d..a1eb812 100644 --- a/src/backend/bookshelfmodel/indexingitem.h +++ b/src/backend/bookshelfmodel/indexingitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/item.cpp b/src/backend/bookshelfmodel/item.cpp index 809021b..02cd991 100644 --- a/src/backend/bookshelfmodel/item.cpp +++ b/src/backend/bookshelfmodel/item.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/item.h b/src/backend/bookshelfmodel/item.h index f10da04..652120b 100644 --- a/src/backend/bookshelfmodel/item.h +++ b/src/backend/bookshelfmodel/item.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/languageitem.cpp b/src/backend/bookshelfmodel/languageitem.cpp index 547c953..2fdab8b 100644 --- a/src/backend/bookshelfmodel/languageitem.cpp +++ b/src/backend/bookshelfmodel/languageitem.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -23,7 +23,7 @@ LanguageItem::LanguageItem(CSwordModuleInfo *module) QVariant LanguageItem::data(int role) const { switch (role) { case Qt::DisplayRole: - return BtBookshelfModel::languageName(m_language); + return m_language->translatedName(); case Qt::DecorationRole: return util::directory::getIcon("flag.svg"); default: diff --git a/src/backend/bookshelfmodel/languageitem.h b/src/backend/bookshelfmodel/languageitem.h index c6e4417..03a9ce3 100644 --- a/src/backend/bookshelfmodel/languageitem.h +++ b/src/backend/bookshelfmodel/languageitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/moduleitem.cpp b/src/backend/bookshelfmodel/moduleitem.cpp index e7aff92..ca9c3fb 100644 --- a/src/backend/bookshelfmodel/moduleitem.cpp +++ b/src/backend/bookshelfmodel/moduleitem.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * diff --git a/src/backend/bookshelfmodel/moduleitem.h b/src/backend/bookshelfmodel/moduleitem.h index 006ae97..5e6e1ba 100644 --- a/src/backend/bookshelfmodel/moduleitem.h +++ b/src/backend/bookshelfmodel/moduleitem.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -28,10 +28,10 @@ class ModuleItem: public Item { ModuleItem(CSwordModuleInfo *module, BtBookshelfTreeModel *parentModel); /** - Reimplementation of \ref Item::data which dispatches all requests to - the \ref BtBookshelfTreeModel parent model. + Reimplementation of Item::data() which dispatches all + requests to the parent model (BtBookshelfTreeModel). */ - QVariant data(int role = Qt::DisplayRole) const; + virtual QVariant data(int role = Qt::DisplayRole) const; inline CSwordModuleInfo *moduleInfo() const { return m_moduleInfo; diff --git a/src/backend/btinstallbackend.cpp b/src/backend/btinstallbackend.cpp new file mode 100644 index 0000000..67f8945 --- /dev/null +++ b/src/backend/btinstallbackend.cpp @@ -0,0 +1,301 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/btinstallbackend.h" + +#include +#include +#include +#include +#include "backend/managers/cswordbackend.h" +#include "frontend/bookshelfmanager/btinstallmgr.h" +#include "util/directory.h" +#include "util/dialogutil.h" + +// Sword includes: +#include +#include +#include + + +using namespace sword; + +namespace BtInstallBackend { + +/** Adds the source described by Source to the backend. */ +bool addSource(sword::InstallSource& source) { + qDebug() << "backend::addSource"; + SWConfig config(configFilename().toLatin1()); + if (!strcmp(source.type, "FTP")) { + //make sure the path doesn't have a trailing slash, sword doesn't like it + if (source.directory[ source.directory.length()-1 ] == '/') { + source.directory--; //make one char shorter + } + + config["Sources"].insert( std::make_pair(SWBuf("FTPSource"), source.getConfEnt()) ); + } + else if (!strcmp(source.type, "DIR")) { + config["Sources"].insert( std::make_pair(SWBuf("DIRSource"), source.getConfEnt()) ); + } + config.Save(); + return true; +} + +/** Returns the Source struct. */ +sword::InstallSource source(const QString &name) { + qDebug() << "backend::source"; + BtInstallMgr mgr; + InstallSourceMap::iterator source = mgr.sources.find(name.toLatin1().data()); + if (source != mgr.sources.end()) { + return *(source->second); + } + else { //not found in Sword, may be a local DIR source + SWConfig config(configFilename().toLatin1()); + SectionMap::iterator sourcesSection = config.Sections.find("Sources"); + if (sourcesSection != config.Sections.end()) { + ConfigEntMap::iterator sourceBegin = + sourcesSection->second.lower_bound("DIRSource"); + ConfigEntMap::iterator sourceEnd = + sourcesSection->second.upper_bound("DIRSource"); + + while (sourceBegin != sourceEnd) { + InstallSource is("DIR", sourceBegin->second.c_str()); + if (!strcmp(is.caption, name.toLatin1()) ) { //found local dir source + return is; + } + + sourceBegin++;//next source + } + } + } + + InstallSource is("EMPTY"); //default return value + is.caption = "unknown caption"; + is.source = "unknown source"; + is.directory = "unknown dir"; + return is; +} + +/** Deletes the source. */ +bool deleteSource(const QString &name) { + qDebug() << "backend::deleteSource"; + sword::InstallSource is = source(name ); + + SWConfig config(configFilename().toLatin1()); + + //this code can probably be shortened by using the stl remove_if functionality + std::pair< ConfigEntMap::iterator, ConfigEntMap::iterator > range = + isRemote(is) + ? config["Sources"].equal_range("FTPSource") + : config["Sources"].equal_range("DIRSource"); + + ConfigEntMap::iterator it = range.first; + SWBuf sourceConfigEntry = is.getConfEnt(); + bool notFound = true; + while (it != range.second) { + //SWORD lib gave us a "nice" surprise: getConfEnt() adds uid, so old sources added by BT are not recognized here + if (it->second == sourceConfigEntry) { + config["Sources"].erase(it); + notFound = false; + break; + } + ++it; + } + if (notFound) { + qDebug() << "source was not found, try without uid"; + //try again without uid + QString sce(sourceConfigEntry.c_str()); + QStringList l = sce.split('|'); + l.removeLast(); + sce = l.join("|").append("|"); + it = range.first; + while (it != range.second) { + qDebug() << it->second; + if (it->second == sce) { + config["Sources"].erase(it); + break; + } + ++it; + } + } + + config.Save(); + return true; /// \todo dummy +} + +/** Returns the moduleinfo list for the source. Delete the pointer after using. IS THIS POSSIBLE?*/ +QList moduleList(QString /*name*/) { + QList list; /// \todo dummy + return list; +} + +bool isRemote(const sword::InstallSource& source) { + return !strcmp(source.type, "FTP"); +} + +QString configPath() { + return util::directory::getUserHomeSwordDir().absolutePath().append("/InstallMgr"); +} + +QString configFilename() { + return configPath().append("/InstallMgr.conf"); +} + +QStringList targetList() { + qDebug() << "backend::targetList"; + QStringList names = CSwordBackend::instance()->swordDirList(); + return names; +} + +bool setTargetList( const QStringList& targets ) { + namespace DU = util::directory; + + qDebug() << "backend::setTargetList"; + //saves a new Sword config using the provided target list + //QString filename = KGlobal::dirs()->saveLocation("data", "bibletime/") + "sword.conf"; //default is to assume the real location isn't writable + //QString filename = util::DirectoryUtil::getUserBaseDir().canonicalPath().append("/.sword/sword.conf"); + //bool directAccess = false; + QString filename = swordConfigFilename(); + QFileInfo i(filename); + QFileInfo dirInfo(i.absolutePath()); + + + if ( !i.exists() && dirInfo.isWritable() ) { + // if the file doesn't exist but the parent is writable, create it + qWarning() << "The Sword config file does not exist, it has to be created"; + QFile f(filename); + f.open(QIODevice::WriteOnly); + f.close(); + i.refresh(); + } + if ( i.exists() && i.isWritable() ) { //we can write to the file ourself + qDebug() << "The Sword config file is writable"; + } + else { + // There is no way to save to the file + qWarning() << "The Sword config file is not writable!"; + util::showWarning(0, QObject::tr("Can't write file"), QObject::tr("The Sword config file can't be written!")); + return false; + } + + filename = util::directory::convertDirSeparators(filename); + SWConfig conf(filename.toLocal8Bit()); + conf.Sections.clear(); + +#ifdef Q_WS_WIN + // On Windows, add the sword directory to the config file. + QString swordPath = DU::convertDirSeparators( DU::getApplicationSwordDir().absolutePath()); + conf["Install"].insert( + std::make_pair( SWBuf("LocalePath"), swordPath.toLocal8Bit().data() ) + ); +#endif + + bool setDataPath = false; + for (QStringList::const_iterator it = targets.begin(); it != targets.end(); ++it) { + QString t = DU::convertDirSeparators(*it); +#ifdef Q_WS_WIN + if (t.contains(DU::convertDirSeparators(DU::getUserHomeDir().canonicalPath().append("\\Sword")))) { +#else + if (t.contains(DU::getUserHomeDir().canonicalPath().append("/.sword"))) { +#endif + //we don't want $HOME/.sword in the config + continue; + } + else { + qDebug() << "Add path to the conf file" << filename << ":" << t; + conf["Install"].insert( std::make_pair(!setDataPath ? SWBuf("DataPath") : SWBuf("AugmentPath"), t.toLocal8Bit().data()) ); + setDataPath = true; + } + } + qDebug() << "save the sword conf..."; + conf.Save(); + CSwordBackend::instance()->reloadModules(CSwordBackend::PathChanged); + return true; +} + +QStringList sourceNameList() { + qDebug() << "backend::sourceList"; + BtInstallMgr mgr; + Q_ASSERT(mgr.installConf); + + QStringList names; + + //add Sword remote sources + for (InstallSourceMap::iterator it = mgr.sources.begin(); it != mgr.sources.end(); it++) { + names << QString::fromLocal8Bit(it->second->caption); + } + + // Add local directory sources + SWConfig config(configFilename().toLatin1()); + sword::SectionMap::iterator sourcesSection = config.Sections.find("Sources"); + if (sourcesSection != config.Sections.end()) { + sword::ConfigEntMap::iterator sourceBegin = sourcesSection->second.lower_bound("DIRSource"); + sword::ConfigEntMap::iterator sourceEnd = sourcesSection->second.upper_bound("DIRSource"); + + while (sourceBegin != sourceEnd) { + InstallSource is("DIR", sourceBegin->second.c_str()); + names << QString::fromLatin1(is.caption.c_str()); + + sourceBegin++; + } + } + + return names; +} + + +void initPassiveFtpMode() { + qDebug() << "backend::initPassiveFtpMode"; + SWConfig config(configFilename().toLatin1()); + config["General"]["PassiveFTP"] = "true"; + config.Save(); +} +QString swordConfigFilename() { + namespace DU = util::directory; + + qDebug() << "backend::swordConfigFilename"; +#ifdef Q_WS_WIN + qDebug() << DU::getUserHomeDir().absolutePath().append("/Sword/sword.conf"); + return DU::getUserHomeDir().absolutePath().append("/Sword/sword.conf"); +// return DU::getApplicationDir().absolutePath().append("/sword.conf"); +#else + qDebug() << DU::getUserHomeDir().absolutePath().append("/.sword/sword.conf"); + return DU::getUserHomeDir().absolutePath().append("/.sword/sword.conf"); +#endif +} + +QDir swordDir() { + namespace DU = util::directory; + +#ifdef Q_WS_WIN + return QDir(DU::getUserHomeDir().absolutePath().append("/Sword/")); +#else + return QDir(DU::getUserHomeDir().absolutePath().append("/.sword/")); +#endif +} + +CSwordBackend* backend( const sword::InstallSource& is) { + qDebug() << "backend::backend"; + CSwordBackend* ret = 0; + /// \anchor BackendNotSingleton + if (isRemote(is)) { + ret = new CSwordBackend( QString(is.localShadow.c_str()), false ); + } + else { + ret = new CSwordBackend( QString(is.directory.c_str()), false); + } + + Q_ASSERT(ret); + if (ret) { + ret->initModules(CSwordBackend::OtherChange); + } + return ret; +} + +} // namespace BtInstallBackend diff --git a/src/backend/btinstallbackend.h b/src/backend/btinstallbackend.h new file mode 100644 index 0000000..fc71697 --- /dev/null +++ b/src/backend/btinstallbackend.h @@ -0,0 +1,71 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef INSTBACKEND_H +#define INSTBACKEND_H + +#include +#include +#include "backend/managers/cswordbackend.h" + +// Sword includes: +#include + + +class CSwordModuleInfo; + +namespace BtInstallBackend { + +/** Adds the source to the backend. */ +bool addSource(sword::InstallSource& source); + +/** Returns the source struct. */ +sword::InstallSource source(const QString &name); + +/** Deletes the source. */ +bool deleteSource(const QString &name); + +/** Returns the moduleinfo list for the source. */ +QList moduleList(const QString &name); + +/** Tells if the source is remote or local. */ +bool isRemote(const sword::InstallSource& source); + +/** Returns the list of available install target paths. */ +QStringList targetList(); + +/** Saves the list of available install target paths to the sword config. Return success indicator.*/ +bool setTargetList( const QStringList& targets ); + +QStringList sourceNameList(); + +/** Returns the path of the sword installer configuration file. */ +QString configPath(); + +/** Returns the name of the sword installer configuration file. */ +QString configFilename(); + +/** Sets the passive mode for as default. +* \todo see if we can en/disable this per source. +*/ +void initPassiveFtpMode(); + +/** Returns the file name for the Sword config file. */ +QString swordConfigFilename(); + +/** Returns the Sword directory ($HOME/.sword/) as a QDir, created with absolute path (not canonical). +*/ +QDir swordDir(); + +/** Returns backend Sword manager for the source. */ +CSwordBackend* backend( const sword::InstallSource& is); + +} // namespace BtInstallBackend + +#endif diff --git a/src/backend/btmoduletreeitem.cpp b/src/backend/btmoduletreeitem.cpp index 01e4446..c57d094 100644 --- a/src/backend/btmoduletreeitem.cpp +++ b/src/backend/btmoduletreeitem.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,7 +14,6 @@ #include #include "backend/drivers/cswordmoduleinfo.h" #include "backend/managers/cswordbackend.h" -#include "util/cpointers.h" #include "util/cresmgr.h" #include "util/tool.h" @@ -30,7 +29,7 @@ BTModuleTreeItem::BTModuleTreeItem(QList& filters, BT m_originalModuleList = *modules; } else { - m_originalModuleList = CPointers::backend()->moduleList(); + m_originalModuleList = CSwordBackend::instance()->moduleList(); } //populate the tree with groups/modules create_tree(filters, grouping); @@ -139,7 +138,7 @@ void BTModuleTreeItem::create_tree(QList& filters, BT map_initialized = true; } - //QList originalInfoList = CPointers::backend()->moduleList(); + //QList originalInfoList = CSwordBackend::instance()()->moduleList(); foreach (CSwordModuleInfo* info, m_originalModuleList) { bool included; diff --git a/src/backend/btmoduletreeitem.h b/src/backend/btmoduletreeitem.h index 5bcebf8..6ee6868 100644 --- a/src/backend/btmoduletreeitem.h +++ b/src/backend/btmoduletreeitem.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -27,21 +27,21 @@ different set of filters you have to create a new tree - it's not possible to mo Example: - ... - QList noFilters - BTModuleTreeItem root(noFilters, BTModuleTreeItem::CatLangMod); - add_to_view(&root, qtreewidget->invisibleRootItem()); - ... - void add_to_view(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem) { - foreach (BTModuleTreeItem* i, item->children()) { - add_to_view(i, new QTreeWidgetItem(widgetItem)); - } - if (item->type() == BTModuleTreeItem::Category) prepare_category_item(widgetItem, item); - ... - } - - - @author The BibleTime team + ... + QList noFilters + BTModuleTreeItem root(noFilters, BTModuleTreeItem::CatLangMod); + add_to_view(&root, qtreewidget->invisibleRootItem()); + ... + void add_to_view(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem) { + foreach (BTModuleTreeItem* i, item->children()) { + add_to_view(i, new QTreeWidgetItem(widgetItem)); + } + if (item->type() == BTModuleTreeItem::Category) prepare_category_item(widgetItem, item); + ... + } + + + @author The BibleTime team */ class BTModuleTreeItem { public: @@ -63,10 +63,10 @@ class BTModuleTreeItem { * will stop with the first negative. * * Example: - * QList filters; - * MyFilter filter; BTModuleTreeItem::HiddenOff hideFilter; - * filters.append(&hideFilter); filters.append(&filter); - * BTModuleTreeItem root(filters, BTModuleTreeItem::CatLangMod); + * QList filters; + * MyFilter filter; BTModuleTreeItem::HiddenOff hideFilter; + * filters.append(&hideFilter); filters.append(&filter); + * BTModuleTreeItem root(filters, BTModuleTreeItem::CatLangMod); */ struct Filter { virtual bool filter(CSwordModuleInfo*) = 0; @@ -102,7 +102,7 @@ class BTModuleTreeItem { * The root item is populated with the item tree. * The constructor takes a list of filters (see Filter), grouping indicator (see Grouping) * and optionally the module list from which the tree is constructed - * (by default CPointers::backend()->moduleList() is used). + * (by default CSwordBackend::instance()()->moduleList() is used). */ BTModuleTreeItem(QList& filters, BTModuleTreeItem::Grouping grouping, QList* modules = 0); diff --git a/src/backend/config/cbtconfig.cpp b/src/backend/config/cbtconfig.cpp index 39c3e0c..883f41f 100644 --- a/src/backend/config/cbtconfig.cpp +++ b/src/backend/config/cbtconfig.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,9 +16,9 @@ #include #include "backend/btmoduletreeitem.h" #include "backend/managers/cdisplaytemplatemgr.h" +#include "btglobal.h" #include "frontend/displaywindow/btactioncollection.h" #include "frontend/searchdialog/btsearchoptionsarea.h" -#include "util/cpointers.h" #include "util/directory.h" // Sword includes: @@ -91,6 +91,8 @@ QString getKey(const bools ID) { return "autoTileHorizontal"; case autoTile: return "autoTile"; + case autoTabbed: + return "autoTabbed"; case autoCascade: return "autoCascade"; @@ -112,18 +114,24 @@ QString getKey(const bools ID) { return "bookshelfShowHidden"; case allowNetworkConnection: return "allowNetworkConnection"; - + case showTextWindowHeaders: return "showTextWindowHeaders"; case showTextWindowNavigator: return "showTextWindowNavigator"; case showTextWindowModuleSelectorButtons: return "showTextWindowModuleSelectorButtons"; + case showFormatToolbarButtons: + return "showFormatToolbarButtons"; case showTextWindowToolButtons: return "showTextWindowToolButtons"; + case showToolbarsInEachWindow: + return "showToolbarsInEachWindow"; + case showTipAtStartup: + return "showTipAtStartup"; } Q_ASSERT(false); - return false; + return QString::null; } QString getKey(const ints ID) { @@ -188,6 +196,8 @@ QString getKey(const ints ID) { return "configDialogHeight"; case configDialogWidth: return "configDialogWidth"; + case tipNumber: + return "tipNumber"; } Q_ASSERT(false); return QString::null; @@ -249,7 +259,7 @@ QString IntListToString(const QList intList) { return intStrings.join(","); } -QList StringToIntList(const QString intListString) { +QList StringToIntList(const QString &intListString) { QList intList; if (!intListString.isEmpty() && intListString.contains(',')) { foreach(QString intString, intListString.split(',')) { @@ -268,13 +278,13 @@ QString getDefault(const strings ID) { case displayStyle: return CDisplayTemplateMgr::defaultTemplate(); case bookshelfCurrentItem: - return QString(); + return QString::null; } return QString::null; } QString getDefault(const modules ID) { - // CSwordBackend *b = CPointers::backend(); + // CSwordBackend *b = CSwordBackend::instance()(); switch (ID) { case standardBible: return "KJV"; @@ -318,6 +328,8 @@ bool getDefault(const bools ID) { return false; case autoTile: return false; + case autoTabbed: + return false; case autoCascade: return false; @@ -338,7 +350,7 @@ bool getDefault(const bools ID) { return false; case allowNetworkConnection: return false; - + case showTextWindowHeaders: return true; case showTextWindowNavigator: @@ -347,6 +359,12 @@ bool getDefault(const bools ID) { return true; case showTextWindowToolButtons: return true; + case showFormatToolbarButtons: + return true; + case showToolbarsInEachWindow: + return true; + case showTipAtStartup: + return true; } return false; } @@ -413,6 +431,8 @@ int getDefault(const ints ID) { return 1; case configDialogWidth: return 1; + case tipNumber: + return 0; } return 0; } @@ -498,7 +518,7 @@ QString get(const strings ID) { CSwordModuleInfo *get(const modules ID) { getConfig()->beginGroup("modules"); - CSwordModuleInfo *result(CPointers::backend()->findModuleByName( + CSwordModuleInfo *result(CSwordBackend::instance()->findModuleByName( getConfig()->value(getKey(ID), getDefault(ID)).toString() )); getConfig()->endGroup(); @@ -603,7 +623,7 @@ FontSettingsPair get(const CLanguageMgr::Language * const language) { return settings; } -void set(const strings ID, const QString value) { +void set(const strings ID, const QString &value) { // KConfigGroup cg = getConfig()->group("strings"); // cg.writeEntry(getKey(ID), value); getConfig()->beginGroup("strings"); @@ -620,7 +640,7 @@ void set(const modules ID, CSwordModuleInfo * const value) { } void set(const modules ID, const QString& value) { - CSwordModuleInfo *module(CPointers::backend()->findModuleByName(value)); + CSwordModuleInfo *module(CSwordBackend::instance()->findModuleByName(value)); if (module) { set(ID, module); } @@ -704,15 +724,15 @@ void set(const CLanguageMgr::Language * const language, m_fontCache.remove(language); } -CSwordBackend::DisplayOptions getDisplayOptionDefaults() { - CSwordBackend::DisplayOptions options; +DisplayOptions getDisplayOptionDefaults() { + DisplayOptions options; options.lineBreaks = get(lineBreaks); options.verseNumbers = get(verseNumbers); return options; } -CSwordBackend::FilterOptions getFilterOptionDefaults() { - CSwordBackend::FilterOptions options; +FilterOptions getFilterOptionDefaults() { + FilterOptions options; options.footnotes = true; // Required for the info display options.strongNumbers = true; // get(strongNumbers); diff --git a/src/backend/config/cbtconfig.h b/src/backend/config/cbtconfig.h index 9f3a850..ef618a2 100644 --- a/src/backend/config/cbtconfig.h +++ b/src/backend/config/cbtconfig.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -56,6 +56,7 @@ enum bools { autoTileVertical, autoTileHorizontal, autoTile, + autoTabbed, autoCascade, lineBreaks, @@ -73,7 +74,10 @@ enum bools { showTextWindowHeaders, showTextWindowNavigator, showTextWindowToolButtons, - showTextWindowModuleSelectorButtons + showTextWindowModuleSelectorButtons, + showFormatToolbarButtons, + showToolbarsInEachWindow, + showTipAtStartup }; enum ints { footnotes, @@ -110,7 +114,8 @@ enum ints { configDialogPosX, configDialogPosY, configDialogHeight, - configDialogWidth + configDialogWidth, + tipNumber }; enum intLists { leftPaneSplitterSizes, @@ -140,7 +145,7 @@ enum stringMaps { }; QString IntListToString(const QList intList); -QList StringToIntList(const QString intListString); +QList StringToIntList(const QString &intListString); QString getDefault(const strings); QString getDefault(const modules); @@ -160,7 +165,7 @@ QStringList get(const stringLists); StringMap get(const stringMaps); FontSettingsPair get(const CLanguageMgr::Language * const); -void set(const strings, const QString value); +void set(const strings, const QString &value); void set(const modules, CSwordModuleInfo * const module); void set(const modules, const QString& moduleName); void set(const bools, const bool value); @@ -171,8 +176,8 @@ void set(const stringMaps, const StringMap value); void set(const CLanguageMgr::Language * const language, const FontSettingsPair &fontSettings); -CSwordBackend::FilterOptions getFilterOptionDefaults(); -CSwordBackend::DisplayOptions getDisplayOptionDefaults(); +FilterOptions getFilterOptionDefaults(); +DisplayOptions getDisplayOptionDefaults(); void setupAccelSettings(const keys type, BtActionCollection * const actionCollection); diff --git a/src/backend/cswordmodulesearch.cpp b/src/backend/cswordmodulesearch.cpp index 9348295..694151d 100644 --- a/src/backend/cswordmodulesearch.cpp +++ b/src/backend/cswordmodulesearch.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,63 +10,32 @@ #include "backend/cswordmodulesearch.h" #include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" #include "backend/managers/cswordbackend.h" +#include "btglobal.h" -// Sword includes: -#include -#include -#include +void CSwordModuleSearch::startSearch() { + // Clear old search results: + m_results.clear(); + m_foundItems = 0; -CSwordModuleSearch* CSwordModuleSearch::searcher = 0; + /// \todo What is the purpose of the following statement? + CSwordBackend::instance()->setFilterOptions(CBTConfig::getFilterOptionDefaults()); -CSwordModuleSearch::CSwordModuleSearch() - : m_searchedText(QString::null), - m_searchOptions(0), - m_foundItems(false) { - searcher = this; -} - -CSwordModuleSearch::~CSwordModuleSearch() { - searcher = 0; -} - -/** This function sets the modules which should be searched. */ -void CSwordModuleSearch::setModules( const QList& list ) { - m_moduleList = list; -} - -/** Starts the search for the search text. */ -bool CSwordModuleSearch::startSearch() { - backend()->setFilterOptions ( CBTConfig::getFilterOptionDefaults() ); - m_foundItems = false; - - bool foundItems = false; - - // for (m_moduleList.first(); m_moduleList.current() && !m_terminateSearch; m_moduleList.next()) { - QList::iterator end_it = m_moduleList.end(); - - for (QList::iterator it = m_moduleList.begin(); it != end_it; ++it) { - if ( (*it)->searchIndexed(m_searchedText/*, m_searchOptions*/, m_searchScope) ) { - foundItems = true; + // Search module-by-module: + Q_FOREACH(const CSwordModuleInfo *m, m_searchModules) { + sword::ListKey results; + int found = m->searchIndexed(m_searchText, m_searchScope, results); + if (found > 0) { + m_results.insert(m, results); + m_foundItems += found; } } - - m_foundItems = foundItems; - - //m_finishedSig.activate(); - emit finished(); - return true; } -/** Sets the text which should be search in the modules. */ -void CSwordModuleSearch::setSearchedText( const QString& text ) { - m_searchedText = text; -} +void CSwordModuleSearch::setSearchScope(const sword::ListKey &scope) { + /// \todo Properly examine and document the inner workings of this method. -/** Sets the search scope. */ -void CSwordModuleSearch::setSearchScope( const sword::ListKey& scope ) { m_searchScope.copyFrom( scope ); if (!strlen(scope.getRangeText())) { //we can't search with an empty search scope, would crash @@ -81,34 +50,14 @@ void CSwordModuleSearch::setSearchScope( const sword::ListKey& scope ) { } } -/** Sets the search scope back. */ -void CSwordModuleSearch::resetSearchScope() { - m_searchScope.ClearList(); -} - -/** Returns true if in the last search the searcher found items, if no items were found return false. */ -bool CSwordModuleSearch::foundItems() const { - return m_foundItems; -} - -/** Returns a copy of the used search scope. */ -const sword::ListKey& CSwordModuleSearch::searchScope() const { - return m_searchScope; -} - -void CSwordModuleSearch::connectFinished( QObject *receiver, const char *member ) { - //m_finishedSig.connect(receiver, member); - QObject::connect(this, SIGNAL(finished()), receiver, member); -} - -bool CSwordModuleSearch::modulesHaveIndices( const QList& modules ) { - bool hasIndices = true; - QList::const_iterator end_it = modules.end(); - for ( QList::const_iterator it = modules.begin(); it != end_it; ++it) { - if (!(*it)->hasIndex()) { - hasIndices = false; - break; +QList CSwordModuleSearch::unindexedModules( + const QList &modules) +{ + QList unindexed; + Q_FOREACH (const CSwordModuleInfo *m, modules) { + if (!m->hasIndex()) { + unindexed.append(m); } } - return hasIndices; + return unindexed; } diff --git a/src/backend/cswordmodulesearch.h b/src/backend/cswordmodulesearch.h index d40e9fa..bc0d37c 100644 --- a/src/backend/cswordmodulesearch.h +++ b/src/backend/cswordmodulesearch.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,8 +11,8 @@ #define CSWORDMODULESEARCH_H #include -#include -#include "util/cpointers.h" + +#include // Sword includes: #include @@ -28,65 +28,86 @@ class CSwordModuleInfo; * @version $Id: cswordmodulesearch.h,v 1.34 2006/08/08 19:32:48 joachim Exp $ */ -class CSwordModuleSearch: public QObject, CPointers { +class CSwordModuleSearch: public QObject { Q_OBJECT - public: - CSwordModuleSearch(); + public: /* Types: */ + typedef QHash Results; + + public: /* Methods: */ + inline CSwordModuleSearch() + : m_foundItems(0) {} + /** - * The destructor of this class. It cleans uop memory before it's deleted. + Sets the text which should be search in the modules. + \param[in] text the text to search. */ - virtual ~CSwordModuleSearch(); + inline void setSearchedText(const QString &text) { + m_searchText = text; + } + /** - * Sets the text which should be search in the modules. + Set the modules which should be searched. + \param[in] modules the modules to search in. */ - void setSearchedText( const QString& ); + inline void setModules(const QList &modules) { + Q_ASSERT(!modules.empty()); + Q_ASSERT(unindexedModules(modules).empty()); + m_searchModules = modules; + } + /** - * Starts the search for the search text. + Sets the search scope. + \param[in] scope the scope used for the search. */ - bool startSearch(); + void setSearchScope(const sword::ListKey &scope); + /** - * This function sets the modules which should be searched. + Resets the search scope. */ - void setModules( const QList& ); + inline void resetSearchScope() { + m_searchScope.ClearList(); + } + /** - * Sets the search scope. + \returns the search scope. */ - void setSearchScope( const sword::ListKey& scope ); + const sword::ListKey &searchScope() const { + return m_searchScope; + } + /** - * Sets the seaech scope back. + Starts the search for the search text. */ - void resetSearchScope(); + void startSearch(); + /** - * @return "true" if in the last search the searcher found items, if no items were found return "false" + \returns the number of found items in the last search. */ - bool foundItems() const; + inline unsigned long foundItems() const { + return m_foundItems; + } + /** - * Returns a copy of the used search scope. + \returns the results of the search. */ - const sword::ListKey& searchScope() const; - - void connectFinished( QObject * receiver, const char * member ); + const Results &results() const { + return m_results; + } /** - * Returns true if all of the specified modules have indices already built. + \returns the list of unindexed modules in the given list. */ - bool modulesHaveIndices( const QList& ); - - protected: - QString m_searchedText; - sword::ListKey m_searchScope; - QList m_moduleList; - - int m_searchOptions; - - bool m_foundItems; + static QList unindexedModules( + const QList &modules); - signals: - void finished(); + private: /* Fields: */ + QString m_searchText; + sword::ListKey m_searchScope; + QList m_searchModules; - private: - static CSwordModuleSearch* searcher; + Results m_results; + unsigned long m_foundItems; }; #endif diff --git a/src/backend/drivers/cswordbiblemoduleinfo.cpp b/src/backend/drivers/cswordbiblemoduleinfo.cpp index 4a65c4d..a81430f 100644 --- a/src/backend/drivers/cswordbiblemoduleinfo.cpp +++ b/src/backend/drivers/cswordbiblemoduleinfo.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "backend/drivers/cswordbiblemoduleinfo.h" -#include +#include #include #include "backend/managers/cswordbackend.h" #include "backend/keys/cswordversekey.h" @@ -18,65 +18,55 @@ #include -CSwordBibleModuleInfo::CSwordBibleModuleInfo( sword::SWModule* module, CSwordBackend* const usedBackend ) - : CSwordModuleInfo(module, usedBackend), +CSwordBibleModuleInfo::CSwordBibleModuleInfo(sword::SWModule *module, + CSwordBackend * const usedBackend, + ModuleType type) + : CSwordModuleInfo(module, usedBackend, type), m_lowerBound(0), m_upperBound(0), m_bookList(0), - m_cachedLocale("unknown"), - m_hasOT(-1), - m_hasNT(-1) {} + m_cachedLocale("unknown") +{ + initBounds(); +} -CSwordBibleModuleInfo::CSwordBibleModuleInfo( const CSwordBibleModuleInfo& m ) : - CSwordModuleInfo(m), +CSwordBibleModuleInfo::CSwordBibleModuleInfo(const CSwordBibleModuleInfo ©) : + CSwordModuleInfo(copy), m_lowerBound(0), m_upperBound(0), - m_bookList(0) { - if (m.m_bookList) { + m_bookList(0), + m_cachedLocale(copy.m_cachedLocale), + m_hasOT(copy.m_hasOT), + m_hasNT(copy.m_hasNT) +{ + if (copy.m_bookList) { m_bookList = new QStringList(); - *m_bookList = *m.m_bookList; + *m_bookList = *copy.m_bookList; } - - m_hasOT = m.m_hasOT; - m_hasNT = m.m_hasNT; - m_cachedLocale = m.m_cachedLocale; -} - -CSwordModuleInfo* CSwordBibleModuleInfo::clone() { - return new CSwordBibleModuleInfo(*this); -} - -CSwordBibleModuleInfo::~CSwordBibleModuleInfo() { - delete m_bookList; + initBounds(); } void CSwordBibleModuleInfo::initBounds() { - if (m_hasOT == -1) { - m_hasOT = hasTestament(OldTestament); - } + const bool oldStatus = module()->getSkipConsecutiveLinks(); + module()->setSkipConsecutiveLinks(true); - if (m_hasNT == -1) { - m_hasNT = hasTestament(NewTestament); - } + module()->setPosition(sword::TOP); // position to first entry + sword::VerseKey key(module()->KeyText()); + m_hasOT = (key.Testament() == 1); - if (m_hasOT) { - m_lowerBound.key("Genesis 1:1"); - } - else { - m_lowerBound.key("Matthew 1:1"); - } + module()->setPosition(sword::BOTTOM); + key = module()->KeyText(); + m_hasNT = (key.Testament() == 2); - if (!m_hasNT) { - m_upperBound.key("Malachi 4:6"); - } - else { - m_upperBound.key("Revelation of John 22:21"); - } + module()->setSkipConsecutiveLinks(oldStatus); + + m_lowerBound.setKey(m_hasOT ? "Genesis 1:1" : "Matthew 1:1"); + m_upperBound.setKey(!m_hasNT ? "Malachi 4:6" : "Revelation of John 22:21"); } /** Returns the books available in this module */ -QStringList* CSwordBibleModuleInfo::books() { +QStringList *CSwordBibleModuleInfo::books() const { if (m_cachedLocale != backend()->booknameLanguage()) { //if the locale has changed delete m_bookList; m_bookList = 0; @@ -85,34 +75,33 @@ QStringList* CSwordBibleModuleInfo::books() { if (!m_bookList) { m_bookList = new QStringList(); - initBounds(); - int min = 0; - int max = 1; + int min = 1; // 1 = OT + int max = 2; // 2 = NT //find out if we have ot and nt, only ot or only nt - if (m_hasOT > 0 && m_hasNT > 0) { //both - min = 0; - max = 1; - } - else if (m_hasOT > 0 && !m_hasNT) { //only OT - min = 0; - max = 0; + if (m_hasOT && m_hasNT) { //both + min = 1; + max = 2; } - else if (!m_hasOT && m_hasNT > 0) { //only NT + else if (m_hasOT && !m_hasNT) { //only OT min = 1; max = 1; } + else if (!m_hasOT && m_hasNT) { //only NT + min = 2; + max = 2; + } else if (!m_hasOT && !m_hasNT) { //somethings wrong here! - no OT and no NT qWarning("CSwordBibleModuleInfo (%s) no OT and not NT! Check your config!", module()->Name()); - min = 0; - max = -1; + min = 1; + max = 0; } - boost::scoped_ptr key((sword::VerseKey *)module()->CreateKey()); - (*key) = sword::TOP; + QSharedPointer key((sword::VerseKey *)module()->CreateKey()); + key->setPosition(sword::TOP); - for (key->Testament(min + 1); !key->Error() && (key->Testament() - 1) <= max; key->Book(key->Book() + 1)) { + for (key->setTestament(min); !key->Error() && key->getTestament() <= max; key->Book(key->Book() + 1)) { m_bookList->append( QString::fromUtf8(key->getBookName()) ); } @@ -122,101 +111,58 @@ QStringList* CSwordBibleModuleInfo::books() { return m_bookList; } -/** Returns the number of chapters for the given book. */ -unsigned int CSwordBibleModuleInfo::chapterCount(const unsigned int book) { +unsigned int CSwordBibleModuleInfo::chapterCount(const unsigned int book) const { int result = 0; - boost::scoped_ptr key((sword::VerseKey *)module()->CreateKey()); - (*key) = sword::TOP; + QSharedPointer key((sword::VerseKey *)module()->CreateKey()); + key->setPosition(sword::TOP); // works for old and new versions key->Book(book); - (*key) = sword::MAXCHAPTER; + key->setPosition(sword::MAXCHAPTER); result = key->Chapter(); return result; } -unsigned int CSwordBibleModuleInfo::chapterCount(const QString& book) { - return chapterCount( bookNumber(book) ); +unsigned int CSwordBibleModuleInfo::chapterCount(const QString &book) const { + return chapterCount(bookNumber(book)); } /** Returns the number of verses for the given chapter. */ -unsigned int CSwordBibleModuleInfo::verseCount( const unsigned int book, const unsigned int chapter ) { +unsigned int CSwordBibleModuleInfo::verseCount(const unsigned int book, + const unsigned int chapter) const +{ unsigned int result = 0; - boost::scoped_ptr key((sword::VerseKey *)module()->CreateKey()); - (*key) = sword::TOP; + QSharedPointer key((sword::VerseKey *)module()->CreateKey()); + key->setPosition(sword::TOP); // works for old and new versions key->Book(book); key->Chapter(chapter); - (*key) = sword::MAXVERSE; + key->setPosition(sword::MAXVERSE); result = key->Verse(); return result; } -unsigned int CSwordBibleModuleInfo::verseCount( const QString& book, const unsigned int chapter ) { - return verseCount( bookNumber(book), chapter ); +unsigned int CSwordBibleModuleInfo::verseCount(const QString &book, + const unsigned int chapter) const +{ + return verseCount(bookNumber(book), chapter); } -unsigned int CSwordBibleModuleInfo::bookNumber(const QString &book) { +unsigned int CSwordBibleModuleInfo::bookNumber(const QString &book) const { unsigned int bookNumber = 0; - //find out if we have ot and nt, only ot or only nt - initBounds(); - - boost::scoped_ptr key((sword::VerseKey *)module()->CreateKey()); - (*key) = sword::TOP; + QSharedPointer key((sword::VerseKey *)module()->CreateKey()); + key->setPosition(sword::TOP); key->setBookName(book.toUtf8().constData()); - bookNumber = ((key->Testament() > 1) ? key->BMAX[0] : 0) + key->Book(); + bookNumber = ((key->getTestament() > 1) ? key->BMAX[0] : 0) + key->Book(); return bookNumber; } - -/** Returns true if his module has the text of desired type of testament */ -bool CSwordBibleModuleInfo::hasTestament( CSwordBibleModuleInfo::Testament type ) { - if (m_hasOT == -1 || m_hasNT == -1) { - const bool oldStatus = module()->getSkipConsecutiveLinks(); - module()->setSkipConsecutiveLinks(true); - - *module() = sword::TOP; //position to first entry - sword::VerseKey key( module()->KeyText() ); - - if (key.Testament() == 1) { // OT && NT - m_hasOT = 1; - } - else if (key.Testament() == 2) { //no OT - m_hasOT = 0; - } - - *module() = sword::BOTTOM; - key = module()->KeyText(); - - if (key.Testament() == 1) { // only OT, no NT - m_hasNT = 0; - } - else if (key.Testament() == 2) { //has NT - m_hasNT = 1; - } - - module()->setSkipConsecutiveLinks(oldStatus); - } - - switch (type) { - - case OldTestament: - return m_hasOT > 0; - - case NewTestament: - return m_hasNT > 0; - - default: - return false; - } -} - diff --git a/src/backend/drivers/cswordbiblemoduleinfo.h b/src/backend/drivers/cswordbiblemoduleinfo.h index 2780558..40ec8cb 100644 --- a/src/backend/drivers/cswordbiblemoduleinfo.h +++ b/src/backend/drivers/cswordbiblemoduleinfo.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,110 +17,102 @@ /** - * This is the CModuleInfo imlementation for Bible modules managed by Sword. - * - * @short Implementation for Sword Bibles - * @author The BibleTime team - * @version $Id: cswordbiblemoduleinfo.h,v 1.18 2006/02/25 11:38:15 joachim Exp $ - */ + \brief Implementation for Sword Bibles. -class CSwordBibleModuleInfo : public CSwordModuleInfo { + This is the CModuleInfo imlementation for Bible modules managed by Sword. +*/ +class CSwordBibleModuleInfo: public CSwordModuleInfo { + Q_OBJECT - public: + public: /* Types: */ enum Testament { OldTestament = 1, NewTestament = 2 }; + public: /* Methods: */ + CSwordBibleModuleInfo(sword::SWModule *module, CSwordBackend * const, + ModuleType type = Bible); + CSwordBibleModuleInfo(const CSwordBibleModuleInfo ©); + + /* Reimplementation of CSwordModuleInfo::clone(). */ + virtual inline CSwordModuleInfo *clone() const { + return new CSwordBibleModuleInfo(*this); + } + + inline ~CSwordBibleModuleInfo() { + delete m_bookList; + } + /** - * The constructor of this class + \returns the number of avalable verses for the given chapter and book. + \param book The number book we should use + \param chapter The chapter we should use */ - CSwordBibleModuleInfo( sword::SWModule* module, CSwordBackend* const ); - /** The copy constructor for this Bible module. - */ - CSwordBibleModuleInfo( const CSwordBibleModuleInfo& m ); + unsigned int verseCount(const unsigned int book, + const unsigned int chapter) const; + /** - * The destructor of this class + \returns the number of avalable verses for the given chapter and book. + \param book The name of the book we use + \param chapter The number of the chapter we use */ - ~CSwordBibleModuleInfo(); + unsigned int verseCount(const QString &book, + const unsigned int chapter) const; + /** - * Returns the number of avalable verses for the given chapter and book. - * - * @param book The number book we should use - * @param chapter The chapter we should use - * @return The number of verses for the given book and chapter + \returns the number of available chapters in the given book. */ - virtual unsigned int verseCount( const unsigned int book, const unsigned int chapter ); + unsigned int chapterCount(const unsigned int book) const; + /** - * Returns the number of avalable verses for the given chapter and book. - * - * @param book The name of the book we use - * @param chapter The number of the chapter we use - * @return The number of verses for the given book and chapter - */ - virtual unsigned int verseCount( const QString& book, const unsigned int chapter ); - /** Information about the chapters in a book. - * @return The number of available chapters of the given book. - * @return The number of chapters for the given book - */ - virtual unsigned int chapterCount( const unsigned int book ); - /** Information about the chapters in a book. - * @return The number of available chapters of the given book. + \returns the number of available chapters in the given book. */ - virtual unsigned int chapterCount( const QString& book ); - /** Return all book of this module. - * @return A QStringList containing the books which are available in this module. - */ - virtual QStringList* books(); + unsigned int chapterCount(const QString &book) const; + /** - * Reimplementation, Returns the type + \returns a QStringList containing the books available in this module. */ - virtual CSwordModuleInfo::ModuleType type() const; + QStringList *books() const; + /** - * @return the book number, values starting with 1; 0 if not found + \returns the index of the book given by its name. + \retval 0 if a book with the given name was not found. */ - unsigned int bookNumber(const QString &book); + unsigned int bookNumber(const QString &book) const; + /** - * Returns true if his module has the text of desired type of testament + \returns whether this module has the text of desired type of testament */ - bool hasTestament( CSwordBibleModuleInfo::Testament ); - /** Reimplementation to clone this object. */ - virtual CSwordModuleInfo* clone(); + bool hasTestament(CSwordBibleModuleInfo::Testament type) const { + return type == OldTestament ? m_hasOT : m_hasNT; + } + /** - * Returns the key which represents the lower bound of this module. + \returns the key which represents the lower bound of this module. */ - inline const CSwordVerseKey& lowerBound(); + inline const CSwordVerseKey &lowerBound() const { + return m_lowerBound; + } + /** - * Returns the key which represents the upper bound of this module. + \returns the key which represents the upper bound of this module. */ - inline const CSwordVerseKey& upperBound(); + inline const CSwordVerseKey &upperBound() const { + return m_upperBound; + } - private: + private: /* Methods: */ void initBounds(); + private: CSwordVerseKey m_lowerBound; CSwordVerseKey m_upperBound; - QStringList* m_bookList; //This booklist is cached - QString m_cachedLocale; - short int m_hasOT; - short int m_hasNT; + mutable QStringList *m_bookList; //This booklist is cached + mutable QString m_cachedLocale; + bool m_hasOT; + bool m_hasNT; }; -inline CSwordModuleInfo::ModuleType CSwordBibleModuleInfo::type() const { - return CSwordModuleInfo::Bible; -} - -/** Returns the key which represents the lower bound of this module. */ -inline const CSwordVerseKey& CSwordBibleModuleInfo::lowerBound() { - initBounds(); - return m_lowerBound; -} - -/** Returns the key which represents the lower bound of this module. */ -inline const CSwordVerseKey& CSwordBibleModuleInfo::upperBound() { - initBounds(); - return m_upperBound; -} - #endif diff --git a/src/backend/drivers/cswordbookmoduleinfo.cpp b/src/backend/drivers/cswordbookmoduleinfo.cpp index 6371de1..8c6b8b1 100644 --- a/src/backend/drivers/cswordbookmoduleinfo.cpp +++ b/src/backend/drivers/cswordbookmoduleinfo.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,33 +16,22 @@ #include -CSwordBookModuleInfo::CSwordBookModuleInfo( sword::SWModule* module, CSwordBackend* const usedBackend ) - : CSwordModuleInfo(module, usedBackend), - m_depth(-1) {} - -CSwordBookModuleInfo::CSwordBookModuleInfo( const CSwordBookModuleInfo& module ) - : CSwordModuleInfo(module) { - m_depth = module.m_depth; -} - -CSwordBookModuleInfo::~CSwordBookModuleInfo() {} - -int CSwordBookModuleInfo::depth() { - if (m_depth == -1) { - sword::TreeKeyIdx* key = tree(); - - if (key) { - key->root(); - computeDepth(key, 0); - } +CSwordBookModuleInfo::CSwordBookModuleInfo(sword::SWModule *module, + CSwordBackend * const usedBackend) + : CSwordModuleInfo(module, usedBackend, + CSwordModuleInfo::GenericBook), + m_depth(-1) +{ + sword::TreeKeyIdx *key = tree(); + if (key) { + key->root(); + computeDepth(key, 0); } - - return m_depth; } -void CSwordBookModuleInfo::computeDepth(sword::TreeKeyIdx* key, int level ) { +void CSwordBookModuleInfo::computeDepth(sword::TreeKeyIdx *key, int level) { std::string savedKey; - // savedKey = key->getFullName(); //sword 1.5.8 + // savedKey = key->getFullName(); //sword 1.5.8 savedKey = key->getText(); if (level > m_depth) { diff --git a/src/backend/drivers/cswordbookmoduleinfo.h b/src/backend/drivers/cswordbookmoduleinfo.h index 77adb29..12a3d01 100644 --- a/src/backend/drivers/cswordbookmoduleinfo.h +++ b/src/backend/drivers/cswordbookmoduleinfo.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,50 +16,48 @@ #include -/** Class for generic book support - * @author The BibleTime team - */ +/** + \brief Class for generic book support +*/ +class CSwordBookModuleInfo: public CSwordModuleInfo { + Q_OBJECT -class CSwordBookModuleInfo : public CSwordModuleInfo { - - public: - /** Constructor. - * @param module The module which belongs to this object - * @param backend The parent backend for this book module. - */ - CSwordBookModuleInfo( sword::SWModule* module, CSwordBackend* const backend ); - /** Copy constructor. - * Copy constructor to copy the passed parameter. - * @param module The module which should be copied. - */ - CSwordBookModuleInfo( const CSwordBookModuleInfo& module ); - /** Destructor. - */ - ~CSwordBookModuleInfo(); + public: /* Methods: */ /** - * Returns the type of the module. + \param module The module which belongs to this object + \param backend The parent backend for this book module. */ - virtual CSwordModuleInfo::ModuleType type() const; + CSwordBookModuleInfo(sword::SWModule *module, + CSwordBackend * const usedBackend); + + inline CSwordBookModuleInfo(const CSwordBookModuleInfo ©) + : CSwordModuleInfo(copy), m_depth(copy.m_depth) {} + + /* Reimplementation of CSwordModuleInfo::clone(). */ + virtual inline CSwordModuleInfo *clone() const { + return new CSwordBookModuleInfo(*this); + } + /** - * Returns the maximal depth of sections and subsections. + \returns the maximal depth of sections and subsections. */ - int depth(); + inline int depth() const { return m_depth; } + /** - * @return A treekey filled with the structure of this module. Don't delete the returned key because it's casted from the module object. + \returns A treekey filled with the structure of this module. Don't + delete the returned key because it's casted from the module + object. */ - sword::TreeKeyIdx* tree() const; + sword::TreeKeyIdx *tree() const; - private: + private: /* Methods: */ /** * A recursive helper function to help computng the module depth! */ - void computeDepth(sword::TreeKeyIdx* key, int level = 0 ); + void computeDepth(sword::TreeKeyIdx *key, int level = 0); + + private: /* Fields: */ int m_depth; }; -inline CSwordBookModuleInfo::ModuleType CSwordBookModuleInfo::type() const { - return CSwordModuleInfo::GenericBook; -} - - #endif diff --git a/src/backend/drivers/cswordcommentarymoduleinfo.cpp b/src/backend/drivers/cswordcommentarymoduleinfo.cpp index 8b74ffa..07e09d2 100644 --- a/src/backend/drivers/cswordcommentarymoduleinfo.cpp +++ b/src/backend/drivers/cswordcommentarymoduleinfo.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,24 +10,11 @@ #include "backend/drivers/cswordcommentarymoduleinfo.h" -CSwordCommentaryModuleInfo::CSwordCommentaryModuleInfo( sword::SWModule* module, CSwordBackend* const usedBackend) - : CSwordBibleModuleInfo(module, usedBackend) {} - -CSwordCommentaryModuleInfo::~CSwordCommentaryModuleInfo() {} - -/** No descriptions */ -CSwordModuleInfo* CSwordCommentaryModuleInfo::clone() { - return new CSwordCommentaryModuleInfo(*this); -} - -/** Returns true if this module may be written by the write display windows. */ bool CSwordCommentaryModuleInfo::isWritable() const { - // qWarning(module()->getConfigEntry("ModDrv")); - //a module is only writable if it's a RawFiles module with writable returning true - - if ( (std::string(module()->getConfigEntry("ModDrv")) == std::string("RawFiles")) && module()->isWritable()) { - return true; - }; - - return false; + /* + A module is only writable if it's a RawFiles module with writable + returning true. + */ + return std::string(module()->getConfigEntry("ModDrv")) == "RawFiles" + && module()->isWritable(); } diff --git a/src/backend/drivers/cswordcommentarymoduleinfo.h b/src/backend/drivers/cswordcommentarymoduleinfo.h index a297538..60640a2 100644 --- a/src/backend/drivers/cswordcommentarymoduleinfo.h +++ b/src/backend/drivers/cswordcommentarymoduleinfo.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,31 +13,27 @@ #include "backend/drivers/cswordbiblemoduleinfo.h" -/** Commentary module implementation. - * This CSwordModule implementation provides access to Sword's commentary modules. - * @author The BibleTime team - * @version $Id: cswordcommentarymoduleinfo.h,v 1.13 2006/02/25 11:38:15 joachim Exp $ - */ - -class CSwordCommentaryModuleInfo : public CSwordBibleModuleInfo { - - public: - CSwordCommentaryModuleInfo( sword::SWModule* module, CSwordBackend* const ); - ~CSwordCommentaryModuleInfo(); - /** Reimplementation to return the commentary type. - */ - virtual CSwordModuleInfo::ModuleType type() const; - /** Reimplementation to clone the current object. - */ - virtual CSwordModuleInfo* clone(); - /** - * Returns true if this module may be written by the write display windows. - */ +/** + \brief Commentary module implementation. + + This CSwordModule implementation provides access to Sword's commentary modules. +*/ +class CSwordCommentaryModuleInfo: public CSwordBibleModuleInfo { + Q_OBJECT + + public: /* Methods: */ + inline CSwordCommentaryModuleInfo(sword::SWModule *module, + CSwordBackend * const usedBackend) + : CSwordBibleModuleInfo(module, usedBackend, + CSwordModuleInfo::Commentary) {} + + /* Reimplementation of CSwordModuleInfo::clone(). */ + virtual inline CSwordModuleInfo* clone() const { + return new CSwordCommentaryModuleInfo(*this); + } + + /* Reimplementation of CSwordModuleInfo::isWritable(). */ virtual bool isWritable() const; }; -inline CSwordModuleInfo::ModuleType CSwordCommentaryModuleInfo::type() const { - return CSwordModuleInfo::Commentary; -} - #endif diff --git a/src/backend/drivers/cswordlexiconmoduleinfo.cpp b/src/backend/drivers/cswordlexiconmoduleinfo.cpp index c4a04de..d6515be 100644 --- a/src/backend/drivers/cswordlexiconmoduleinfo.cpp +++ b/src/backend/drivers/cswordlexiconmoduleinfo.cpp @@ -2,14 +2,13 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "backend/drivers/cswordlexiconmoduleinfo.h" -#include #include #include #include @@ -24,45 +23,23 @@ //Change it once the format changed to make all systems rebuild their caches #define CACHE_FORMAT "3" -CSwordLexiconModuleInfo::CSwordLexiconModuleInfo( sword::SWModule* module, CSwordBackend* const backend ) : CSwordModuleInfo(module, backend) { - m_entryList = 0; -} - -CSwordLexiconModuleInfo::CSwordLexiconModuleInfo( const CSwordLexiconModuleInfo& m ) : CSwordModuleInfo(m) { - delete m_entryList; - m_entryList = 0; - - if (m.m_entryList) { - m_entryList = new QStringList(); - *m_entryList = *m.m_entryList;//copy list items - } -} - -CSwordLexiconModuleInfo::~CSwordLexiconModuleInfo() { - delete m_entryList; - m_entryList = 0; -} - -/** Returns the entries of the module. */ -QStringList* CSwordLexiconModuleInfo::entries() { +const QStringList &CSwordLexiconModuleInfo::entries() const { namespace DU = util::directory; - if (!module()) { - return 0; + // If cache is ok, just return it: + if (!m_entries.empty()) { + return m_entries; } - if (m_entryList) return m_entryList; - - m_entryList = new QStringList(); - + // Initialize cache: //Check for buggy modules! They will not be loaded any more. if ( name() == QString("ZhEnglish")) { qWarning() << "Module ZhEnglish is buggy and will not be loaded."; - return m_entryList; + return m_entries; } if ( name() == QString("EReo_en")) { qWarning() << "Module EReo_en is buggy and will not be loaded."; - return m_entryList; + return m_entries; } QString dir(DU::getUserCacheDir().absolutePath()); @@ -88,11 +65,11 @@ QStringList* CSwordLexiconModuleInfo::entries() { if (ModuleVersion == config(CSwordModuleInfo::ModuleVersion) && CacheVersion == CACHE_FORMAT && QDataStreamVersion == QString::number(s.version())) { - s >> *m_entryList; + s >> m_entries; f1.close(); - qDebug() << "Read" << m_entryList->count() << "entries from lexicon cache for module" << name(); - return m_entryList; + qDebug() << "Read" << m_entries.count() << "entries from lexicon cache for module" << name(); + return m_entries; } f1.close(); @@ -103,40 +80,37 @@ QStringList* CSwordLexiconModuleInfo::entries() { */ qDebug() << "Read all entries of lexicon" << name(); - sword::SWModule* my_module = module(); - my_module->setSkipConsecutiveLinks(true); - (*my_module) = sword::TOP; + module()->setSkipConsecutiveLinks(true); + module()->setPosition(sword::TOP); snap(); //snap to top entry do { if ( isUnicode() ) { - m_entryList->append(QString::fromUtf8(my_module->KeyText())); + m_entries.append(QString::fromUtf8(module()->KeyText())); } else { //for latin1 modules use fromLatin1 because of speed QTextCodec* codec = QTextCodec::codecForName("Windows-1252"); - m_entryList->append(codec->toUnicode(my_module->KeyText())); + m_entries.append(codec->toUnicode(module()->KeyText())); } - (*my_module)++; - } - while ( !my_module->Error() ); - - (*my_module) = sword::TOP; //back to the first entry + module()->increment(); + } while (!module()->Error()); - my_module->setSkipConsecutiveLinks(false); + module()->setPosition(sword::TOP); // back to the first entry + module()->setSkipConsecutiveLinks(false); - if (m_entryList->count()) { - m_entryList->first().simplified(); + if (m_entries.count()) { + m_entries.first().simplified(); - if (m_entryList->first().trimmed().isEmpty()) { - m_entryList->erase( m_entryList->begin() ); + if (m_entries.first().trimmed().isEmpty()) { + m_entries.erase( m_entries.begin() ); } } qDebug() << "Writing cache file for lexicon module" << name(); - if (m_entryList->count()) { + if (m_entries.count()) { //create cache QString dir(DU::getUserCacheDir().absolutePath()); QFile f2( QString(dir).append("/").append(name()) ); @@ -146,24 +120,10 @@ QStringList* CSwordLexiconModuleInfo::entries() { s << config(CSwordModuleInfo::ModuleVersion) //store module version << QString(CACHE_FORMAT) //store BT version -- format may change << QString::number(s.version()) //store QDataStream version -- format may change - << *m_entryList; + << m_entries; f2.close(); } } - return m_entryList; -} - -/** Jumps to the closest entry in the module. */ -bool CSwordLexiconModuleInfo::snap() { - if (module()->getRawEntry()) { // Snap to the current entry - return true; - } - - return false; -} - -/** No descriptions */ -CSwordModuleInfo* CSwordLexiconModuleInfo::clone() { - return new CSwordLexiconModuleInfo(*this); + return m_entries; } diff --git a/src/backend/drivers/cswordlexiconmoduleinfo.h b/src/backend/drivers/cswordlexiconmoduleinfo.h index 36d30fb..d75e106 100644 --- a/src/backend/drivers/cswordlexiconmoduleinfo.h +++ b/src/backend/drivers/cswordlexiconmoduleinfo.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,55 +16,46 @@ /** - * The implementation of CModuleInfo for the Sword lexiccons and citionaries. - * @author The BibleTime team - * @version $Id: cswordlexiconmoduleinfo.h,v 1.12 2006/02/25 11:38:15 joachim Exp $ - */ + The implementation of CModuleInfo for the Sword lexiccons and citionaries. +*/ +class CSwordLexiconModuleInfo: public CSwordModuleInfo { + Q_OBJECT -class CSwordLexiconModuleInfo : public CSwordModuleInfo { + public: /* Methods: */ + inline CSwordLexiconModuleInfo(sword::SWModule *module, + CSwordBackend * const backend) + : CSwordModuleInfo(module, backend, Lexicon) {} + + inline CSwordLexiconModuleInfo(const CSwordLexiconModuleInfo ©) + : CSwordModuleInfo(copy), m_entries(copy.m_entries) {} + + /* Reimplementation of CSwordModuleInfo::clone(). */ + virtual inline CSwordModuleInfo *clone() const { + return new CSwordLexiconModuleInfo(*this); + } - public: - /** - * The standard constructor fot this object. - * A default constructor doesn't exist. Use this one. - */ - CSwordLexiconModuleInfo( sword::SWModule* module, CSwordBackend* const ); - /** - * The copy constructor - */ - CSwordLexiconModuleInfo( const CSwordLexiconModuleInfo& m ); - /** Reimplementation to return a valid clone. - */ - virtual CSwordModuleInfo* clone(); - /** Destructor. - */ - virtual ~CSwordLexiconModuleInfo(); - /** - * Returns the entries of the module. - * This function returns the entries of the modules represented by this object. - * If this function is called for the first time the list is load from disk and stored in a list which cahes it. - * If the function is called again, the cached list is returned so we have a major speed improvement. - * @return The list of lexicon entries - */ - QStringList* entries(); /** - * Reimplementation, to return the right type for this lexicon. + This method returns the entries of the modules represented by this + object. If this function is called for the first time the list is load + from disk and stored in a list which cahes it. If the function is + called again, the cached list is returned so we have a major speed + improvement. + \returns the list of lexicon entries in the module. */ - virtual CSwordModuleInfo::ModuleType type() const; + const QStringList &entries() const; + /** - * Jumps to the closest entry in the module. + Jumps to the closest entry in the module. */ - bool snap(); + virtual inline bool snap() const { + return module()->getRawEntry(); + } - private: + private: /* Fields: */ /** - * This is the list which caches the entres of the module. + This is the list which caches the entres of the module. */ - QStringList* m_entryList; + mutable QStringList m_entries; }; -inline CSwordModuleInfo::ModuleType CSwordLexiconModuleInfo::type() const { - return CSwordModuleInfo::Lexicon; -} - #endif diff --git a/src/backend/drivers/cswordmoduleinfo.cpp b/src/backend/drivers/cswordmoduleinfo.cpp index 6096af2..b1e646f 100644 --- a/src/backend/drivers/cswordmoduleinfo.cpp +++ b/src/backend/drivers/cswordmoduleinfo.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "backend/drivers/cswordmoduleinfo.h" -#include +#include #include #include #include @@ -28,8 +28,9 @@ #include "backend/managers/cswordbackend.h" #include "backend/rendering/centrydisplay.h" #include "backend/cswordmodulesearch.h" +#include "btglobal.h" +#include "util/cresmgr.h" #include "util/directory.h" -#include "util/cpointers.h" #include "util/exceptions.h" #include "util/dialogutil.h" @@ -42,6 +43,29 @@ #include +#ifdef BT_DEBUG +namespace { + +/** HELPER Method to dump all current EntryAttributes of a module. */ +void dumpEntryAttributes(sword::SWModule *m) { + qDebug() << "Attributes for key: " << m->getKeyText(); + sword::AttributeTypeList::iterator i1; + sword::AttributeList::iterator i2; + sword::AttributeValue::iterator i3; + for (i1 = m->getEntryAttributes().begin(); i1 != m->getEntryAttributes().end(); i1++) { + qDebug() << "[ " << i1->first << " ]"; + for (i2 = i1->second.begin(); i2 != i1->second.end(); i2++) { + qDebug() << "\t[ " << i2->first << " ]"; + for (i3 = i2->second.begin(); i3 != i2->second.end(); i3++) { + qDebug() << "\t\t" << i3->first << " = " << i3->second; + } + } + } +} + +} // anonymous namespace +#endif + //Increment this, if the index format changes //Then indices on the user's systems will be rebuilt const unsigned int INDEX_VERSION = 7; @@ -50,69 +74,76 @@ const unsigned int INDEX_VERSION = 7; //Lucene default is too small const unsigned long BT_MAX_LUCENE_FIELD_LENGTH = 1024 * 1024; -CSwordModuleInfo::CSwordModuleInfo(sword::SWModule * module, CSwordBackend * const usedBackend) { - m_module = module; - Q_ASSERT(module); +CSwordModuleInfo::CSwordModuleInfo(sword::SWModule *module, + CSwordBackend * const usedBackend, + ModuleType type) + : m_module(module), + m_backend(usedBackend ? usedBackend : CSwordBackend::instance()), + m_type(type), + m_cancelIndexing(false), + m_cachedName(QString::fromUtf8(module->Name())), + m_cachedHasVersion(!QString((*m_backend->getConfig())[module->Name()]["Version"]).isEmpty()) +{ + Q_ASSERT(module != 0); + Q_ASSERT(usedBackend != 0); + + initCachedCategory(); + initCachedLanguage(); - m_cancelIndexing = false; - m_searchResult.ClearList(); - m_backend = usedBackend ? usedBackend : CPointers::backend(); - m_dataCache.name = module ? QString(module->Name()) : QString::null; - m_dataCache.isUnicode = module ? module->isUnicode() : false; - m_dataCache.category = UnknownCategory; - m_dataCache.language = 0; - m_dataCache.hasVersion = !QString((*m_backend->getConfig())[module->Name()]["Version"]).isEmpty(); m_hidden = CBTConfig::get(CBTConfig::hiddenModules).contains(name()); if (backend()) { if (hasVersion() && (minimumSwordVersion() > sword::SWVersion::currentVersion)) { qWarning("The module \"%s\" requires a newer Sword library. Please update to \"Sword %s\".", name().toUtf8().constData(), (const char *)minimumSwordVersion()); + + /// \todo if this is the case, can we use the module at all? } } } -CSwordModuleInfo::CSwordModuleInfo(const CSwordModuleInfo & m) : QObject() { - m_module = m.m_module; - m_backend = m.m_backend; - m_dataCache = m.m_dataCache; - m_searchResult = m.m_searchResult; - m_hidden = m.m_hidden; - m_cancelIndexing = m.m_cancelIndexing; +CSwordModuleInfo::CSwordModuleInfo(const CSwordModuleInfo &o) + : QObject(0), m_module(o.m_module), m_backend(o.m_backend), + m_type(o.m_type), m_hidden(o.m_hidden), + m_cancelIndexing(o.m_cancelIndexing), m_cachedName(o.m_cachedName), + m_cachedCategory(o.m_cachedCategory), + m_cachedLanguage(o.m_cachedLanguage), + m_cachedHasVersion(o.m_cachedHasVersion) +{ + // Intentionally empty } -/** No descriptions */ -CSwordModuleInfo *CSwordModuleInfo::clone() { - return new CSwordModuleInfo(*this); -} - -CSwordModuleInfo::~CSwordModuleInfo() { - m_searchResult.ClearList(); - m_module = 0; //the Sword module object is deleted by the backend -} - -/** Sets the unlock key of the modules and writes the key into the cofig file.*/ bool CSwordModuleInfo::unlock(const QString & unlockKey) { if (!isEncrypted()) { return false; } + bool unlocked = unlockKeyIsValid(); + CBTConfig::setModuleEncryptionKey(name(), unlockKey); + + /// \todo remove this comment once it is no longer needed + /* There is currently a deficiency in sword 1.6.1 in that backend->setCipherKey() does + * not work correctly for modules from which data was already fetched. Therefore we have to + * reload the modules in bibletime.cpp + */ backend()->setCipherKey(m_module->Name(), unlockKey.toUtf8().constData()); + /// \todo write to Sword config as well + if (unlockKeyIsValid() != unlocked) { + emit unlockedChanged(!unlocked); + } return true; } -/** This function returns true if this module is locked, otherwise return false. */ -bool CSwordModuleInfo::isLocked() { +bool CSwordModuleInfo::isLocked() const { //still works, but the cipherkey is stored in CBTConfig. //Works because it is set in sword on program startup. return isEncrypted() && !unlockKeyIsValid(); } -/** This functions returns true if this module is encrypted (locked or unlocked). */ bool CSwordModuleInfo::isEncrypted() const { /** * If we have the CipherKey entry the module @@ -120,22 +151,18 @@ bool CSwordModuleInfo::isEncrypted() const { */ //This code is still right, though we do no longer write to the module config files any more - sword::ConfigEntMap config = backend()->getConfig()->Sections.find(name().toUtf8().constData())->second; + std::map < sword::SWBuf, sword::ConfigEntMap, std::less < sword::SWBuf > >::iterator SectionMapIter; + SectionMapIter = backend()->getConfig()->Sections.find(name().toUtf8().constData()); + if (SectionMapIter == backend()->getConfig()->Sections.end()) + return false; + sword::ConfigEntMap config = SectionMapIter->second; sword::ConfigEntMap::iterator it = config.find("CipherKey"); return it != config.end(); } -/** This function makes an estimate if a module was properly unlocked. -* It returns true if the first entry of the module is not empty and -* contains only printable characters (for the first 100 chars or so). -* If that is the case, we can safely assume that a) the module was properly -* unlocked and b) no buffer overflows will occur, which can happen when -* Sword filters process garbage text which was not properly decrypted. -*/ -bool CSwordModuleInfo::unlockKeyIsValid() { - - (*m_module) = sword::TOP; +bool CSwordModuleInfo::unlockKeyIsValid() const { + m_module->setPosition(sword::TOP); // This needs to use ::fromLatin1 because if the text is still locked, // a lot of garbage will show up. It will also work with properly decrypted @@ -146,18 +173,15 @@ bool CSwordModuleInfo::unlockKeyIsValid() { : QString::fromLatin1( m_module->getRawEntryBuf().c_str() ); if (test.isEmpty()) { - qWarning() << "Unlock key of module" << name() << "is NOT valid!"; return false; } for (int i = 0; i <= test.length() && i < 100; i++) { if ( !test[i].isPrint() && !test[i].isNull() ) { - qWarning() << "Unlock key of module" << name() << "is NOT valid!"; return false; } } - qDebug() << "Unlock key of module" << name() << "is valid"; return true; } @@ -173,7 +197,7 @@ QString CSwordModuleInfo::getModuleStandardIndexLocation() const { //this for no return getModuleBaseIndexLocation() + QString("/standard"); } -bool CSwordModuleInfo::hasIndex() { +bool CSwordModuleInfo::hasIndex() const { //this will return true only //if the index exists and has correct version information for both index and module QDir d; @@ -199,25 +223,6 @@ bool CSwordModuleInfo::hasIndex() { return lucene::index::IndexReader::indexExists(getModuleStandardIndexLocation().toAscii().constData()); } -// HELPER Method: this dumps all current EntryAttributes of a module -//#include -//void dumpEntryAttributes(sword::SWModule *module) { -// std::cout << "Attributes for key: " << module->getKeyText() << std::endl; -// sword::AttributeTypeList::iterator i1; -// sword::AttributeList::iterator i2; -// sword::AttributeValue::iterator i3; -// for (i1 = module->getEntryAttributes().begin(); i1 != module->getEntryAttributes().end(); i1++) { -// std::cout << "[ " << i1->first << " ]\n"; -// for (i2 = i1->second.begin(); i2 != i1->second.end(); i2++) { -// std::cout << "\t[ " << i2->first << " ]\n"; -// for (i3 = i2->second.begin(); i3 != i2->second.end(); i3++) { -// std::cout << "\t\t" << i3->first << " = " << i3->second << "\n"; -// } -// } -// } -// std::cout << std::endl; -//} - void CSwordModuleInfo::buildIndex() { m_cancelIndexing = false; @@ -252,14 +257,14 @@ void CSwordModuleInfo::buildIndex() { } } - boost::scoped_ptr writer( new lucene::index::IndexWriter(index.toAscii().constData(), &an, true) ); //always create a new index + QSharedPointer writer( new lucene::index::IndexWriter(index.toAscii().constData(), &an, true) ); //always create a new index writer->setMaxFieldLength(BT_MAX_LUCENE_FIELD_LENGTH); writer->setUseCompoundFile(true); //merge segments into a single file writer->setMinMergeDocs(1000); - *m_module = sword::TOP; + m_module->setPosition(sword::TOP); unsigned long verseLowIndex = m_module->Index(); - *m_module = sword::BOTTOM; + m_module->setPosition(sword::BOTTOM); unsigned long verseHighIndex = m_module->Index(); //verseLowIndex is not 0 in all cases (i.e. NT-only modules) @@ -271,7 +276,7 @@ void CSwordModuleInfo::buildIndex() { if (type() == CSwordModuleInfo::Lexicon) { verseIndex = 0; verseLowIndex = 0; - verseSpan = ((CSwordLexiconModuleInfo*)this)->entries()->size(); + verseSpan = ((CSwordLexiconModuleInfo*)this)->entries().size(); } emit indexingProgress(0); @@ -296,14 +301,15 @@ void CSwordModuleInfo::buildIndex() { wchar_t wcharBuffer[BT_MAX_LUCENE_FIELD_LENGTH + 1]; - for (*m_module = sword::TOP; !(m_module->Error()) && !m_cancelIndexing; (*m_module)++) { + m_module->setPosition(sword::TOP); + while (!(m_module->Error()) && !m_cancelIndexing) { // Also index Chapter 0 and Verse 0, because they might have information in the entry attributes // We used to just put their content into the textBuffer and continue to the next verse, but // with entry attributes this doesn't work any more. // Hits in the search dialog will show up as 1:1 (instead of 0) - boost::scoped_ptr doc(new lucene::document::Document()); + QSharedPointer doc(new lucene::document::Document()); //index the key lucene_utf8towcs(wcharBuffer, key->getText(), BT_MAX_LUCENE_FIELD_LENGTH); @@ -357,7 +363,7 @@ void CSwordModuleInfo::buildIndex() { } } // for attListI - writer->addDocument(doc.get()); + writer->addDocument(doc.data()); //Index() is not implemented properly for lexicons, so we use a //workaround. if (type() == CSwordModuleInfo::Lexicon) { @@ -380,7 +386,9 @@ void CSwordModuleInfo::buildIndex() { //m_indexingProgress.activate(); emit indexingProgress(indexingProgressValue); } - } + + m_module->increment(); + } // while (!(m_module->Error()) && !m_cancelIndexing) if (!m_cancelIndexing) { writer->optimize(); @@ -421,20 +429,23 @@ unsigned long CSwordModuleInfo::indexSize() const { } -bool CSwordModuleInfo::searchIndexed(const QString& searchedText, sword::ListKey& scope) { +int CSwordModuleInfo::searchIndexed(const QString &searchedText, + const sword::ListKey &scope, + sword::ListKey &results) const +{ char utfBuffer[BT_MAX_LUCENE_FIELD_LENGTH + 1]; wchar_t wcharBuffer[BT_MAX_LUCENE_FIELD_LENGTH + 1]; // work around Swords thread insafety for Bibles and Commentaries - boost::scoped_ptr < CSwordKey > key(CSwordKey::createInstance(this)); - sword::SWKey* s = dynamic_cast < sword::SWKey * >(key.get()); + QSharedPointer < CSwordKey > key(CSwordKey::createInstance(this)); + sword::SWKey* s = dynamic_cast < sword::SWKey * >(key.data()); QList list; if (s) { m_module->SetKey(*s); } - m_searchResult.ClearList(); + results.ClearList(); try { // do not use any stop words @@ -442,15 +453,16 @@ bool CSwordModuleInfo::searchIndexed(const QString& searchedText, sword::ListKey lucene::analysis::standard::StandardAnalyzer analyzer( stop_words ); lucene::search::IndexSearcher searcher(getModuleStandardIndexLocation().toAscii().constData()); lucene_utf8towcs(wcharBuffer, searchedText.toUtf8().constData(), BT_MAX_LUCENE_FIELD_LENGTH); - boost::scoped_ptr q( lucene::queryParser::QueryParser::parse((const TCHAR*)wcharBuffer, (const TCHAR*)_T("content"), &analyzer) ); + QSharedPointer q( lucene::queryParser::QueryParser::parse((const TCHAR*)wcharBuffer, (const TCHAR*)_T("content"), &analyzer) ); - boost::scoped_ptr h( searcher.search(q.get(), lucene::search::Sort::INDEXORDER) ); + QSharedPointer h( searcher.search(q.data(), lucene::search::Sort::INDEXORDER) ); - const bool useScope = (scope.Count() > 0); -// const bool isVerseModule = (type() == CSwordModuleInfo::Bible) || (type() == CSwordModuleInfo::Commentary); + /// \warning This is a workaround for Sword constness + const bool useScope = (const_cast(scope).Count() > 0); +// const bool isVerseModule = (type() == CSwordModuleInfo::Bible) || (type() == CSwordModuleInfo::Commentary); lucene::document::Document* doc = 0; - boost::scoped_ptr swKey( module()->CreateKey() ); + QSharedPointer swKey( module()->CreateKey() ); for (int i = 0; i < h->length(); ++i) { @@ -462,46 +474,34 @@ bool CSwordModuleInfo::searchIndexed(const QString& searchedText, sword::ListKey // limit results based on scope //if (searchOptions & CSwordModuleSearch::useScope && scope.Count() > 0){ if (useScope) { - for (int j = 0; j < scope.Count(); j++) { - sword::VerseKey* vkey = dynamic_cast(scope.getElement(j)); + /// \warning This is a workaround for sword constness + for (int j = 0; j < const_cast(scope).Count(); j++) { + /// \warning This is a workaround for sword constness + sword::ListKey &scope2 = const_cast(scope); + sword::VerseKey* vkey = dynamic_cast(scope2.getElement(j)); if (vkey->LowerBound().compare(*swKey) <= 0 && vkey->UpperBound().compare(*swKey) >= 0) { - m_searchResult.add(*swKey); + results.add(*swKey); } } } else { // no scope, give me all buffers - m_searchResult.add(*swKey); + results.add(*swKey); } } } catch (...) { qWarning("CLucene exception occurred"); util::showWarning(0, QCoreApplication::tr("Search aborted"), QCoreApplication::tr("An internal error occurred while executing your search.")); - return false; + return 0; } qDeleteAll(list); list.clear(); - return (m_searchResult.Count() > 0); -} - -/** Returns the last search result for this module. */ -sword::ListKey & CSwordModuleInfo::searchResult(const sword::ListKey * newResult) { - if (newResult) { - m_searchResult.copyFrom(*newResult); - } - - return m_searchResult; -} - -/** Clears the last search result. */ -void CSwordModuleInfo::clearSearchResult() { - m_searchResult.ClearList(); + return results.Count(); } -/** Returns the required Sword version for this module. Returns -1 if no special Sword version is required. */ -sword::SWVersion CSwordModuleInfo::minimumSwordVersion() { +sword::SWVersion CSwordModuleInfo::minimumSwordVersion() const { return sword::SWVersion(config(CSwordModuleInfo::MinimumSwordVersion).toUtf8().constData()); } @@ -634,12 +634,11 @@ QString CSwordModuleInfo::config(const CSwordModuleInfo::ConfigEntry entry) cons } } -/** Returns true if the module supports the feature given as parameter. */ bool CSwordModuleInfo::has(const CSwordModuleInfo::Feature feature) const { switch (feature) { - // case StrongsNumbers: - // return m_module->getConfig().has("Feature", "StrongsNumber"); + // case StrongsNumbers: + // return m_module->getConfig().has("Feature", "StrongsNumber"); case GreekDef: return m_module->getConfig().has("Feature", "GreekDef"); @@ -684,25 +683,20 @@ bool CSwordModuleInfo::has(const CSwordModuleInfo::FilterTypes option) const { return false; } -/** Returns the text direction of the module's text., */ -CSwordModuleInfo::TextDirection CSwordModuleInfo::textDirection() { - if (config(TextDir) == "RtoL") { +CSwordModuleInfo::TextDirection CSwordModuleInfo::textDirection() const { + if (config(TextDir) == "RtoL") return CSwordModuleInfo::RightToLeft; - } - else { - return CSwordModuleInfo::LeftToRight; - } + + return CSwordModuleInfo::LeftToRight; } -/** Writes the new text at the given position into the module. This does only work for writable modules. */ -void CSwordModuleInfo::write(CSwordKey * key, const QString & newText) { +void CSwordModuleInfo::write(CSwordKey *key, const QString &newText) { module()->KeyText(key->key().toUtf8().constData()); //don't store a pointer to the const char* value somewhere because QCString doesn't keep the value of it module()->setEntry(isUnicode() ? newText.toUtf8().constData() : newText.toLocal8Bit().constData()); } -/** Deletes the current entry and removes it from the module. */ bool CSwordModuleInfo::deleteEntry(CSwordKey * const key) { module()->KeyText(isUnicode() ? key->key().toUtf8().constData() : key->key().toLocal8Bit().constData()); @@ -714,43 +708,48 @@ bool CSwordModuleInfo::deleteEntry(CSwordKey * const key) { return false; } -/** Returns the category of this module. See CSwordModuleInfo::Category for possible values. */ -CSwordModuleInfo::Category CSwordModuleInfo::category() const { - //qDebug() << "CSwordModuleInfo::category"; - if (m_dataCache.category == CSwordModuleInfo::UnknownCategory) { - const QString cat(m_module->getConfigEntry("Category")); - //qDebug() << "the category was unknown, add a category "<< cat << "for module" << m_module->Name(); +void CSwordModuleInfo::initCachedCategory() { + /// \todo Maybe we can use raw string comparsion instead of QString? + const QString cat(m_module->getConfigEntry("Category")); - if (cat == "Cults / Unorthodox / Questionable Material") { - m_dataCache.category = Cult; - } - else if (cat == "Daily Devotional" || m_module->getConfig().has("Feature", "DailyDevotion")) { - m_dataCache.category = DailyDevotional; - } - else if (cat == "Glossaries" || m_module->getConfig().has("Feature", "Glossary")) { //allow both - m_dataCache.category = Glossary; - } - else if (cat == "Images" || cat == "Maps") { - m_dataCache.category = Images; - } - else if (type() == Commentary) { - m_dataCache.category = Commentaries; - } - else if (type() == Bible) { - m_dataCache.category = Bibles; - } - else if (type() == Lexicon) { - m_dataCache.category = Lexicons; - } - else if (type() == GenericBook) { - m_dataCache.category = Books; + /// \warning cat has to be checked before type() !!! + if (cat == "Cults / Unorthodox / Questionable Material") { + m_cachedCategory = Cult; + } else if (cat == "Daily Devotional" + || m_module->getConfig().has("Feature","DailyDevotion")) + { + m_cachedCategory = DailyDevotional; + } else if (cat == "Glossaries" + || m_module->getConfig().has("Feature", "Glossary")) + { + m_cachedCategory = Glossary; + } else if (cat == "Images" || cat == "Maps") { + m_cachedCategory = Images; + } else { + switch (type()) { + case Bible: m_cachedCategory = Bibles; break; + case Commentary: m_cachedCategory = Commentaries; break; + case Lexicon: m_cachedCategory = Lexicons; break; + case GenericBook: m_cachedCategory = Books; break; + case Unknown: // Fall thru + default: m_cachedCategory = UnknownCategory; break; } } - //qDebug() << "assigned category: " << m_dataCache.category; - return m_dataCache.category; } -/** Returns the display object for this module. */ +void CSwordModuleInfo::initCachedLanguage() { + CLanguageMgr *lm = CLanguageMgr::instance(); + if (category() == Glossary) { + /* + Special handling for glossaries, we use the "from language" as + language for the module. + */ + m_cachedLanguage = lm->languageForAbbrev(config(GlossaryFrom)); + } else { + m_cachedLanguage = lm->languageForAbbrev(m_module->Lang()); + } +} + Rendering::CEntryDisplay * CSwordModuleInfo::getDisplay() const { return dynamic_cast < Rendering::CEntryDisplay * >(m_module->Disp()); } @@ -873,30 +872,114 @@ QString CSwordModuleInfo::aboutText() const { return text; } -/** Returns the language of the module. */ -const CLanguageMgr::Language* CSwordModuleInfo::language() const { - if (!m_dataCache.language) { - if (module()) { - if (category() == Glossary) { - //special handling for glossaries, we use the "from language" as language for the module - m_dataCache.language = (CPointers::languageMgr())->languageForAbbrev(config(GlossaryFrom)); +QIcon CSwordModuleInfo::moduleIcon(const CSwordModuleInfo *module) { + const QString &filename = moduleIconFilename(module); + if (filename.isEmpty()) return QIcon(); + return util::directory::getIcon(filename); +} + +const QString &CSwordModuleInfo::moduleIconFilename( + const CSwordModuleInfo *module) +{ + const CSwordModuleInfo::Category cat(module->category()); + switch (cat) { + case CSwordModuleInfo::Bibles: + if (module->isLocked()) { + return CResMgr::modules::bible::icon_locked; } else { - m_dataCache.language = (CPointers::languageMgr())->languageForAbbrev(module()->Lang()); + return CResMgr::modules::bible::icon_unlocked; } - } - else { - m_dataCache.language = (CPointers::languageMgr())->defaultLanguage(); //default language - } + case CSwordModuleInfo::Commentaries: + if (module->isLocked()) { + return CResMgr::modules::commentary::icon_locked; + } + else { + return CResMgr::modules::commentary::icon_unlocked; + } + case CSwordModuleInfo::Lexicons: + if (module->isLocked()) { + return CResMgr::modules::lexicon::icon_locked; + } + else { + return CResMgr::modules::lexicon::icon_unlocked; + } + case CSwordModuleInfo::Books: + if (module->isLocked()) { + return CResMgr::modules::book::icon_locked; + } + else { + return CResMgr::modules::book::icon_unlocked; + } + case CSwordModuleInfo::Cult: + case CSwordModuleInfo::Images: + case CSwordModuleInfo::DailyDevotional: + case CSwordModuleInfo::Glossary: + case CSwordModuleInfo::UnknownCategory: + default: + return categoryIconFilename(cat); } +} - return m_dataCache.language; +QIcon CSwordModuleInfo::categoryIcon(const CSwordModuleInfo::Category &category) +{ + QString filename = categoryIconFilename(category); + if (filename.isEmpty()) return QIcon(); + return util::directory::getIcon(filename); +} + +const QString &CSwordModuleInfo::categoryIconFilename( + const CSwordModuleInfo::Category &category) +{ + static const QString noFilename; + + switch (category) { + case CSwordModuleInfo::Bibles: + return CResMgr::categories::bibles::icon; + case CSwordModuleInfo::Commentaries: + return CResMgr::categories::commentaries::icon; + case CSwordModuleInfo::Books: + return CResMgr::categories::books::icon; + case CSwordModuleInfo::Cult: + return CResMgr::categories::cults::icon; + case CSwordModuleInfo::Images: + return CResMgr::categories::images::icon; + case CSwordModuleInfo::DailyDevotional: + return CResMgr::categories::dailydevotional::icon; + case CSwordModuleInfo::Lexicons: + return CResMgr::categories::lexicons::icon; + case CSwordModuleInfo::Glossary: + return CResMgr::categories::glossary::icon; + case CSwordModuleInfo::UnknownCategory: + default: + return noFilename; + } } +QString CSwordModuleInfo::categoryName( + const CSwordModuleInfo::Category &category) { + switch (category) { + case CSwordModuleInfo::Bibles: + return tr("Bibles"); + case CSwordModuleInfo::Commentaries: + return tr("Commentaries"); + case CSwordModuleInfo::Books: + return tr("Books"); + case CSwordModuleInfo::Cult: + return tr("Cults/Unorthodox"); + case CSwordModuleInfo::Images: + return tr("Maps and Images"); + case CSwordModuleInfo::DailyDevotional: + return tr("Daily Devotionals"); + case CSwordModuleInfo::Lexicons: + return tr("Lexicons and Dictionaries"); + case CSwordModuleInfo::Glossary: + return tr("Glossaries"); + default: + return tr("Unknown"); + } +} -/*! - \fn CSwordModuleInfo::getSimpleConfigEntry(char* name) -*/ QString CSwordModuleInfo::getSimpleConfigEntry(const QString& name) const { QString ret = isUnicode() ? QString::fromUtf8(m_module->getConfigEntry(name.toUtf8().constData())) @@ -933,3 +1016,4 @@ bool CSwordModuleInfo::setHidden(bool hide) { emit hiddenChanged(hide); return true; } + diff --git a/src/backend/drivers/cswordmoduleinfo.h b/src/backend/drivers/cswordmoduleinfo.h index a767c41..d7397de 100644 --- a/src/backend/drivers/cswordmoduleinfo.h +++ b/src/backend/drivers/cswordmoduleinfo.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -162,25 +162,28 @@ class CSwordModuleInfo: public QObject { */ QString config( const CSwordModuleInfo::ConfigEntry entry ) const; - CSwordModuleInfo( sword::SWModule* module, CSwordBackend* const = 0 ); - /** Copy constructor to copy the passed parameter. - * @param m The module to be copied - */ - CSwordModuleInfo( const CSwordModuleInfo& m ); - /** Reimplementation to return a valid clone. - */ - virtual CSwordModuleInfo* clone(); - /** Destructor. - */ - virtual ~CSwordModuleInfo(); + CSwordModuleInfo(sword::SWModule *module, + CSwordBackend * const = 0, + ModuleType type = Unknown); + + CSwordModuleInfo(const CSwordModuleInfo ©); + + virtual CSwordModuleInfo *clone() const = 0; + + virtual inline ~CSwordModuleInfo() {} + /** * Returns the module object so all objects can access the original Sword module. */ - sword::SWModule* module() const; + inline sword::SWModule *module() const { + return m_module; + } + /** - * Sets the unlock key of the modules and writes the key into the cofig file. - * @return True if the unlock process was succesful, if the key was wrong, or if the config file was write protected return false. + * Sets the unlock key of the modules and writes the key into the config file. + * @return True if the unlock process was succesful, if the key was +wrong, or if the config file was write protected return false. */ bool unlock( const QString& unlockKey ); /** @@ -200,99 +203,130 @@ class CSwordModuleInfo: public QObject { /** * This function returns true if this module is locked (encrypted + correct cipher key), * otherwise return false. - * \todo Make CSwordModuleInfo::isLocked() const. * @return True if this module is locked, i.e. encrypted but without a key set */ - bool isLocked(); + bool isLocked() const; - bool unlockKeyIsValid(); - /** The module version. - * @return true if this module has a version number and false if it doesn't have one. + /** + This function makes an estimate if a module was properly unlocked. It + returns true if the first entry of the module is not empty and + contains only printable characters (for the first 100 chars or so). If + that is the case, we can safely assume that a) the module was properly + unlocked and b) no buffer overflows will occur, which can happen when + Sword filters process garbage text which was not properly decrypted. */ - inline bool hasVersion() const; + bool unlockKeyIsValid() const; /** - * Returns true if the module's index has been built. + \retval true if this module has a version number + \retval false if it doesn't have a version number */ - virtual bool hasIndex(); + inline bool hasVersion() const { + return m_cachedHasVersion; + } + /** - * Returns the path to this module's index base dir + \returns true if the module's index has been built. */ - virtual QString getModuleBaseIndexLocation() const; + bool hasIndex() const; + /** - * Returns the path to this module's standard index + \returns the path to this module's index base dir */ - virtual QString getModuleStandardIndexLocation() const; - /** - * Builds a search index for this module - */ - virtual void buildIndex(); + QString getModuleBaseIndexLocation() const; + /** - * Returns index size + \returns the path to this module's standard index */ - virtual unsigned long indexSize() const; + QString getModuleStandardIndexLocation() const; + /** - * Returns true if something was found, otherwise return false. - * This function uses CLucene to perform and index based search. It also - * overwrites the variable containing the last search result. + Builds a search index for this module */ - virtual bool searchIndexed(const QString& searchedText, sword::ListKey& scope); + void buildIndex(); + /** - * Returns the last search result for this module. - * The last result is cleared by @ref search + \returns index size */ - virtual sword::ListKey& searchResult( const sword::ListKey* newResult = 0 ); + unsigned long indexSize() const; + /** - * Clears the last search result. - * This does immediately clean the last search result, - * no matter if search is in progress or not. + This function uses CLucene to perform and index based search. It also + overwrites the variable containing the last search result. + \returns the number of results found */ - void clearSearchResult(); + int searchIndexed(const QString &searchedText, + const sword::ListKey &scope, + sword::ListKey &results) const; + /** - * Returns the type of the module. + \returns the type of the module. */ - virtual CSwordModuleInfo::ModuleType type() const; + inline ModuleType type() const { + return m_type; + } + /** * Returns the required Sword version for this module. * Returns -1 if no special Sword version is required. */ - sword::SWVersion minimumSwordVersion(); + sword::SWVersion minimumSwordVersion() const; + /** - * Returns the name of the module. - * @return The name of this module. + \note The Sword library takes care of the duplicate names: _n is added + after each duplicate. + \returns The name of this module. */ - QString name() const; + inline const QString &name() const { + return m_cachedName; + } + /** * Snaps to the closest entry in the module if the current key is * not present in the data files. */ - virtual bool snap() { + virtual inline bool snap() const { return false; } - bool has( const CSwordModuleInfo::Feature ) const; - bool has( const CSwordModuleInfo::FilterTypes ) const; /** - * Returns the text direction of the module's text., + \returns whether the module supports the feature given as parameter. + */ + bool has(const CSwordModuleInfo::Feature) const; + + bool has(const CSwordModuleInfo::FilterTypes ) const; + + /** + \returns the text direction of the module's text. */ - virtual CSwordModuleInfo::TextDirection textDirection(); + CSwordModuleInfo::TextDirection textDirection() const; + /** - * Writes the new text at the given position into the module. This does only work for writabe modules. + Writes the new text at the given position into the module. This does + only work for writabe modules. */ - virtual void write( CSwordKey* key, const QString& newText ); + void write(CSwordKey *key, const QString &newText); + /** - * Deletes the current entry and removes it from the module. + Deletes the current entry and removes it from the module. */ - bool deleteEntry( CSwordKey* const key ); + bool deleteEntry(CSwordKey * const key); + /** - * Returns the language of the module. + \returns the language of the module. */ - const CLanguageMgr::Language* language() const; + inline const CLanguageMgr::Language *language() const { + return m_cachedLanguage; + } + /** - * Returns true if this module may be written by the write display windows. + \returns whether this module may be written to. */ - inline virtual bool isWritable() const; + inline virtual bool isWritable() const { + return false; + } + /** * Returns true if this module is hidden (not to be shown with other modules in certain views). */ @@ -308,9 +342,12 @@ class CSwordModuleInfo: public QObject { bool setHidden(bool hide); /** - * Returns the category of this module. See CSwordModuleInfo::Category for possible values. + \returns the category of this module. */ - CSwordModuleInfo::Category category() const; + inline CSwordModuleInfo::Category category() const { + return m_cachedCategory; + } + /** * The about text which belongs to this module. */ @@ -320,9 +357,39 @@ class CSwordModuleInfo: public QObject { * Protected because it should not be used outside of the CSword*ModuleInfo classes. */ inline bool isUnicode() const { - return m_dataCache.isUnicode; + return m_module->isUnicode(); } + /** + Returns an icon for the given module. + \param[in] module The module whose icon to return. + */ + static QIcon moduleIcon(const CSwordModuleInfo *module); + + /** + Returns the icon filename for the given module. + \param[in] module The module whose icon filename to return. + */ + static const QString &moduleIconFilename(const CSwordModuleInfo *module); + + /** + Returns an icon for the category of given module. + \param[in] module The module whose category icon to return. + */ + static QIcon categoryIcon(const CSwordModuleInfo::Category &category); + + /** + Returns the icon filename for the category of given module. + \param[in] module The module whose category icon filename to return. + */ + static const QString &categoryIconFilename(const CSwordModuleInfo::Category &category); + + /** + Returns a translated name for the given category. + \param[in] module The category whose translated name to return. + */ + static QString categoryName(const CSwordModuleInfo::Category &category); + public slots: inline void cancelIndexing() { m_cancelIndexing = true; @@ -344,66 +411,42 @@ class CSwordModuleInfo: public QObject { QString getSimpleConfigEntry(const QString& name) const; QString getFormattedConfigEntry(const QString& name) const; + private: /* Methods: */ + /** + Initializes CSwordModuleInfo::m_cachedCategory. + \pre m_module must be set + */ + void initCachedCategory(); + + /** + Initializes CSwordModuleInfo::m_cachedLanguage. + \pre CSwordModuleInfo::m_module must be set + \pre CSwordModuleInfo::m_cachedLanguage must be set + */ + void initCachedLanguage(); + signals: - void hasIndexChanged(bool); - void hiddenChanged(bool); + void hasIndexChanged(bool hasIndex); + void hiddenChanged(bool hidden); + void unlockedChanged(bool unlocked); void indexingFinished(); void indexingProgress(int); private: - sword::SWModule* m_module; - sword::ListKey m_searchResult; - - mutable struct DataCache { - DataCache() { - language = 0; - } - - QString name; - bool isUnicode; - CSwordModuleInfo::Category category; - const CLanguageMgr::Language* language; - bool hasVersion; - } - - m_dataCache; - - CSwordBackend* m_backend; - + sword::SWModule * const m_module; + CSwordBackend *m_backend; + ModuleType m_type; bool m_hidden; - bool m_cancelIndexing; + + // Cached data: + const QString m_cachedName; + CSwordModuleInfo::Category m_cachedCategory; + const CLanguageMgr::Language *m_cachedLanguage; + bool m_cachedHasVersion; }; Q_DECLARE_METATYPE(CSwordModuleInfo::Category); Q_DECLARE_OPERATORS_FOR_FLAGS(CSwordModuleInfo::Categories) -inline CSwordModuleInfo::ModuleType CSwordModuleInfo::type() const { - return CSwordModuleInfo::Unknown; -} - -inline sword::SWModule* CSwordModuleInfo::module() const { - return m_module; -} - -inline bool CSwordModuleInfo::hasVersion() const { - return m_dataCache.hasVersion; -} - - -/** -* Returns the name of the module. -* The Sword library takes care of the duplicate names: _n is added after each duplicate. -*/ -inline QString CSwordModuleInfo::name() const { - return m_dataCache.name; -} - -/** Returns true if this module may be written by the write display windows. */ -inline bool CSwordModuleInfo::isWritable() const { - return false; -} - -//#include "util/cpointers.h" - #endif diff --git a/src/backend/filters/bt_gbfhtml.cpp b/src/backend/filters/bt_gbfhtml.cpp deleted file mode 100644 index 8d6a36a..0000000 --- a/src/backend/filters/bt_gbfhtml.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "backend/filters/bt_gbfhtml.h" - -#include -#include -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" -#include "util/cpointers.h" - -// Sword includes: -#include - - -Filters::BT_GBFHTML::BT_GBFHTML() : sword::GBFHTML() { - - setEscapeStringCaseSensitive(true); - setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes - - removeTokenSubstitute("Rf"); - // addTokenSubstitute("RB", ""); //start of a footnote with embedded text - - addTokenSubstitute("FI", ""); // italics begin - addTokenSubstitute("Fi", ""); - - addTokenSubstitute("FB", ""); // bold begin - addTokenSubstitute("Fb", ""); - - addTokenSubstitute("FR", ""); - addTokenSubstitute("Fr", ""); - - addTokenSubstitute("FU", ""); // underline begin - addTokenSubstitute("Fu", ""); - - addTokenSubstitute("FO", ""); // Old Testament quote begin - addTokenSubstitute("Fo", ""); - - - addTokenSubstitute("FS", ""); // Superscript begin// Subscript begin - addTokenSubstitute("Fs", ""); - - addTokenSubstitute("FV", ""); // Subscript begin - addTokenSubstitute("Fv", ""); - - addTokenSubstitute("TT", "
"); - addTokenSubstitute("Tt", "
"); - - addTokenSubstitute("TS", "
"); - addTokenSubstitute("Ts", "
"); - - //addTokenSubstitute("PP", ""); // poetry begin - //addTokenSubstitute("Pp", ""); - - - addTokenSubstitute("Fn", ""); // font end - addTokenSubstitute("CL", "
"); // new line - addTokenSubstitute("CM", "
"); // paragraph is a non showing comment that can be changed in the front end to

if desired - - addTokenSubstitute("CG", ">"); // literal greater-than sign - addTokenSubstitute("CT", "<"); // literal less-than sign - - addTokenSubstitute("JR", ""); // right align begin - addTokenSubstitute("JC", ""); // center align begin - addTokenSubstitute("JL", ""); // align end -} - -/** No descriptions */ -char Filters::BT_GBFHTML::processText(sword::SWBuf& buf, const sword::SWKey * key, const sword::SWModule * module) { - GBFHTML::processText(buf, key, module); - - if (!module->isProcessEntryAttributes()) { - return 1; //no processing should be done, may happen in a search - } - - CSwordModuleInfo* m = CPointers::backend()->findModuleByName( module->Name() ); - - if (m && !(m->has(CSwordModuleInfo::lemmas) || m->has(CSwordModuleInfo::morphTags) || m->has(CSwordModuleInfo::strongNumbers))) { //only parse if the module has strongs or lemmas - return 1; //WARNING: Return alread here - } - - //Am Anfang schuf Gott Himmel und Erde. - //A simple word means: No entry for this word "word" - QString result; - - QString t = QString::fromUtf8(buf.c_str()); - - QRegExp tag("([.,;:]?]*>\\s*)+"); - - QStringList list; - - int lastMatchEnd = 0; - - int pos = tag.indexIn(t, 0); - - if (pos == -1) { //no strong or morph code found in this text - return 1; //WARNING: Return already here - } - - //split the text into parts which end with the GBF tag marker for strongs/lemmas - while (pos != -1) { - list.append(t.mid(lastMatchEnd, pos + tag.matchedLength() - lastMatchEnd)); - - lastMatchEnd = pos + tag.matchedLength(); - pos = tag.indexIn(t, pos + tag.matchedLength()); - } - - //append the trailing text to the list. - if (!t.right(t.length() - lastMatchEnd).isEmpty()) { - list.append(t.right(t.length() - lastMatchEnd)); - } - - //list is now a list of words with 1-n Strongs at the end, which belong to this word. - - //now create the necessary HTML in list entries and concat them to the result - tag = QRegExp("]*)>"); - tag.setMinimal(true); - - for (QStringList::iterator it = list.begin(); it != list.end(); ++it) { - QString e = (*it); //current entry to process - //qWarning(e.latin1()); - - //check if there is a word to which the strongs info belongs to. - //If yes, wrap that word with the strongs info - //If not, leave out the strongs info, because it can't be tight to a text - //Comparing the first char with < is not enough, because the tokenReplace is done already - //so there might be html tags already. - const bool textPresent = (e.trimmed().remove(QRegExp("[.,;:]")).left(2) != ""); - pos += 7; - - //skip blanks, commas, dots and stuff at the beginning, it doesn't belong to the morph code - QString rep(""); - - hasMorphAttr = isMorph; - hasLemmaAttr = !isMorph; - - int startPos = 0; - QChar c = e[startPos]; - - while ((startPos < pos) && (c.isSpace() || c.isPunct())) { - ++startPos; - - c = e[startPos]; - } - - e.insert( startPos, rep ); - tagAttributeStart = startPos + 6; //to point to the start of the attributes - pos += rep.length(); - } - else { //add the attribute to the existing tag - e.remove(pos, tag.matchedLength()); - - if (tagAttributeStart == -1) { - continue; //nothing valid found - } - - if ((!isMorph && hasLemmaAttr) || (isMorph && hasMorphAttr)) { //we append another attribute value, e.g. 3000 gets 3000|5000 - //search the existing attribute start - QRegExp attrRegExp( isMorph ? "morph=\".+(?=\")" : "lemma=\".+(?=\")" ); - attrRegExp.setMinimal(true); - const int foundPos = e.indexOf(attrRegExp, tagAttributeStart); - - if (foundPos != -1) { - e.insert(foundPos + attrRegExp.matchedLength(), QString("|").append(value)); - pos += value.length() + 1; - - hasLemmaAttr = !isMorph; - hasMorphAttr = isMorph; - } - } - else { //attribute was not yet inserted - QString attr = QString(isMorph ? "morph" : "lemma").append("=\"").append(value).append("\" "); - - e.insert(tagAttributeStart, attr); - pos += attr.length(); - - hasMorphAttr = isMorph; - hasLemmaAttr = !isMorph; - } - - //tagAttributeStart remains the same - } - - insertedTag = true; - pos = tag.indexIn(e, pos); - } - - result += e; - } - - if (list.count()) { - buf = (const char*)result.toUtf8().constData(); - } - - return 1; -} - -bool Filters::BT_GBFHTML::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { - if (!substituteToken(buf, token)) { //more than a simple replace - const unsigned int tokenLength = strlen(token); - unsigned long i; - sword::SWBuf value; - - BT_UserData* myUserData = dynamic_cast(userData); - sword::SWModule* myModule = const_cast(myUserData->module); //hack to be able to call stuff like Lang() - - if ( !strncmp(token, "WG", 2) - || !strncmp(token, "WH", 2) - || !strncmp(token, "WT", 2) ) { - buf.append('<'); - buf.append(token); - buf.append('>'); - } - else if (!strncmp(token, "RB", 2)) { - myUserData->hasFootnotePreTag = true; - buf.append(""); - } - else if (!strncmp(token, "RF", 2)) { - //we use several append calls because appendFormatted slows down filtering, which should be fast - - if (myUserData->hasFootnotePreTag) { - // qWarning("inserted footnotepre end"); - buf.append(""); - myUserData->hasFootnotePreTag = false; - } - - buf.append(" Name()); - buf.append('/'); - buf.append(myUserData->key->getShortText()); - buf.append('/'); - buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); - buf.append("\">* "); - - userData->suspendTextPassThru = true; - } - else if (!strncmp(token, "Rf", 2)) { //end of footnote - userData->suspendTextPassThru = false; - } - else if (!strncmp(token, "FN", 2)) { //the end tag is inserted in addTokenSubsitute - buf.append(""); - } - else if (!strncmp(token, "CA", 2)) { // ASCII value - buf.append( (char)atoi(&token[2]) ); - } - else { - return GBFHTML::handleToken(buf, token, userData); - } - } - - return true; -} diff --git a/src/backend/filters/bt_gbfhtml.h b/src/backend/filters/bt_gbfhtml.h deleted file mode 100644 index 45e7e59..0000000 --- a/src/backend/filters/bt_gbfhtml.h +++ /dev/null @@ -1,50 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BT_GBFHTML_H -#define BT_GBFHTML_H - -// Sword includes: -#include - - -namespace Filters { - -/** GBF to HTML filter, -* This filter converts GBF Text into HTML -*/ - -class BT_GBFHTML : public sword::GBFHTML { /*, protected CFilterTool */ - - protected: - - class BT_UserData : public sword::GBFHTML::MyUserData { - - public: - BT_UserData(const sword::SWModule *module, const sword::SWKey *key) : sword::GBFHTML::MyUserData(module, key) { - swordFootnote = 1; - hasFootnotePreTag = false; - } - - short unsigned int swordFootnote; - }; - - virtual sword::BasicFilterUserData *createUserData(const sword::SWModule* module, const sword::SWKey* key) { - return new BT_UserData(module, key); - } - - public: - BT_GBFHTML(); - virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData); - virtual char processText(sword::SWBuf& buf, const sword::SWKey*, const sword::SWModule * = 0); -}; - -} - -#endif diff --git a/src/backend/filters/bt_osishtml.cpp b/src/backend/filters/bt_osishtml.cpp deleted file mode 100644 index 7525aca..0000000 --- a/src/backend/filters/bt_osishtml.cpp +++ /dev/null @@ -1,593 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "backend/filters/bt_osishtml.h" - -#include -#include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/clanguagemgr.h" -#include "backend/managers/referencemanager.h" -#include "util/cpointers.h" - -// Sword includes: -#include -#include -#include - - -Filters::BT_OSISHTML::BT_OSISHTML() : sword::OSISHTMLHREF() { - setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes - - addTokenSubstitute("inscription", ""); - addTokenSubstitute("/inscription", ""); - - addTokenSubstitute("mentioned", ""); - addTokenSubstitute("/mentioned", ""); - -// addTokenSubstitute("divineName", ""); -// addTokenSubstitute("/divineName", ""); - - /// \todo Move that down to the real tag handling, segs without the type morph would generate incorrect markup, as the end span is always inserted -// addTokenSubstitute("seg type=\"morph\"", ""); -// addTokenSubstitute("/seg", ""); - - // OSIS tables - addTokenSubstitute("table", ""); - addTokenSubstitute("/table", "
"); - addTokenSubstitute("row", ""); - addTokenSubstitute("/row", ""); - addTokenSubstitute("cell", ""); - addTokenSubstitute("/cell", ""); - -} - -bool Filters::BT_OSISHTML::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { - // manually process if it wasn't a simple substitution - - if (!substituteToken(buf, token)) { - BT_UserData* myUserData = dynamic_cast(userData); - sword::SWModule* myModule = const_cast(myUserData->module); //hack - - sword::XMLTag tag(token); - // qWarning("found %s", token); - const bool osisQToTick = ((!userData->module->getConfigEntry("OSISqToTick")) || (strcmp(userData->module->getConfigEntry("OSISqToTick"), "false"))); - - if (!tag.getName()) { - return false; - } - - //

tag - if (!strcmp(tag.getName(), "div")) { - //handle intro - - if ((!tag.isEmpty()) && (!tag.isEndTag())) { //start tag - sword::SWBuf type( tag.getAttribute("type") ); - - if (type == "introduction") { - buf.append("
"); - } - else if (type == "chapter") { - buf.append("
"); //don't open a div here, that would lead to a broken XML structure - } - else { - buf.append("
"); - } - } - else if (tag.isEndTag()) { //end tag - buf.append("
"); - } - } - else if (!strcmp(tag.getName(), "w")) { - if ((!tag.isEmpty()) && (!tag.isEndTag())) { //start tag - const char *attrib; - const char *val; - - sword::XMLTag outTag("span"); - sword::SWBuf attrValue; - - if ((attrib = tag.getAttribute("xlit"))) { - val = strchr(attrib, ':'); - val = (val) ? (val + 1) : attrib; - outTag.setAttribute("xlit", val); - } - - if ((attrib = tag.getAttribute("gloss"))) { - val = strchr(attrib, ':'); - val = (val) ? (val + 1) : attrib; - outTag.setAttribute("gloss", val); - } - - if ((attrib = tag.getAttribute("lemma"))) { - char splitChar = '|'; - const int countSplit1 = tag.getAttributePartCount("lemma", '|'); - const int countSplit2 = tag.getAttributePartCount("lemma", ' '); /// \todo not allowed, remove soon - int count = 0; - - if (countSplit1 > countSplit2) { //| split char - splitChar = '|'; /// \todo not allowed, remove soon - count = countSplit1; - } - else { - splitChar = ' '; - count = countSplit2; - } - - int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 - attrValue = ""; - - do { - if (attrValue.length()) { - attrValue.append( '|' ); - } - - attrib = tag.getAttribute("lemma", i, splitChar); - - if (i < 0) { // to handle our -1 condition - i = 0; - } - - val = strchr(attrib, ':'); - val = (val) ? (val + 1) : attrib; - - attrValue.append(val); - } - while (++i < count); - - if (attrValue.length()) { - outTag.setAttribute("lemma", attrValue.c_str()); - } - } - - if ((attrib = tag.getAttribute("morph"))) { - char splitChar = '|'; - const int countSplit1 = tag.getAttributePartCount("morph", '|'); - const int countSplit2 = tag.getAttributePartCount("morph", ' '); /// \todo not allowed, remove soon - int count = 0; - - if (countSplit1 > countSplit2) { //| split char - splitChar = '|'; - count = countSplit1; - } - else { - splitChar = ' '; - count = countSplit2; - } - - int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 - - attrValue = ""; - - do { - if (attrValue.length()) { - attrValue.append('|'); - } - - attrib = tag.getAttribute("morph", i, splitChar); - - if (i < 0) { - i = 0; // to handle our -1 condition - } - - val = strchr(attrib, ':'); - - if (val) { //the prefix gives the modulename - //check the prefix - if (!strncmp("robinson:", attrib, 9)) { //robinson - attrValue.append( "Robinson:" ); //work is not the same as Sword's module name - attrValue.append( val + 1 ); - } - //strongs is handled by BibleTime - /*else if (!strncmp("strongs", attrib, val-atrrib)) { - attrValue.append( !strncmp(attrib, "x-", 2) ? attrib+2 : attrib ); - }*/ - else { - attrValue.append( !strncmp(attrib, "x-", 2) ? attrib + 2 : attrib ); - } - } - else { //no prefix given - val = attrib; - const bool skipFirst = ((val[0] == 'T') && ((val[1] == 'H') || (val[1] == 'H'))); - attrValue.append( skipFirst ? val + 1 : val ); - } - } - while (++i < count); - - if (attrValue.length()) { - outTag.setAttribute("morph", attrValue.c_str()); - } - } - - if ((attrib = tag.getAttribute("POS"))) { - val = strchr(attrib, ':'); - val = (val) ? (val + 1) : attrib; - outTag.setAttribute("pos", val); - } - - buf.append( outTag.toString() ); - } - else if (tag.isEndTag()) { // end or empty tag - buf.append(""); - } - } - - // tag - else if (!strcmp(tag.getName(), "note")) { - if (!tag.isEndTag()) { //start tag - const sword::SWBuf type( tag.getAttribute("type") ); - - if (type == "crossReference") { //note containing cross references - myUserData->inCrossrefNote = true; - myUserData->noteType = BT_UserData::CrossReference; - - /* - * Do not count crossrefs as footnotes if they are displayed in the text. This will cause problems - * with footnote numbering when crossrefs are turned on/off. - * When accessing footnotes, crossrefs must be turned off in the filter so that they are not in the entry - * attributes of Sword. - * - * //myUserData->swordFootnote++; // cross refs count as notes, too - */ - - buf.append(""); - sword::SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); - sword::SWBuf footnoteBody = myUserData->entryAttributes["Footnote"][footnoteNumber]["body"]; - buf += myModule->RenderText(footnoteBody); - } - - /* else if (type == "explanation") { - } - */ - else if ((type == "strongsMarkup") || (type == "x-strongsMarkup")) { - /** - * leave strong's markup notes out, in the future we'll probably have - * different option filters to turn different note types on or off - */ - - myUserData->suspendTextPassThru = true; - myUserData->noteType = BT_UserData::StrongsMarkup; - } - - else { - // qWarning("found note in %s", myUserData->key->getShortText()); - buf.append(" Name()); - buf.append('/'); - buf.append(myUserData->key->getShortText()); - buf.append('/'); - buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); //inefficient - - const sword::SWBuf n = tag.getAttribute("n"); - - buf.append("\">"); - buf.append( (n.length() > 0) ? n.c_str() : "*" ); - buf.append(" "); - - myUserData->noteType = BT_UserData::Footnote; - myUserData->suspendTextPassThru = true; - } - } - else { //if (tag.isEndTag()) { - Q_ASSERT(myUserData->noteType != BT_UserData::Unknown); - - if (myUserData->noteType == BT_UserData::CrossReference) { - buf.append(" "); -// myUserData->suspendTextPassThru = false; - myUserData->inCrossrefNote = false; - } - - myUserData->noteType = BT_UserData::Unknown; - myUserData->suspendTextPassThru = false; - } - } - // The

paragraph tag is handled by OSISHTMLHref - else if (!strcmp(tag.getName(), "reference")) { // tag - if (!tag.isEndTag() && !tag.isEmpty()) { - - renderReference(tag.getAttribute("osisRef"), buf, myModule, myUserData); - - } - else if (tag.isEndTag()) { - buf.append(""); - } - else { // empty reference marker - // -- what should we do? nothing for now. - } - } - - // is handled by OSISHTMLHref - // - else if (!strcmp(tag.getName(), "title")) { - if (!tag.isEndTag() && !tag.isEmpty()) { - buf.append("<div class=\"sectiontitle\">"); - } - else if (tag.isEndTag()) { - buf.append("</div>"); - } - else { // empty title marker - // what to do? is this even valid? - buf.append("<br/>"); - } - } - - // <hi> highlighted text - else if (!strcmp(tag.getName(), "hi")) { - const sword::SWBuf type = tag.getAttribute("type"); - - if ((!tag.isEndTag()) && (!tag.isEmpty())) { - if (type == "bold") { - buf.append("<span class=\"bold\">"); - } - else if (type == "illuminated") { - buf.append("<span class=\"illuminated\">"); - } - else if (type == "italic") { - buf.append("<span class=\"italic\">"); - } - else if (type == "line-through") { - buf.append("<span class=\"line-through\">"); - } - else if (type == "normal") { - buf.append("<span class=\"normal\">"); - } - else if (type == "small-caps") { - buf.append("<span class=\"small-caps\">"); - } - else if (type == "underline") { - buf.append("<span class=\"underline\">"); - } - else { - buf.append("<span>"); //don't break markup, </span> is inserted later - } - } - else if (tag.isEndTag()) { //all hi replacements are html spans - buf.append("</span>"); - } - } - - //name - else if (!strcmp(tag.getName(), "name")) { - const sword::SWBuf type = tag.getAttribute("type"); - - if ((!tag.isEndTag()) && (!tag.isEmpty())) { - if (type == "geographic") { - buf.append("<span class=\"name\"><span class=\"geographic\">"); - } - else if (type == "holiday") { - buf.append("<span class=\"name\"><span class=\"holiday\">"); - } - else if (type == "nonhuman") { - buf.append("<span class=\"name\"><span class=\"nonhuman\">"); - } - else if (type == "person") { - buf.append("<span class=\"name\"><span class=\"person\">"); - } - else if (type == "ritual") { - buf.append("<span class=\"name\"><span class=\"ritual\">"); - } - else { - buf.append("<span class=\"name\"><span>"); - } - } - else if (tag.isEndTag()) { //all hi replacements are html spans - buf.append("</span></span> "); - } - } - else if (!strcmp(tag.getName(), "transChange")) { - sword::SWBuf type( tag.getAttribute("type") ); - - if ( !type.length() ) { - type = tag.getAttribute("changeType"); - } - - if ((!tag.isEndTag()) && (!tag.isEmpty())) { - if (type == "added") { - buf.append("<span class=\"transchange\" title=\""); - buf.append(QObject::tr("Added text").toUtf8().constData()); - buf.append("\"><span class=\"added\">"); - } - else if (type == "amplified") { - buf.append("<span class=\"transchange\"><span class=\"amplified\">"); - } - else if (type == "changed") { - buf.append("<span class=\"transchange\"><span class=\"changed\">"); - } - else if (type == "deleted") { - buf.append("<span class=\"transchange\"><span class=\"deleted\">"); - } - else if (type == "moved") { - buf.append("<span class=\"transchange\"><span class=\"moved\">"); - } - else if (type == "tenseChange") { - buf.append("<span class=\"transchange\" title=\""); - buf.append(QObject::tr("Verb tense changed").toUtf8().constData()); - buf.append("\"><span class=\"tenseChange\">"); - } - else { - buf.append("<span class=\"transchange\"><span>"); - } - } - else if (tag.isEndTag()) { //all hi replacements are html spans - buf.append("</span></span>"); - } - } - else if (!strcmp(tag.getName(), "p")) { - if (tag.isEmpty()) { - buf.append("<p/>"); - } - } - - // <q> quote - else if (!strcmp(tag.getName(), "q")) { - sword::SWBuf type = tag.getAttribute("type"); - sword::SWBuf who = tag.getAttribute("who"); - const char *lev = tag.getAttribute("level"); - int level = (lev) ? atoi(lev) : 1; - const char* quoteMarker = tag.getAttribute("marker"); - - if ((!tag.isEndTag())) { - myUserData->quote.who = who; - if (quoteMarker) { - buf.append(quoteMarker); - } - else if (osisQToTick) //alternate " and ' - buf.append((level % 2) ? '\"' : '\''); - - if (who == "Jesus") { - buf.append("<span class=\"jesuswords\">"); - } - } - else if (tag.isEndTag()) { - if (myUserData->quote.who == "Jesus") { - buf.append("</span>"); - } - if (quoteMarker) { - buf.append(quoteMarker); - } - else if (osisQToTick) { //alternate " and ' - buf.append((level % 2) ? '\"' : '\''); - } - - myUserData->quote.who = ""; - } - } - - // abbr tag - else if (!strcmp(tag.getName(), "abbr")) { - if (!tag.isEndTag() && !tag.isEmpty()) { - const sword::SWBuf expansion = tag.getAttribute("expansion"); - - buf.append("<span class=\"abbreviation\" expansion=\""); - buf.append(expansion); - buf.append("\">"); - } - else if (tag.isEndTag()) { - buf.append("</span>"); - } - } - - // <milestone> tag - else if (!strcmp(tag.getName(), "milestone")) { - const sword::SWBuf type = tag.getAttribute("type"); - - if ((type == "screen") || (type == "line")) {//line break - buf.append("<br/>"); - userData->supressAdjacentWhitespace = true; - } - else if (type == "x-p") { //e.g. occurs in the KJV2006 module - //buf.append("<br/>"); - const sword::SWBuf marker = tag.getAttribute("marker"); - if (marker.length() > 0) { - buf.append(marker); - } - } - } - //seg tag - else if (!strcmp(tag.getName(), "seg")) { - if (!tag.isEndTag() && !tag.isEmpty()) { - - const sword::SWBuf type = tag.getAttribute("type"); - - if (type == "morph") {//line break - //This code is for WLC and MORPH (WHI) - sword::XMLTag outTag("span"); - outTag.setAttribute("class", "morphSegmentation"); - const char* attrValue; - //Transfer the values to the span - //Problem: the data is in hebrew/aramaic, how to encode in HTML/BibleTime? - if ((attrValue = tag.getAttribute("lemma"))) outTag.setAttribute("lemma", attrValue); - if ((attrValue = tag.getAttribute("morph"))) outTag.setAttribute("morph", attrValue); - if ((attrValue = tag.getAttribute("homonym"))) outTag.setAttribute("homonym", attrValue); - - buf.append(outTag.toString()); - //buf.append("<span class=\"morphSegmentation\">"); - } - else { - buf.append("<span>"); - } - } - else { // seg end tag - buf.append("</span>"); - } - //qWarning(QString("handled <seg> token. result: %1").arg(buf.c_str()).latin1()); - } - - //divine name, don't use simple tag replacing because it may have attributes - else if (!strcmp(tag.getName(), "divineName")) { - if (!tag.isEndTag()) { - buf.append("<span class=\"name\"><span class=\"divine\">"); - } - else { //all hi replacements are html spans - buf.append("</span></span>"); - } - } - - else { //all tokens handled by OSISHTMLHref will run through the filter now - return sword::OSISHTMLHREF::handleToken(buf, token, userData); - } - } - - return false; -} - -void Filters::BT_OSISHTML::renderReference(const char *osisRef, sword::SWBuf &buf, sword::SWModule *myModule, BT_UserData *myUserData) { - QString ref( osisRef ); - QString hrefRef( ref ); - //Q_ASSERT(!ref.isEmpty()); checked later - - if (!ref.isEmpty()) { - //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default. - //If the osisRef is something like "ModuleID:key comes here" then the - // modulename is given, so we'll use that one - - CSwordModuleInfo* mod = CPointers::backend()->findSwordModuleByPointer(myModule); - //Q_ASSERT(mod); checked later - if (!mod || (mod->type() != CSwordModuleInfo::Bible - && mod->type() != CSwordModuleInfo::Commentary)) { - - mod = CBTConfig::get( CBTConfig::standardBible ); - } - - // Q_ASSERT(mod); There's no necessarily a module or standard Bible - - //if the osisRef like "GerLut:key" contains a module, use that - int pos = ref.indexOf(":"); - - if ((pos >= 0) && ref.at(pos - 1).isLetter() && ref.at(pos + 1).isLetter()) { - QString newModuleName = ref.left(pos); - hrefRef = ref.mid(pos + 1); - - if (CPointers::backend()->findModuleByName(newModuleName)) { - mod = CPointers::backend()->findModuleByName(newModuleName); - } - } - - if (mod) { - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); - options.refDestinationModule = QString(mod->name()); - options.sourceLanguage = QString(myModule->Lang()); - options.destinationLanguage = QString("en"); - - buf.append("<a href=\""); - buf.append( //create the hyperlink with key and mod - ReferenceManager::encodeHyperlink( - mod->name(), - ReferenceManager::parseVerseReference(hrefRef, options), - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - buf.append("\" crossrefs=\""); - buf.append((const char*)ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any - buf.append("\">"); - } - // should we add something if there were no referenced module available? - } -} - diff --git a/src/backend/filters/bt_osishtml.h b/src/backend/filters/bt_osishtml.h deleted file mode 100644 index 83bf0a9..0000000 --- a/src/backend/filters/bt_osishtml.h +++ /dev/null @@ -1,70 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BT_OSISHTML_H -#define BT_OSISHTML_H - -// Sword includes: -#include <osishtmlhref.h> -#include <swbuf.h> -#include <swmodule.h> - -namespace Filters { - -/** BibleTime's OSIS to HTMl filter. -* This filter works on OSIS tags and outputs HTML in the structure supported by BibleTime. -*/ - -class BT_OSISHTML : public sword::OSISHTMLHREF { - - protected: - - class BT_UserData : public sword::OSISHTMLHREF::MyUserData { - - public: - BT_UserData(const sword::SWModule *module, const sword::SWKey *key) : sword::OSISHTMLHREF::MyUserData(module, key) { - noteType = Unknown; - swordFootnote = 1; - inCrossrefNote = false; - entryAttributes = module->getEntryAttributes(); - } - - unsigned short int swordFootnote; - bool inCrossrefNote; - sword::AttributeTypeList entryAttributes; - - enum NoteType { - Unknown, - Alternative, - CrossReference, - Footnote, - StrongsMarkup - } noteType; - - struct { - sword::SWBuf who; - } - - quote; - }; - - virtual sword::BasicFilterUserData *createUserData(const sword::SWModule* module, const sword::SWKey* key) { - return new BT_UserData(module, key); - } - - public: - BT_OSISHTML(); - virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData); - private: - void renderReference(const char *osisRef, sword::SWBuf &buf, sword::SWModule *myModule, BT_UserData *myUserData); -}; - -} //end of Filters namespace - -#endif diff --git a/src/backend/filters/bt_plainhtml.cpp b/src/backend/filters/bt_plainhtml.cpp deleted file mode 100644 index c70db79..0000000 --- a/src/backend/filters/bt_plainhtml.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "backend/filters/bt_plainhtml.h" - - -Filters::BT_PLAINHTML::BT_PLAINHTML() : sword::SWFilter() { -} - -/** No descriptions */ -char Filters::BT_PLAINHTML::processText(sword::SWBuf& text, const sword::SWKey* /*key*/, const sword::SWModule* /*module*/) { - int count = 0; - - sword::SWBuf orig = text; - const char *from = orig.c_str(); - for (text = ""; *from; from++) { - if ((*from == '\n') && (from[1] == '\n')) { // two newlinea are a paragraph - text += "<P>"; - from++; - continue; - } - //This is a special case: Newlines in the plaintext editor are stored as <br />, not as \n - //we need to let them through - else if ((*from == '<') && (from[1] == 'b') && (from[2] == 'r') && (from[3] == ' ') && (from[4] == '/') && (from[5] == '>')) { - text += "<br />"; - from += 5; - continue; - } - else if ((*from == '\n')) { // only one new line - text += "<br/>"; - continue; - } - else if (*from == '<') { - text += "<"; - continue; - } - else if (*from == '>') { - text += ">"; - continue; - } - else if (*from == '&') { - text += "&"; - continue; - } - else if (*from == '{') { //footnote start - text += "<font color=\"#800000\"><small> ("; /// \bug Possible color conflict - continue; - } - else if (*from == '}') { //footnote end - text += ") </small></font>"; - continue; - } - else if ((*from == ' ') && (count > 5000)) { - text += "<wbr/>"; - count = 0; - continue; - } - - text += *from; - count++; - } - return 0; -} diff --git a/src/backend/filters/bt_plainhtml.h b/src/backend/filters/bt_plainhtml.h deleted file mode 100644 index c228660..0000000 --- a/src/backend/filters/bt_plainhtml.h +++ /dev/null @@ -1,34 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BT_PLAINHTML_H -#define BT_PLAINHTML_H - -// Sword includes: -#include <swbuf.h> -#include <swfilter.h> - - -class SWKey; -class SWModule; - -namespace Filters { - -/** Plain to HTML filter, -* This filter converts Plain Text into HTML -*/ -class BT_PLAINHTML : public sword::SWFilter { - protected: - virtual char processText(sword::SWBuf& buf, const sword::SWKey*, const sword::SWModule * = 0); - public: - BT_PLAINHTML(); -}; -} - -#endif diff --git a/src/backend/filters/bt_teihtml.cpp b/src/backend/filters/bt_teihtml.cpp deleted file mode 100644 index b242f46..0000000 --- a/src/backend/filters/bt_teihtml.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "backend/filters/bt_teihtml.h" - -#include <QString> -#include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/clanguagemgr.h" -#include "backend/managers/referencemanager.h" -#include "util/cpointers.h" - -// Sword includes: -#include <swbuf.h> -#include <swmodule.h> -#include <utilxml.h> - - - -Filters::BT_TEIHTML::BT_TEIHTML() : sword::TEIHTMLHREF() { - setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes -} - -bool Filters::BT_TEIHTML::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { - // manually process if it wasn't a simple substitution - - if (!substituteToken(buf, token)) { - - sword::XMLTag tag(token); - - if (0) { - - } - else if (!strcmp(tag.getName(), "ref")) { - - if (!tag.isEndTag() && !tag.isEmpty()) { - - renderReference(tag.getAttribute("osisRef"), buf, userData); - - } - else if (tag.isEndTag()) { - buf.append("</a>"); - } - else { // empty reference marker - // -- what should we do? nothing for now. - } - } - // <hi> highlighted text - else if (!strcmp(tag.getName(), "hi")) { - const sword::SWBuf type = tag.getAttribute("rend"); - - if ((!tag.isEndTag()) && (!tag.isEmpty())) { - if (type == "bold") { - buf.append("<span class=\"bold\">"); - } - else if (type == "illuminated") { - buf.append("<span class=\"illuminated\">"); - } - else if (type == "italic") { - buf.append("<span class=\"italic\">"); - } - else if (type == "line-through") { - buf.append("<span class=\"line-through\">"); - } - else if (type == "normal") { - buf.append("<span class=\"normal\">"); - } - else if (type == "small-caps") { - buf.append("<span class=\"small-caps\">"); - } - else if (type == "underline") { - buf.append("<span class=\"underline\">"); - } - else { - buf.append("<span>"); //don't break markup, </span> is inserted later - } - } - else if (tag.isEndTag()) { //all hi replacements are html spans - buf.append("</span>"); - } - } - else { //all tokens handled by OSISHTMLHref will run through the filter now - return sword::TEIHTMLHREF::handleToken(buf, token, userData); - } - } - - return false; -} - -void Filters::BT_TEIHTML::renderReference(const char *osisRef, sword::SWBuf &buf, sword::BasicFilterUserData *myUserData) { - QString ref( osisRef ); - QString hrefRef( ref ); - - if (!ref.isEmpty()) { - //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default. - //If the osisRef is something like "ModuleID:key comes here" then the - // modulename is given, so we'll use that one - - CSwordModuleInfo* mod = CBTConfig::get( CBTConfig::standardBible ); - - // Q_ASSERT(mod); There's no necessarily a module or standard Bible - - //if the osisRef like "GerLut:key" contains a module, use that - int pos = ref.indexOf(":"); - - if ((pos >= 0) && ref.at(pos - 1).isLetter() && ref.at(pos + 1).isLetter()) { - QString newModuleName = ref.left(pos); - hrefRef = ref.mid(pos + 1); - - if (CPointers::backend()->findModuleByName(newModuleName)) { - mod = CPointers::backend()->findModuleByName(newModuleName); - } - } - - if (mod) { - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); - options.refDestinationModule = QString(mod->name()); - options.sourceLanguage = QString(mod->module()->Lang()); - options.destinationLanguage = QString("en"); - - buf.append("<a href=\""); - buf.append( //create the hyperlink with key and mod - ReferenceManager::encodeHyperlink( - mod->name(), - ReferenceManager::parseVerseReference(hrefRef, options), - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - buf.append("\" crossrefs=\""); - buf.append((const char*)ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any - buf.append("\">"); - } - // should we add something if there were no referenced module available? - } -} - diff --git a/src/backend/filters/bt_teihtml.h b/src/backend/filters/bt_teihtml.h deleted file mode 100644 index 2160349..0000000 --- a/src/backend/filters/bt_teihtml.h +++ /dev/null @@ -1,34 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BT_TEIHTML_H -#define BT_TEIHTML_H - -// Sword includes: -#include <teihtmlhref.h> -#include <swbuf.h> - -namespace Filters { - -/** BibleTime's TEI to HTMl filter. -* This filter works on TEI tags and outputs HTML in the structure supported by BibleTime. -*/ - -class BT_TEIHTML : public sword::TEIHTMLHREF { - - public: - BT_TEIHTML(); - virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData); - private: - void renderReference(const char *osisRef, sword::SWBuf &buf, sword::BasicFilterUserData *myUserData); -}; - -} //end of Filters namespace - -#endif diff --git a/src/backend/filters/bt_thmlhtml.cpp b/src/backend/filters/bt_thmlhtml.cpp deleted file mode 100644 index 478339c..0000000 --- a/src/backend/filters/bt_thmlhtml.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "backend/filters/bt_thmlhtml.h" - -#include <QString> -#include <QRegExp> -#include <QUrl> -#include <QTextCodec> -#include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/clanguagemgr.h" -#include "backend/managers/referencemanager.h" -#include "util/cpointers.h" - -// Sword includes: -#include <swmodule.h> -#include <utilstr.h> -#include <utilxml.h> -#include <versekey.h> - - -Filters::BT_ThMLHTML::BT_ThMLHTML() { - setEscapeStringCaseSensitive(true); - setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes - - setTokenStart("<"); - setTokenEnd(">"); - setTokenCaseSensitive(true); - - addTokenSubstitute("/foreign", "</span>"); - - removeTokenSubstitute("note"); - removeTokenSubstitute("/note"); -} - -char Filters::BT_ThMLHTML::processText(sword::SWBuf& buf, const sword::SWKey* key, const sword::SWModule* module) { - sword::ThMLHTML::processText(buf, key, module); - - CSwordModuleInfo* m = CPointers::backend()->findModuleByName( module->Name() ); - - if (m && !(m->has(CSwordModuleInfo::lemmas) || m->has(CSwordModuleInfo::strongNumbers))) { //only parse if the module has strongs or lemmas - return 1; - } - - QString result; - - QString t = QString::fromUtf8(buf.c_str()); - QRegExp tag("([.,;]?<sync[^>]+(type|value)=\"([^\"]+)\"[^>]+(type|value)=\"([^\"]+)\"([^<]*)>)+"); - - QStringList list; - int lastMatchEnd = 0; - int pos = tag.indexIn(t, 0); - - if (pos == -1) { //no strong or morph code found in this text - return 1; //WARNING: Return alread here - } - - while (pos != -1) { - list.append(t.mid(lastMatchEnd, pos + tag.matchedLength() - lastMatchEnd)); - - lastMatchEnd = pos + tag.matchedLength(); - pos = tag.indexIn(t, pos + tag.matchedLength()); - } - - if (!t.right(t.length() - lastMatchEnd).isEmpty()) { - list.append(t.right(t.length() - lastMatchEnd)); - } - - tag = QRegExp("<sync[^>]+(type|value|class)=\"([^\"]+)\"[^>]+(type|value|class)=\"([^\"]+)\"[^>]+((type|value|class)=\"([^\"]+)\")*([^<]*)>"); - - for (QStringList::iterator it = list.begin(); it != list.end(); ++it) { - QString e( *it ); - - const bool textPresent = (e.trimmed().remove(QRegExp("[.,;:]")).left(1) != "<"); - - if (!textPresent) { - continue; - } - - - bool hasLemmaAttr = false; - bool hasMorphAttr = false; - - int pos = tag.indexIn(e, 0); - bool insertedTag = false; - QString value; - QString valueClass; - - while (pos != -1) { - bool isMorph = false; - bool isStrongs = false; - value = QString::null; - valueClass = QString::null; - - // check 3 attribute/value pairs - - for (int i = 1; i < 6; i += 2) { - if (i > 4) - i++; - - if (tag.cap(i) == "type") { - isMorph = (tag.cap(i + 1) == "morph"); - isStrongs = (tag.cap(i + 1) == "Strongs"); - } - else if (tag.cap(i) == "value") { - value = tag.cap(i + 1); - } - else if (tag.cap(i) == "class") { - valueClass = tag.cap(i + 1); - } - } - - // prepend the class qualifier to the value - if (!valueClass.isEmpty()) { - value = valueClass + ":" + value; - // value.append(":").append(value); - } - - if (value.isEmpty()) { - break; - } - - //insert the span - if (!insertedTag) { - e.replace(pos, tag.matchedLength(), "</span>"); - pos += 7; - - QString rep = QString("<span lemma=\"").append(value).append("\">"); - int startPos = 0; - QChar c = e[startPos]; - - while ((startPos < pos) && (c.isSpace() || c.isPunct())) { - ++startPos; - c = e[startPos]; - } - - hasLemmaAttr = isStrongs; - hasMorphAttr = isMorph; - - e.insert( startPos, rep ); - pos += rep.length(); - } - else { //add the attribute to the existing tag - e.remove(pos, tag.matchedLength()); - - if ((!isMorph && hasLemmaAttr) || (isMorph && hasMorphAttr)) { //we append another attribute value, e.g. 3000 gets 3000|5000 - //search the existing attribute start - QRegExp attrRegExp( isMorph ? "morph=\".+(?=\")" : "lemma=\".+(?=\")" ); - attrRegExp.setMinimal(true); - const int foundAttrPos = e.indexOf(attrRegExp, pos); - - if (foundAttrPos != -1) { - e.insert(foundAttrPos + attrRegExp.matchedLength(), QString("|").append(value)); - pos += value.length() + 1; - - hasLemmaAttr = !isMorph; - hasMorphAttr = isMorph; - } - } - else { //attribute was not yet inserted - const int attrPos = e.indexOf(QRegExp("morph=|lemma="), 0); - - if (attrPos >= 0) { - QString attr; - attr.append(isMorph ? "morph" : "lemma").append("=\"").append(value).append("\" "); - e.insert(attrPos, attr); - - hasMorphAttr = isMorph; - hasLemmaAttr = !isMorph; - - pos += attr.length(); - } - } - } - - insertedTag = true; - pos = tag.indexIn(e, pos); - } - - result.append( e ); - } - - if (list.count()) { - buf = (const char*)result.toUtf8(); - } - - return 1; -} - - -bool Filters::BT_ThMLHTML::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { - if (!substituteToken(buf, token) && !substituteEscapeString(buf, token)) { - sword::XMLTag tag(token); - BT_UserData* myUserData = dynamic_cast<BT_UserData*>(userData); - sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack to be able to call stuff like Lang() - - if ( tag.getName() && !sword::stricmp(tag.getName(), "foreign") ) { // a text part in another language, we have to set the right font - - if (tag.getAttribute("lang")) { - const char* abbrev = tag.getAttribute("lang"); - //const CLanguageMgr::Language* const language = CPointers::languageMgr()->languageForAbbrev( QString::fromLatin1(abbrev) ); - - buf.append("<span class=\"foreign\" lang=\""); - buf.append(abbrev); - buf.append("\">"); - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "sync")) { //lemmas, morph codes or strongs - - if (tag.getAttribute("type") && (!sword::stricmp(tag.getAttribute("type"), "morph") || !sword::stricmp(tag.getAttribute("type"), "Strongs") || !sword::stricmp(tag.getAttribute("type"), "lemma"))) { // Morph or Strong - buf.append('<'); - buf.append(token); - buf.append('>'); - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "note")) { // <note> tag - - if (!tag.isEndTag() && !tag.isEmpty()) { - //appending is faster than appendFormatted - buf.append(" <span class=\"footnote\" note=\""); - buf.append(myModule->Name()); - buf.append('/'); - buf.append(myUserData->key->getShortText()); - buf.append('/'); - buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); - buf.append("\">*</span> "); - - myUserData->suspendTextPassThru = true; - myUserData->inFootnoteTag = true; - } - else if (tag.isEndTag() && !tag.isEmpty()) { //end tag - //buf += ")</span>"; - myUserData->suspendTextPassThru = false; - myUserData->inFootnoteTag = false; - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "scripRef")) { // a scripRef - //scrip refs which are embeded in footnotes may not be displayed! - - if (!myUserData->inFootnoteTag) { - if (tag.isEndTag()) { - if (myUserData->inscriptRef) { // like "<scripRef passage="John 3:16">See John 3:16</scripRef>" - buf.append("</a></span>"); - - myUserData->inscriptRef = false; - myUserData->suspendTextPassThru = false; - } - else { // like "<scripRef>John 3:16</scripRef>" - - CSwordModuleInfo* mod = CBTConfig::get(CBTConfig::standardBible); - //Q_ASSERT(mod); tested later - if (mod) { - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); //current module key - options.refDestinationModule = QString(mod->name()); - options.sourceLanguage = QString(myModule->Lang()); - options.destinationLanguage = QString("en"); - - //it's ok to split the reference, because to descriptive text is given - bool insertSemicolon = false; - buf.append("<span class=\"crossreference\">"); - QStringList refs = QString::fromUtf8(myUserData->lastTextNode.c_str()).split(";"); - QString oldRef; //the previous reference to use as a base for the next refs - for (QStringList::iterator it(refs.begin()); it != refs.end(); ++it) { - - if (! oldRef.isEmpty() ) { - options.refBase = oldRef; //use the last ref as a base, e.g. Rom 1,2-3, when the next ref is only 3:3-10 - } - const QString completeRef( ReferenceManager::parseVerseReference((*it), options) ); - - oldRef = completeRef; //use the parsed result as the base for the next ref. - - if (insertSemicolon) { //prepend a ref divider if we're after the first one - buf.append("; "); - } - - buf.append("<a href=\""); - buf.append( - ReferenceManager::encodeHyperlink( - mod->name(), - completeRef, - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - - buf.append("\" crossrefs=\""); - buf.append((const char*)completeRef.toUtf8()); - buf.append("\">"); - - buf.append((const char*)(*it).toUtf8()); - - buf.append("</a>"); - - insertSemicolon = true; - } - buf.append("</span>"); //crossref end - } - - myUserData->suspendTextPassThru = false; - } - } - else if (tag.getAttribute("passage") ) { //the passage was given as a parameter value - myUserData->inscriptRef = true; - myUserData->suspendTextPassThru = false; - - const char* ref = tag.getAttribute("passage"); - Q_ASSERT(ref); - - CSwordModuleInfo* mod = CBTConfig::get(CBTConfig::standardBible); - //Q_ASSERT(mod); tested later - - ReferenceManager::ParseOptions options; - options.refBase = QString::fromUtf8(myUserData->key->getText()); - - options.sourceLanguage = myModule->Lang(); - options.destinationLanguage = QString("en"); - - const QString completeRef = ReferenceManager::parseVerseReference(QString::fromUtf8(ref), options); - - if (mod) { - options.refDestinationModule = QString(mod->name()); - buf.append("<span class=\"crossreference\">"); - buf.append("<a href=\""); - buf.append( - ReferenceManager::encodeHyperlink( - mod->name(), - completeRef, - ReferenceManager::typeFromModule(mod->type()) - ).toUtf8().constData() - ); - buf.append("\" crossrefs=\""); - buf.append((const char*)completeRef.toUtf8()); - buf.append("\">"); - } - else { - buf.append("<span><a>"); - } - } - else if ( !tag.getAttribute("passage") ) { // we're starting a scripRef like "<scripRef>John 3:16</scripRef>" - myUserData->inscriptRef = false; - - // let's stop text from going to output, the text get's added in the -tag handler - myUserData->suspendTextPassThru = true; - } - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "div")) { - if (tag.isEndTag()) { - buf.append("</div>"); - } - else if ( tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"), "sechead") ) { - buf.append("<div class=\"sectiontitle\">"); - } - else if (tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"), "title")) { - buf.append("<div class=\"booktitle\">"); - } - } - else if (tag.getName() && !sword::stricmp(tag.getName(), "img") && tag.getAttribute("src")) { - const char* value = tag.getAttribute("src"); - - if (value[0] == '/') { - value++; //strip the first / - } - - buf.append("<img src=\""); - QString absPath(QTextCodec::codecForLocale()->toUnicode(myUserData->module->getConfigEntry("AbsoluteDataPath"))); - QString relPath(QString::fromUtf8(value)); - QString url(QUrl::fromLocalFile(absPath.append('/').append(relPath)).toString()); - buf.append(url.toUtf8().data()); - buf.append("\" />"); - } - else { // let unknown token pass thru - return sword::ThMLHTML::handleToken(buf, token, userData); - } - } - - return true; -} diff --git a/src/backend/filters/bt_thmlhtml.h b/src/backend/filters/bt_thmlhtml.h deleted file mode 100644 index 6a220b6..0000000 --- a/src/backend/filters/bt_thmlhtml.h +++ /dev/null @@ -1,54 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BT_THMLHTML_H -#define BT_THMLHTML_H - -// Sword includes: -#include <swbuf.h> -#include <thmlhtml.h> - - -namespace Filters { - -/** ThML to HTML filter. -* This filter converts ThML text to HTML text -*/ - -class BT_ThMLHTML : public sword::ThMLHTML { - - protected: - - class BT_UserData : public sword::ThMLHTML::MyUserData { - - public: - BT_UserData(const sword::SWModule *module, const sword::SWKey *key) : sword::ThMLHTML::MyUserData(module, key) { - inscriptRef = false; - swordFootnote = 1; - inFootnoteTag = false; - } - - bool inscriptRef; - bool inFootnoteTag; - unsigned short int swordFootnote; - }; - - virtual sword::BasicFilterUserData *createUserData(const sword::SWModule* module, const sword::SWKey* key) { - return new BT_UserData(module, key); - } - - public: - BT_ThMLHTML (); - virtual bool handleToken(sword::SWBuf& buf, const char *token, sword::BasicFilterUserData *userData); - virtual char processText(sword::SWBuf& buf, const sword::SWKey*, const sword::SWModule* = 0); -}; - -} - -#endif diff --git a/src/backend/filters/bt_thmlplain.cpp b/src/backend/filters/bt_thmlplain.cpp deleted file mode 100644 index ecd7bbd..0000000 --- a/src/backend/filters/bt_thmlplain.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -/****************************************************************************** - * - * thmlplain - SWFilter descendant to strip out all ThML tags or convert to - * ASCII rendered symbols. - */ - -#include "backend/filters/bt_thmlplain.h" - - -Filters::BT_ThMLPlain::BT_ThMLPlain() { -} - -char Filters::BT_ThMLPlain::processText(sword::SWBuf &text, const sword::SWKey* /*key*/, const sword::SWModule* /*module*/) { - char token[2048]; - int tokpos = 0; - bool intoken = false; - bool ampersand = false; - - const char *from; - sword::SWBuf orig = text; - from = orig.c_str(); - for (text = ""; *from; from++) { - if (*from == 10 || *from == 13) - from++; - if (*from == '<') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - ampersand = false; - continue; - } - else if (*from == '&') { - intoken = true; - tokpos = 0; - token[0] = 0; - token[1] = 0; - token[2] = 0; - ampersand = true; - continue; - } - if (*from == ';' && ampersand) { - intoken = false; - ampersand = false; - - if (!strncmp("nbsp", token, 4)) text += " "; - else if (!strncmp("quot", token, 4)) text += "\""; - else if (!strncmp("amp", token, 3)) text += "&"; - else if (!strncmp("lt", token, 2)) text += "<"; - else if (!strncmp("gt", token, 2)) text += ">"; - else if (!strncmp("brvbar", token, 6)) text += "¦"; - else if (!strncmp("sect", token, 4)) text += "§"; - else if (!strncmp("copy", token, 4)) text += "©"; - else if (!strncmp("laquo", token, 5)) text += "«"; - else if (!strncmp("reg", token, 3)) text += "®"; - else if (!strncmp("acute", token, 5)) text += "´"; - else if (!strncmp("para", token, 4)) text += "¶"; - else if (!strncmp("raquo", token, 5)) text += "»"; - - else if (!strncmp("Aacute", token, 6)) text += "Á"; - else if (!strncmp("Agrave", token, 6)) text += "À"; - else if (!strncmp("Acirc", token, 5)) text += "Â"; - else if (!strncmp("Auml", token, 4)) text += "Ä"; - else if (!strncmp("Atilde", token, 6)) text += "Ã"; - else if (!strncmp("Aring", token, 5)) text += "Å"; - else if (!strncmp("aacute", token, 6)) text += "á"; - else if (!strncmp("agrave", token, 6)) text += "à"; - else if (!strncmp("acirc", token, 5)) text += "â"; - else if (!strncmp("auml", token, 4)) text += "ä"; - else if (!strncmp("atilde", token, 6)) text += "ã"; - else if (!strncmp("aring", token, 5)) text += "å"; - else if (!strncmp("Eacute", token, 6)) text += "É"; - else if (!strncmp("Egrave", token, 6)) text += "È"; - else if (!strncmp("Ecirc", token, 5)) text += "Ê"; - else if (!strncmp("Euml", token, 4)) text += "Ë"; - else if (!strncmp("eacute", token, 6)) text += "é"; - else if (!strncmp("egrave", token, 6)) text += "è"; - else if (!strncmp("ecirc", token, 5)) text += "ê"; - else if (!strncmp("euml", token, 4)) text += "ë"; - else if (!strncmp("Iacute", token, 6)) text += "Í"; - else if (!strncmp("Igrave", token, 6)) text += "Ì"; - else if (!strncmp("Icirc", token, 5)) text += "Î"; - else if (!strncmp("Iuml", token, 4)) text += "Ï"; - else if (!strncmp("iacute", token, 6)) text += "í"; - else if (!strncmp("igrave", token, 6)) text += "ì"; - else if (!strncmp("icirc", token, 5)) text += "î"; - else if (!strncmp("iuml", token, 4)) text += "ï"; - else if (!strncmp("Oacute", token, 6)) text += "Ó"; - else if (!strncmp("Ograve", token, 6)) text += "Ò"; - else if (!strncmp("Ocirc", token, 5)) text += "Ô"; - else if (!strncmp("Ouml", token, 4)) text += "Ö"; - else if (!strncmp("Otilde", token, 6)) text += "Õ"; - else if (!strncmp("oacute", token, 6)) text += "ó"; - else if (!strncmp("ograve", token, 6)) text += "ò"; - else if (!strncmp("ocirc", token, 5)) text += "ô"; - else if (!strncmp("ouml", token, 4)) text += "ö"; - else if (!strncmp("otilde", token, 6)) text += "õ"; - else if (!strncmp("Uacute", token, 6)) text += "Ú"; - else if (!strncmp("Ugrave", token, 6)) text += "Ù"; - else if (!strncmp("Ucirc", token, 5)) text += "Û"; - else if (!strncmp("Uuml", token, 4)) text += "Ü"; - else if (!strncmp("uacute", token, 6)) text += "ú"; - else if (!strncmp("ugrave", token, 6)) text += "ù"; - else if (!strncmp("ucirc", token, 5)) text += "û"; - else if (!strncmp("uuml", token, 4)) text += "ü"; - else if (!strncmp("Yacute", token, 6)) text += "Ý"; - else if (!strncmp("yacute", token, 6)) text += "ý"; - else if (!strncmp("yuml", token, 4)) text += "ÿ"; - - else if (!strncmp("deg", token, 3)) text += "°"; - else if (!strncmp("plusmn", token, 6)) text += "±"; - else if (!strncmp("sup2", token, 4)) text += "²"; - else if (!strncmp("sup3", token, 4)) text += "³"; - else if (!strncmp("sup1", token, 4)) text += "¹"; - else if (!strncmp("nbsp", token, 4)) text += "º"; - else if (!strncmp("pound", token, 5)) text += "£"; - else if (!strncmp("cent", token, 4)) text += "¢"; - else if (!strncmp("frac14", token, 6)) text += "¼"; - else if (!strncmp("frac12", token, 6)) text += "½"; - else if (!strncmp("frac34", token, 6)) text += "¾"; - else if (!strncmp("iquest", token, 6)) text += "¿"; - else if (!strncmp("iexcl", token, 5)) text += "¡"; - else if (!strncmp("ETH", token, 3)) text += "Ð"; - else if (!strncmp("eth", token, 3)) text += "ð"; - else if (!strncmp("THORN", token, 5)) text += "Þ"; - else if (!strncmp("thorn", token, 5)) text += "þ"; - else if (!strncmp("AElig", token, 5)) text += "Æ"; - else if (!strncmp("aelig", token, 5)) text += "æ"; - else if (!strncmp("Oslash", token, 6)) text += "Ø"; - else if (!strncmp("curren", token, 6)) text += "¤"; - else if (!strncmp("Ccedil", token, 6)) text += "Ç"; - else if (!strncmp("ccedil", token, 6)) text += "ç"; - else if (!strncmp("szlig", token, 5)) text += "ß"; - else if (!strncmp("Ntilde", token, 6)) text += "Ñ"; - else if (!strncmp("ntilde", token, 6)) text += "ñ"; - else if (!strncmp("yen", token, 3)) text += "¥"; - else if (!strncmp("not", token, 3)) text += "¬"; - else if (!strncmp("ordf", token, 4)) text += "ª"; - else if (!strncmp("uml", token, 3)) text += "¨"; - else if (!strncmp("shy", token, 3)) text += "­"; - else if (!strncmp("macr", token, 4)) text += "¯"; - else if (!strncmp("micro", token, 5)) text += "µ"; - else if (!strncmp("middot", token, 6)) text += "·"; - else if (!strncmp("cedil", token, 5)) text += "¸"; - else if (!strncmp("ordm", token, 4)) text += "º"; - else if (!strncmp("times", token, 5)) text += "×"; - else if (!strncmp("divide", token, 6)) text += "÷"; - else if (!strncmp("oslash", token, 6)) text += "ø"; - continue; - - } - else if (*from == '>' && !ampersand) { - intoken = false; - // process desired tokens - if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) { - text += ' '; - text += '<'; - for (unsigned int i = 27; token[i] != '\"'; i++) - text += token[i]; - text += '>'; - continue; - } - if (!strncmp(token, "sync type=\"morph\" value=\"", 25)) { - text += ' '; - text += '('; - for (unsigned int i = 25; token[i] != '\"'; i++) - text += token[i]; - text += ')'; - continue; - } - if (!strncmp("note", token, 4)) { - text += ' '; - text += '('; - } - else if (!strncmp("br", token, 2)) - text += '\n'; - else if (!strncmp("/p", token, 2)) - text += '\n'; - else if (!strncmp("/note", token, 5)) { - text += ')'; - text += ' '; - } - continue; - } - if (intoken) { - if (tokpos < 2045) - token[tokpos++] = *from; - token[tokpos+2] = 0; - } - else text += *from; - } - - orig = text; - from = orig.c_str(); - for (text = ""; *from; from++) { //loop to remove extra spaces - if ((strchr(" \t\n\r", *from))) { - while (*(from + 1) && (strchr(" \t\n\r", *(from + 1)))) { - from++; - } - text += " "; - } - else { - text += *from; - } - } - text += (char)0; - - return 0; -} - diff --git a/src/backend/filters/bt_thmlplain.h b/src/backend/filters/bt_thmlplain.h deleted file mode 100644 index 92c2c33..0000000 --- a/src/backend/filters/bt_thmlplain.h +++ /dev/null @@ -1,30 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BT_THMLPLAIN_H -#define BT_THMLPLAIN_H - -// Sword includes: -#include <swbuf.h> -#include <swfilter.h> - - -namespace Filters { - -/** This filter converts ThML text to plain text -*/ -class BT_ThMLPlain : public sword::SWFilter { - protected: - virtual char processText(sword::SWBuf &text, const sword::SWKey *key = 0, const sword::SWModule *module = 0); - public: - BT_ThMLPlain(); -}; - -} -#endif diff --git a/src/backend/filters/gbftohtml.cpp b/src/backend/filters/gbftohtml.cpp new file mode 100644 index 0000000..fac70ba --- /dev/null +++ b/src/backend/filters/gbftohtml.cpp @@ -0,0 +1,289 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/filters/gbftohtml.h" + +#include <QRegExp> +#include <QString> +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/cswordbackend.h" + +// Sword includes: +#include <utilxml.h> + + +Filters::GbfToHtml::GbfToHtml() : sword::GBFHTML() { + + setEscapeStringCaseSensitive(true); + setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes + + removeTokenSubstitute("Rf"); + // addTokenSubstitute("RB", "<span>"); //start of a footnote with embedded text + + addTokenSubstitute("FI", "<span class=\"italic\">"); // italics begin + addTokenSubstitute("Fi", "</span>"); + + addTokenSubstitute("FB", "<span class=\"bold\">"); // bold begin + addTokenSubstitute("Fb", "</span>"); + + addTokenSubstitute("FR", "<span class=\"jesuswords\">"); + addTokenSubstitute("Fr", "</span>"); + + addTokenSubstitute("FU", "<u>"); // underline begin + addTokenSubstitute("Fu", "</u>"); + + addTokenSubstitute("FO", "<span class=\"quotation\">"); // Old Testament quote begin + addTokenSubstitute("Fo", "</span>"); + + + addTokenSubstitute("FS", "<span class=\"sup\">"); // Superscript begin// Subscript begin + addTokenSubstitute("Fs", "</span>"); + + addTokenSubstitute("FV", "<span class=\"sub\">"); // Subscript begin + addTokenSubstitute("Fv", "</span>"); + + addTokenSubstitute("TT", "<div class=\"booktitle\">"); + addTokenSubstitute("Tt", "</div>"); + + addTokenSubstitute("TS", "<div class=\"sectiontitle\">"); + addTokenSubstitute("Ts", "</div>"); + + //addTokenSubstitute("PP", "<span class=\"poetry\">"); // poetry begin + //addTokenSubstitute("Pp", "</span>"); + + + addTokenSubstitute("Fn", "</font>"); // font end + addTokenSubstitute("CL", "<br/>"); // new line + addTokenSubstitute("CM", "<br/>"); // paragraph <!P> is a non showing comment that can be changed in the front end to <P> if desired + + addTokenSubstitute("CG", ">"); // literal greater-than sign + addTokenSubstitute("CT", "<"); // literal less-than sign + + addTokenSubstitute("JR", "<span class=\"right\">"); // right align begin + addTokenSubstitute("JC", "<span class=\"center\">"); // center align begin + addTokenSubstitute("JL", "</span>"); // align end +} + +/** No descriptions */ +char Filters::GbfToHtml::processText(sword::SWBuf& buf, const sword::SWKey * key, const sword::SWModule * module) { + GBFHTML::processText(buf, key, module); + + if (!module->isProcessEntryAttributes()) { + return 1; //no processing should be done, may happen in a search + } + + CSwordModuleInfo* m = CSwordBackend::instance()->findModuleByName( module->Name() ); + + if (m && !(m->has(CSwordModuleInfo::lemmas) || m->has(CSwordModuleInfo::morphTags) || m->has(CSwordModuleInfo::strongNumbers))) { //only parse if the module has strongs or lemmas + return 1; //WARNING: Return alread here + } + + //Am Anfang<WH07225> schuf<WH01254><WTH8804> Gott<WH0430> Himmel<WH08064> und<WT> Erde<WH0776>. + //A simple word<WT> means: No entry for this word "word" + QString result; + + QString t = QString::fromUtf8(buf.c_str()); + + QRegExp tag("([.,;:]?<W[HGT][^>]*>\\s*)+"); + + QStringList list; + + int lastMatchEnd = 0; + + int pos = tag.indexIn(t, 0); + + if (pos == -1) { //no strong or morph code found in this text + return 1; //WARNING: Return already here + } + + //split the text into parts which end with the GBF tag marker for strongs/lemmas + while (pos != -1) { + list.append(t.mid(lastMatchEnd, pos + tag.matchedLength() - lastMatchEnd)); + + lastMatchEnd = pos + tag.matchedLength(); + pos = tag.indexIn(t, pos + tag.matchedLength()); + } + + //append the trailing text to the list. + if (!t.right(t.length() - lastMatchEnd).isEmpty()) { + list.append(t.right(t.length() - lastMatchEnd)); + } + + //list is now a list of words with 1-n Strongs at the end, which belong to this word. + + //now create the necessary HTML in list entries and concat them to the result + tag = QRegExp("<W([HGT])([^>]*)>"); + tag.setMinimal(true); + + for (QStringList::iterator it = list.begin(); it != list.end(); ++it) { + QString e = (*it); //current entry to process + //qWarning(e.latin1()); + + //check if there is a word to which the strongs info belongs to. + //If yes, wrap that word with the strongs info + //If not, leave out the strongs info, because it can't be tight to a text + //Comparing the first char with < is not enough, because the tokenReplace is done already + //so there might be html tags already. + const bool textPresent = (e.trimmed().remove(QRegExp("[.,;:]")).left(2) != "<W"); + + if (!textPresent) { + result += (*it); + continue; + } + + int pos = tag.indexIn(e, 0); //try to find a strong number marker + bool insertedTag = false; + bool hasLemmaAttr = false; + bool hasMorphAttr = false; + + QString value = QString::null; + int tagAttributeStart = -1; + + while (pos != -1) { //work on all strong/lemma tags in this section, should be between 1-3 loops + const bool isMorph = (tag.cap(1) == "T"); + value = isMorph ? tag.cap(2) : tag.cap(2).prepend( tag.cap(1) ); + + if (value.isEmpty()) { + break; + } + + //insert the span + if (!insertedTag) { //we have to insert a new tag end and beginning, i.e. our first loop + e.replace(pos, tag.matchedLength(), "</span>"); + pos += 7; + + //skip blanks, commas, dots and stuff at the beginning, it doesn't belong to the morph code + QString rep("<span "); + rep.append(isMorph ? "morph" : "lemma").append("=\"").append(value).append("\">"); + + hasMorphAttr = isMorph; + hasLemmaAttr = !isMorph; + + int startPos = 0; + QChar c = e[startPos]; + + while ((startPos < pos) && (c.isSpace() || c.isPunct())) { + ++startPos; + + c = e[startPos]; + } + + e.insert( startPos, rep ); + tagAttributeStart = startPos + 6; //to point to the start of the attributes + pos += rep.length(); + } + else { //add the attribute to the existing tag + e.remove(pos, tag.matchedLength()); + + if (tagAttributeStart == -1) { + continue; //nothing valid found + } + + if ((!isMorph && hasLemmaAttr) || (isMorph && hasMorphAttr)) { //we append another attribute value, e.g. 3000 gets 3000|5000 + //search the existing attribute start + QRegExp attrRegExp( isMorph ? "morph=\".+(?=\")" : "lemma=\".+(?=\")" ); + attrRegExp.setMinimal(true); + const int foundPos = e.indexOf(attrRegExp, tagAttributeStart); + + if (foundPos != -1) { + e.insert(foundPos + attrRegExp.matchedLength(), QString("|").append(value)); + pos += value.length() + 1; + + hasLemmaAttr = !isMorph; + hasMorphAttr = isMorph; + } + } + else { //attribute was not yet inserted + QString attr = QString(isMorph ? "morph" : "lemma").append("=\"").append(value).append("\" "); + + e.insert(tagAttributeStart, attr); + pos += attr.length(); + + hasMorphAttr = isMorph; + hasLemmaAttr = !isMorph; + } + + //tagAttributeStart remains the same + } + + insertedTag = true; + pos = tag.indexIn(e, pos); + } + + result += e; + } + + if (list.count()) { + buf = (const char*)result.toUtf8().constData(); + } + + return 1; +} + +bool Filters::GbfToHtml::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { + if (!substituteToken(buf, token)) { //more than a simple replace + const unsigned int tokenLength = strlen(token); + + UserData* myUserData = dynamic_cast<UserData*>(userData); + sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack to be able to call stuff like Lang() + + if ( !strncmp(token, "WG", 2) + || !strncmp(token, "WH", 2) + || !strncmp(token, "WT", 2) ) { + buf.append('<'); + buf.append(token); + buf.append('>'); + } + else if (!strncmp(token, "RB", 2)) { + myUserData->hasFootnotePreTag = true; + buf.append("<span class=\"footnotepre\">"); + } + else if (!strncmp(token, "RF", 2)) { + //we use several append calls because appendFormatted slows down filtering, which should be fast + + if (myUserData->hasFootnotePreTag) { + // qWarning("inserted footnotepre end"); + buf.append("</span>"); + myUserData->hasFootnotePreTag = false; + } + + buf.append(" <span class=\"footnote\" note=\""); + buf.append(myModule->Name()); + buf.append('/'); + buf.append(myUserData->key->getShortText()); + buf.append('/'); + buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); + buf.append("\">*</span> "); + + userData->suspendTextPassThru = true; + } + else if (!strncmp(token, "Rf", 2)) { //end of footnote + userData->suspendTextPassThru = false; + } + else if (!strncmp(token, "FN", 2)) { //the end </font> tag is inserted in addTokenSubsitute + buf.append("<font face=\""); + + for (unsigned long i = 2; i < tokenLength; i++) { + if (token[i] != '\"') { + buf.append( token[i] ); + } + } + + buf.append("\">"); + } + else if (!strncmp(token, "CA", 2)) { // ASCII value + buf.append( (char)atoi(&token[2]) ); + } + else { + return GBFHTML::handleToken(buf, token, userData); + } + } + + return true; +} diff --git a/src/backend/filters/gbftohtml.h b/src/backend/filters/gbftohtml.h new file mode 100644 index 0000000..fbe5db2 --- /dev/null +++ b/src/backend/filters/gbftohtml.h @@ -0,0 +1,61 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef FILTERS_GBFTOHTML_H +#define FILTERS_GBFTOHTML_H + +// Sword includes: +#include <gbfhtml.h> + + +namespace Filters { + +/** + \brief GBF to HTML conversion filter. +*/ +class GbfToHtml: public sword::GBFHTML { + protected: /* Types: */ + class UserData: public sword::GBFHTML::MyUserData { + public: + inline UserData(const sword::SWModule *module, + const sword::SWKey *key) + : sword::GBFHTML::MyUserData(module, key), + swordFootnote(1) + { + hasFootnotePreTag = false; + } + + short unsigned int swordFootnote; + }; + + public: /* Methods: */ + GbfToHtml(); + + /** Reimplemented from sword::OSISHTMLHREF. */ + virtual bool handleToken(sword::SWBuf &buf, + const char *token, + sword::BasicFilterUserData *userData); + + /** Reimplemented from sword::SWFilter. */ + virtual char processText(sword::SWBuf &buf, + const sword::SWKey *key, + const sword::SWModule *module = 0); + + protected: /* Methods: */ + /** Reimplemented from sword::OSISHTMLHREF. */ + virtual inline sword::BasicFilterUserData *createUserData( + const sword::SWModule *module, const sword::SWKey *key) + { + return new UserData(module, key); + } +}; + +} // namespace Filters + +#endif diff --git a/src/backend/filters/osismorphsegmentation.cpp b/src/backend/filters/osismorphsegmentation.cpp index 512fe2e..421b63e 100644 --- a/src/backend/filters/osismorphsegmentation.cpp +++ b/src/backend/filters/osismorphsegmentation.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -67,7 +67,7 @@ char Filters::OSISMorphSegmentation::processText(sword::SWBuf &text, const sword text.append(token); text.append('>'); - // hide = false; //not right, because there may be child tags in seg. Only /seg may disable the seg hiding. + // hide = false; //not right, because there may be child tags in seg. Only /seg may disable the seg hiding. continue; } //end of intoken part diff --git a/src/backend/filters/osismorphsegmentation.h b/src/backend/filters/osismorphsegmentation.h index c5bbb18..4843488 100644 --- a/src/backend/filters/osismorphsegmentation.h +++ b/src/backend/filters/osismorphsegmentation.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/backend/filters/osistohtml.cpp b/src/backend/filters/osistohtml.cpp new file mode 100644 index 0000000..c04c820 --- /dev/null +++ b/src/backend/filters/osistohtml.cpp @@ -0,0 +1,595 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/filters/osistohtml.h" + +#include <QString> +#include "backend/config/cbtconfig.h" +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/clanguagemgr.h" +#include "backend/managers/referencemanager.h" + +// Sword includes: +#include <swbuf.h> +#include <swmodule.h> +#include <utilxml.h> + + +Filters::OsisToHtml::OsisToHtml() : sword::OSISHTMLHREF() { + setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes + + addTokenSubstitute("inscription", "<span class=\"inscription\">"); + addTokenSubstitute("/inscription", "</span>"); + + addTokenSubstitute("mentioned", "<span class=\"mentioned\">"); + addTokenSubstitute("/mentioned", "</span>"); + +// addTokenSubstitute("divineName", "<span class=\"name\"><span class=\"divine\">"); +// addTokenSubstitute("/divineName", "</span></span>"); + + /// \todo Move that down to the real tag handling, segs without the type morph would generate incorrect markup, as the end span is always inserted +// addTokenSubstitute("seg type=\"morph\"", "<span class=\"morphSegmentation\">"); +// addTokenSubstitute("/seg", "</span>"); + + // OSIS tables + addTokenSubstitute("table", "<table>"); + addTokenSubstitute("/table", "</table>"); + addTokenSubstitute("row", "<tr>"); + addTokenSubstitute("/row", "</tr>"); + addTokenSubstitute("cell", "<td>"); + addTokenSubstitute("/cell", "</td>"); + +} + +bool Filters::OsisToHtml::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { + // manually process if it wasn't a simple substitution + + if (!substituteToken(buf, token)) { + UserData* myUserData = dynamic_cast<UserData*>(userData); + sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack + + sword::XMLTag tag(token); + // qWarning("found %s", token); + const bool osisQToTick = ((!userData->module->getConfigEntry("OSISqToTick")) || (strcmp(userData->module->getConfigEntry("OSISqToTick"), "false"))); + + if (!tag.getName()) { + return false; + } + + // <div> tag + if (!strcmp(tag.getName(), "div")) { + //handle intro + + if ((!tag.isEmpty()) && (!tag.isEndTag())) { //start tag + sword::SWBuf type( tag.getAttribute("type") ); + + if (type == "introduction") { + buf.append("<div class=\"introduction\">"); + } + else if (type == "chapter") { + buf.append("<div class=\"chapter\" />"); //don't open a div here, that would lead to a broken XML structure + } + else { + buf.append("<div>"); + } + } + else if (tag.isEndTag()) { //end tag + buf.append("</div>"); + } + } + else if (!strcmp(tag.getName(), "w")) { + if ((!tag.isEmpty()) && (!tag.isEndTag())) { //start tag + const char *attrib; + const char *val; + + sword::XMLTag outTag("span"); + sword::SWBuf attrValue; + + if ((attrib = tag.getAttribute("xlit"))) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + outTag.setAttribute("xlit", val); + } + + if ((attrib = tag.getAttribute("gloss"))) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + outTag.setAttribute("gloss", val); + } + + if ((attrib = tag.getAttribute("lemma"))) { + char splitChar = '|'; + const int countSplit1 = tag.getAttributePartCount("lemma", '|'); + const int countSplit2 = tag.getAttributePartCount("lemma", ' '); /// \todo not allowed, remove soon + int count = 0; + + if (countSplit1 > countSplit2) { //| split char + splitChar = '|'; /// \todo not allowed, remove soon + count = countSplit1; + } + else { + splitChar = ' '; + count = countSplit2; + } + + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + attrValue = ""; + + do { + if (attrValue.length()) { + attrValue.append( '|' ); + } + + attrib = tag.getAttribute("lemma", i, splitChar); + + if (i < 0) { // to handle our -1 condition + i = 0; + } + + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + + attrValue.append(val); + } + while (++i < count); + + if (attrValue.length()) { + outTag.setAttribute("lemma", attrValue.c_str()); + } + } + + if ((attrib = tag.getAttribute("morph"))) { + char splitChar = '|'; + const int countSplit1 = tag.getAttributePartCount("morph", '|'); + const int countSplit2 = tag.getAttributePartCount("morph", ' '); /// \todo not allowed, remove soon + int count = 0; + + if (countSplit1 > countSplit2) { //| split char + splitChar = '|'; + count = countSplit1; + } + else { + splitChar = ' '; + count = countSplit2; + } + + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + + attrValue = ""; + + do { + if (attrValue.length()) { + attrValue.append('|'); + } + + attrib = tag.getAttribute("morph", i, splitChar); + + if (i < 0) { + i = 0; // to handle our -1 condition + } + + val = strchr(attrib, ':'); + + if (val) { //the prefix gives the modulename + //check the prefix + if (!strncmp("robinson:", attrib, 9)) { //robinson + attrValue.append( "Robinson:" ); //work is not the same as Sword's module name + attrValue.append( val + 1 ); + } + //strongs is handled by BibleTime + /*else if (!strncmp("strongs", attrib, val-atrrib)) { + attrValue.append( !strncmp(attrib, "x-", 2) ? attrib+2 : attrib ); + }*/ + else { + attrValue.append( !strncmp(attrib, "x-", 2) ? attrib + 2 : attrib ); + } + } + else { //no prefix given + val = attrib; + const bool skipFirst = ((val[0] == 'T') && ((val[1] == 'H') || (val[1] == 'H'))); + attrValue.append( skipFirst ? val + 1 : val ); + } + } + while (++i < count); + + if (attrValue.length()) { + outTag.setAttribute("morph", attrValue.c_str()); + } + } + + if ((attrib = tag.getAttribute("POS"))) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + outTag.setAttribute("pos", val); + } + + buf.append( outTag.toString() ); + } + else if (tag.isEndTag()) { // end or empty <w> tag + buf.append("</span>"); + } + } + + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { //start tag + const sword::SWBuf type( tag.getAttribute("type") ); + + if (type == "crossReference") { //note containing cross references + myUserData->inCrossrefNote = true; + myUserData->noteType = UserData::CrossReference; + + /* + * Do not count crossrefs as footnotes if they are displayed in the text. This will cause problems + * with footnote numbering when crossrefs are turned on/off. + * When accessing footnotes, crossrefs must be turned off in the filter so that they are not in the entry + * attributes of Sword. + * + * //myUserData->swordFootnote++; // cross refs count as notes, too + */ + + buf.append("<span class=\"crossreference\">"); + sword::SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + sword::SWBuf footnoteBody = myUserData->entryAttributes["Footnote"][footnoteNumber]["body"]; + buf += myModule->RenderText(footnoteBody); + } + + /* else if (type == "explanation") { + } + */ + else if ((type == "strongsMarkup") || (type == "x-strongsMarkup")) { + /** + * leave strong's markup notes out, in the future we'll probably have + * different option filters to turn different note types on or off + */ + + myUserData->suspendTextPassThru = true; + myUserData->noteType = UserData::StrongsMarkup; + } + + else { + // qWarning("found note in %s", myUserData->key->getShortText()); + buf.append(" <span class=\"footnote\" note=\""); + buf.append(myModule->Name()); + buf.append('/'); + buf.append(myUserData->key->getShortText()); + buf.append('/'); + buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); //inefficient + + const sword::SWBuf n = tag.getAttribute("n"); + + buf.append("\">"); + buf.append( (n.length() > 0) ? n.c_str() : "*" ); + buf.append("</span> "); + + myUserData->noteType = UserData::Footnote; + myUserData->suspendTextPassThru = true; + } + } + else { //if (tag.isEndTag()) { + Q_ASSERT(myUserData->noteType != UserData::Unknown); + + if (myUserData->noteType == UserData::CrossReference) { + buf.append("</span> "); +// myUserData->suspendTextPassThru = false; + myUserData->inCrossrefNote = false; + } + + myUserData->noteType = UserData::Unknown; + myUserData->suspendTextPassThru = false; + } + } + // The <p> paragraph tag is handled by OSISHTMLHref + else if (!strcmp(tag.getName(), "reference")) { // <reference> tag + if (!tag.isEndTag() && !tag.isEmpty()) { + + renderReference(tag.getAttribute("osisRef"), buf, myModule, myUserData); + + } + else if (tag.isEndTag()) { + buf.append("</a>"); + } + else { // empty reference marker + // -- what should we do? nothing for now. + } + } + + // <l> is handled by OSISHTMLHref + // <title> + else if (!strcmp(tag.getName(), "title")) { + if (!tag.isEndTag() && !tag.isEmpty()) { + buf.append("<div class=\"sectiontitle\">"); + } + else if (tag.isEndTag()) { + buf.append("</div>"); + } + else { // empty title marker + // what to do? is this even valid? + buf.append("<br/>"); + } + } + + // <hi> highlighted text + else if (!strcmp(tag.getName(), "hi")) { + const sword::SWBuf type = tag.getAttribute("type"); + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + if (type == "bold") { + buf.append("<span class=\"bold\">"); + } + else if (type == "illuminated") { + buf.append("<span class=\"illuminated\">"); + } + else if (type == "italic") { + buf.append("<span class=\"italic\">"); + } + else if (type == "line-through") { + buf.append("<span class=\"line-through\">"); + } + else if (type == "normal") { + buf.append("<span class=\"normal\">"); + } + else if (type == "small-caps") { + buf.append("<span class=\"small-caps\">"); + } + else if (type == "underline") { + buf.append("<span class=\"underline\">"); + } + else { + buf.append("<span>"); //don't break markup, </span> is inserted later + } + } + else if (tag.isEndTag()) { //all hi replacements are html spans + buf.append("</span>"); + } + } + + //name + else if (!strcmp(tag.getName(), "name")) { + const sword::SWBuf type = tag.getAttribute("type"); + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + if (type == "geographic") { + buf.append("<span class=\"name\"><span class=\"geographic\">"); + } + else if (type == "holiday") { + buf.append("<span class=\"name\"><span class=\"holiday\">"); + } + else if (type == "nonhuman") { + buf.append("<span class=\"name\"><span class=\"nonhuman\">"); + } + else if (type == "person") { + buf.append("<span class=\"name\"><span class=\"person\">"); + } + else if (type == "ritual") { + buf.append("<span class=\"name\"><span class=\"ritual\">"); + } + else { + buf.append("<span class=\"name\"><span>"); + } + } + else if (tag.isEndTag()) { //all hi replacements are html spans + buf.append("</span></span> "); + } + } + else if (!strcmp(tag.getName(), "transChange")) { + sword::SWBuf type( tag.getAttribute("type") ); + + if ( !type.length() ) { + type = tag.getAttribute("changeType"); + } + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + if (type == "added") { + buf.append("<span class=\"transchange\" title=\""); + buf.append(QObject::tr("Added text").toUtf8().constData()); + buf.append("\"><span class=\"added\">"); + } + else if (type == "amplified") { + buf.append("<span class=\"transchange\"><span class=\"amplified\">"); + } + else if (type == "changed") { + buf.append("<span class=\"transchange\"><span class=\"changed\">"); + } + else if (type == "deleted") { + buf.append("<span class=\"transchange\"><span class=\"deleted\">"); + } + else if (type == "moved") { + buf.append("<span class=\"transchange\"><span class=\"moved\">"); + } + else if (type == "tenseChange") { + buf.append("<span class=\"transchange\" title=\""); + buf.append(QObject::tr("Verb tense changed").toUtf8().constData()); + buf.append("\"><span class=\"tenseChange\">"); + } + else { + buf.append("<span class=\"transchange\"><span>"); + } + } + else if (tag.isEndTag()) { //all hi replacements are html spans + buf.append("</span></span>"); + } + } + else if (!strcmp(tag.getName(), "p")) { + if (tag.isEmpty()) { + buf.append("<p/>"); + } + } + + // <q> quote + else if (!strcmp(tag.getName(), "q")) { + //sword::SWBuf type = tag.getAttribute("type"); + sword::SWBuf who = tag.getAttribute("who"); + const char *lev = tag.getAttribute("level"); + int level = (lev) ? atoi(lev) : 1; + sword::SWBuf quoteMarker = tag.getAttribute("marker"); + + if ((!tag.isEndTag())) { + if (!tag.isEmpty()) { + myUserData->quote.who = who; + } + + if (quoteMarker.size() > 0) { + buf.append(quoteMarker); + } + else if (osisQToTick) //alternate " and ' + buf.append((level % 2) ? '\"' : '\''); + + if (who == "Jesus") { + buf.append("<span class=\"jesuswords\">"); + } + } + else if (tag.isEndTag()) { + if (myUserData->quote.who == "Jesus") { + buf.append("</span>"); + } + if (quoteMarker.size() > 0) { + buf.append(quoteMarker); + } + else if (osisQToTick) { //alternate " and ' + buf.append((level % 2) ? '\"' : '\''); + } + + myUserData->quote.who = ""; + } + } + + // abbr tag + else if (!strcmp(tag.getName(), "abbr")) { + if (!tag.isEndTag() && !tag.isEmpty()) { + const sword::SWBuf expansion = tag.getAttribute("expansion"); + + buf.append("<span class=\"abbreviation\" expansion=\""); + buf.append(expansion); + buf.append("\">"); + } + else if (tag.isEndTag()) { + buf.append("</span>"); + } + } + + // <milestone> tag + else if (!strcmp(tag.getName(), "milestone")) { + const sword::SWBuf type = tag.getAttribute("type"); + + if ((type == "screen") || (type == "line")) {//line break + buf.append("<br/>"); + userData->supressAdjacentWhitespace = true; + } + else if (type == "x-p") { //e.g. occurs in the KJV2006 module + //buf.append("<br/>"); + const sword::SWBuf marker = tag.getAttribute("marker"); + if (marker.length() > 0) { + buf.append(marker); + } + } + } + //seg tag + else if (!strcmp(tag.getName(), "seg")) { + if (!tag.isEndTag() && !tag.isEmpty()) { + + const sword::SWBuf type = tag.getAttribute("type"); + + if (type == "morph") {//line break + //This code is for WLC and MORPH (WHI) + sword::XMLTag outTag("span"); + outTag.setAttribute("class", "morphSegmentation"); + const char* attrValue; + //Transfer the values to the span + //Problem: the data is in hebrew/aramaic, how to encode in HTML/BibleTime? + if ((attrValue = tag.getAttribute("lemma"))) outTag.setAttribute("lemma", attrValue); + if ((attrValue = tag.getAttribute("morph"))) outTag.setAttribute("morph", attrValue); + if ((attrValue = tag.getAttribute("homonym"))) outTag.setAttribute("homonym", attrValue); + + buf.append(outTag.toString()); + //buf.append("<span class=\"morphSegmentation\">"); + } + else { + buf.append("<span>"); + } + } + else { // seg end tag + buf.append("</span>"); + } + //qWarning(QString("handled <seg> token. result: %1").arg(buf.c_str()).latin1()); + } + + //divine name, don't use simple tag replacing because it may have attributes + else if (!strcmp(tag.getName(), "divineName")) { + if (!tag.isEndTag()) { + buf.append("<span class=\"name\"><span class=\"divine\">"); + } + else { //all hi replacements are html spans + buf.append("</span></span>"); + } + } + + else { //all tokens handled by OSISHTMLHref will run through the filter now + return sword::OSISHTMLHREF::handleToken(buf, token, userData); + } + } + + return false; +} + +void Filters::OsisToHtml::renderReference(const char *osisRef, sword::SWBuf &buf, sword::SWModule *myModule, UserData *myUserData) { + QString ref( osisRef ); + QString hrefRef( ref ); + //Q_ASSERT(!ref.isEmpty()); checked later + + if (!ref.isEmpty()) { + //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default. + //If the osisRef is something like "ModuleID:key comes here" then the + // modulename is given, so we'll use that one + + CSwordModuleInfo* mod = CSwordBackend::instance()->findSwordModuleByPointer(myModule); + //Q_ASSERT(mod); checked later + if (!mod || (mod->type() != CSwordModuleInfo::Bible + && mod->type() != CSwordModuleInfo::Commentary)) { + + mod = CBTConfig::get( CBTConfig::standardBible ); + } + + // Q_ASSERT(mod); There's no necessarily a module or standard Bible + + //if the osisRef like "GerLut:key" contains a module, use that + int pos = ref.indexOf(":"); + + if ((pos >= 0) && ref.at(pos - 1).isLetter() && ref.at(pos + 1).isLetter()) { + QString newModuleName = ref.left(pos); + hrefRef = ref.mid(pos + 1); + + if (CSwordBackend::instance()->findModuleByName(newModuleName)) { + mod = CSwordBackend::instance()->findModuleByName(newModuleName); + } + } + + if (mod) { + ReferenceManager::ParseOptions options; + options.refBase = QString::fromUtf8(myUserData->key->getText()); + options.refDestinationModule = QString(mod->name()); + options.sourceLanguage = QString(myModule->Lang()); + options.destinationLanguage = QString("en"); + + buf.append("<a href=\""); + buf.append( //create the hyperlink with key and mod + ReferenceManager::encodeHyperlink( + mod->name(), + ReferenceManager::parseVerseReference(hrefRef, options), + ReferenceManager::typeFromModule(mod->type()) + ).toUtf8().constData() + ); + buf.append("\" crossrefs=\""); + buf.append((const char*)ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any + buf.append("\">"); + } + // should we add something if there were no referenced module available? + } +} + diff --git a/src/backend/filters/osistohtml.h b/src/backend/filters/osistohtml.h new file mode 100644 index 0000000..ca36fe6 --- /dev/null +++ b/src/backend/filters/osistohtml.h @@ -0,0 +1,75 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef FILTERS_OSISTOHTML_H +#define FILTERS_OSISTOHTML_H + +// Sword includes: +#include <osishtmlhref.h> +#include <swbuf.h> +#include <swmodule.h> + +namespace Filters { + +/** + \brief OSIS to HTMl conversion filter. +*/ +class OsisToHtml: public sword::OSISHTMLHREF { + protected: /* Types: */ + class UserData: public sword::OSISHTMLHREF::MyUserData { + public: + inline UserData(const sword::SWModule *module, + const sword::SWKey *key) + : sword::OSISHTMLHREF::MyUserData(module, key), + swordFootnote(1), inCrossrefNote(false), + entryAttributes(module->getEntryAttributes()), + noteType(Unknown) {} + + unsigned short int swordFootnote; + bool inCrossrefNote; + sword::AttributeTypeList entryAttributes; + + enum NoteType { + Unknown, + Alternative, + CrossReference, + Footnote, + StrongsMarkup + } noteType; + + struct { + sword::SWBuf who; + } quote; + }; + + public: /* Methods: */ + OsisToHtml(); + + /** Reimplemented from sword::OSISHTMLHREF. */ + virtual bool handleToken(sword::SWBuf &buf, + const char *token, + sword::BasicFilterUserData *userData); + + protected: /* Methods: */ + /** Reimplemented from sword::OSISHTMLHREF. */ + virtual inline sword::BasicFilterUserData *createUserData( + const sword::SWModule *module, + const sword::SWKey *key) + { + return new UserData(module, key); + } + + private: /* Methods: */ + void renderReference(const char *osisRef, sword::SWBuf &buf, + sword::SWModule *myModule, UserData *myUserData); +}; + +} // namespace Filters + +#endif diff --git a/src/backend/filters/plaintohtml.cpp b/src/backend/filters/plaintohtml.cpp new file mode 100644 index 0000000..bc19440 --- /dev/null +++ b/src/backend/filters/plaintohtml.cpp @@ -0,0 +1,69 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/filters/plaintohtml.h" + + +Filters::PlainToHtml::PlainToHtml() : sword::SWFilter() { +} + +/** No descriptions */ +char Filters::PlainToHtml::processText(sword::SWBuf& text, const sword::SWKey* /*key*/, const sword::SWModule* /*module*/) { + int count = 0; + + sword::SWBuf orig = text; + const char *from = orig.c_str(); + for (text = ""; *from; from++) { + if ((*from == '\n') && (from[1] == '\n')) { // two newlinea are a paragraph + text += "<P>"; + from++; + continue; + } + //This is a special case: Newlines in the plaintext editor are stored as <br />, not as \n + //we need to let them through + else if ((*from == '<') && (from[1] == 'b') && (from[2] == 'r') && (from[3] == ' ') && (from[4] == '/') && (from[5] == '>')) { + text += "<br />"; + from += 5; + continue; + } + else if ((*from == '\n')) { // only one new line + text += "<br/>"; + continue; + } + else if (*from == '<') { + text += "<"; + continue; + } + else if (*from == '>') { + text += ">"; + continue; + } + else if (*from == '&') { + text += "&"; + continue; + } + else if (*from == '{') { //footnote start + text += "<font color=\"#800000\"><small> ("; /// \bug Possible color conflict + continue; + } + else if (*from == '}') { //footnote end + text += ") </small></font>"; + continue; + } + else if ((*from == ' ') && (count > 5000)) { + text += "<wbr/>"; + count = 0; + continue; + } + + text += *from; + count++; + } + return 0; +} diff --git a/src/backend/filters/plaintohtml.h b/src/backend/filters/plaintohtml.h new file mode 100644 index 0000000..1093e2c --- /dev/null +++ b/src/backend/filters/plaintohtml.h @@ -0,0 +1,40 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef FILTERS_PLAINTOHTML_H +#define FILTERS_PLAINTOHTML_H + +// Sword includes: +#include <swbuf.h> +#include <swfilter.h> + +namespace sword { + class SWKey; + class SWModule; +} + +namespace Filters { + +/** + \brief Plain text to HTML conversion filter. +*/ +class PlainToHtml: public sword::SWFilter { + public: /* Methods: */ + PlainToHtml(); + + protected: /* Methods: */ + /** Reimplemented from sword::SWFilter. */ + virtual char processText(sword::SWBuf &buf, + const sword::SWKey *key, + const sword::SWModule *module = 0); +}; + +} // namespace Filters + +#endif diff --git a/src/backend/filters/teitohtml.cpp b/src/backend/filters/teitohtml.cpp new file mode 100644 index 0000000..4b390d5 --- /dev/null +++ b/src/backend/filters/teitohtml.cpp @@ -0,0 +1,150 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/filters/teitohtml.h" + +#include <QString> +#include "backend/config/cbtconfig.h" +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/clanguagemgr.h" +#include "backend/managers/referencemanager.h" + +// Sword includes: +#include <swbuf.h> +#include <swmodule.h> +#include <utilxml.h> + + +namespace Filters { + +TeiToHtml::TeiToHtml() + : sword::TEIHTMLHREF() +{ + setPassThruUnknownEscapeString(true); // the HTML widget will render the HTML escape codes +} + +bool TeiToHtml::handleToken(sword::SWBuf &buf, const char *token, + sword::BasicFilterUserData *userData) +{ + // manually process if it wasn't a simple substitution + + if (!substituteToken(buf, token)) { + + sword::XMLTag tag(token); + + if (0) { + + } + else if (!strcmp(tag.getName(), "ref")) { + + if (!tag.isEndTag() && !tag.isEmpty()) { + + renderReference(tag.getAttribute("osisRef"), buf, userData); + + } + else if (tag.isEndTag()) { + buf.append("</a>"); + } + else { // empty reference marker + // -- what should we do? nothing for now. + } + } + // <hi> highlighted text + else if (!strcmp(tag.getName(), "hi")) { + const sword::SWBuf type = tag.getAttribute("rend"); + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + if (type == "bold") { + buf.append("<span class=\"bold\">"); + } + else if (type == "illuminated") { + buf.append("<span class=\"illuminated\">"); + } + else if (type == "italic") { + buf.append("<span class=\"italic\">"); + } + else if (type == "line-through") { + buf.append("<span class=\"line-through\">"); + } + else if (type == "normal") { + buf.append("<span class=\"normal\">"); + } + else if (type == "small-caps") { + buf.append("<span class=\"small-caps\">"); + } + else if (type == "underline") { + buf.append("<span class=\"underline\">"); + } + else { + buf.append("<span>"); //don't break markup, </span> is inserted later + } + } + else if (tag.isEndTag()) { //all hi replacements are html spans + buf.append("</span>"); + } + } + else { //all tokens handled by OSISHTMLHref will run through the filter now + return sword::TEIHTMLHREF::handleToken(buf, token, userData); + } + } + + return false; +} + +void TeiToHtml::renderReference(const char *osisRef, sword::SWBuf &buf, + sword::BasicFilterUserData *myUserData) +{ + QString ref( osisRef ); + QString hrefRef( ref ); + + if (!ref.isEmpty()) { + //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default. + //If the osisRef is something like "ModuleID:key comes here" then the + // modulename is given, so we'll use that one + + CSwordModuleInfo* mod = CBTConfig::get( CBTConfig::standardBible ); + + // Q_ASSERT(mod); There's no necessarily a module or standard Bible + + //if the osisRef like "GerLut:key" contains a module, use that + int pos = ref.indexOf(":"); + + if ((pos >= 0) && ref.at(pos - 1).isLetter() && ref.at(pos + 1).isLetter()) { + QString newModuleName = ref.left(pos); + hrefRef = ref.mid(pos + 1); + + if (CSwordBackend::instance()->findModuleByName(newModuleName)) { + mod = CSwordBackend::instance()->findModuleByName(newModuleName); + } + } + + if (mod) { + ReferenceManager::ParseOptions options; + options.refBase = QString::fromUtf8(myUserData->key->getText()); + options.refDestinationModule = QString(mod->name()); + options.sourceLanguage = QString(mod->module()->Lang()); + options.destinationLanguage = QString("en"); + + buf.append("<a href=\""); + buf.append( //create the hyperlink with key and mod + ReferenceManager::encodeHyperlink( + mod->name(), + ReferenceManager::parseVerseReference(hrefRef, options), + ReferenceManager::typeFromModule(mod->type()) + ).toUtf8().constData() + ); + buf.append("\" crossrefs=\""); + buf.append((const char*)ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any + buf.append("\">"); + } + // should we add something if there were no referenced module available? + } +} + +} // namespace Filters diff --git a/src/backend/filters/teitohtml.h b/src/backend/filters/teitohtml.h new file mode 100644 index 0000000..6fcc2c6 --- /dev/null +++ b/src/backend/filters/teitohtml.h @@ -0,0 +1,37 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef FILTERS_TEITOHTML_H +#define FILTERS_TEITOHTML_H + +// Sword includes: +#include <teihtmlhref.h> +#include <swbuf.h> + +namespace Filters { + +/** + \brief TEI to HTML conversion filter. +*/ +class TeiToHtml: public sword::TEIHTMLHREF { + public: /* Methods: */ + TeiToHtml(); + + /** Reimplemented from sword::OSISHTMLHREF. */ + virtual bool handleToken(sword::SWBuf &buf, const char *token, + sword::BasicFilterUserData *userData); + + private: /* Methods: */ + void renderReference(const char *osisRef, sword::SWBuf &buf, + sword::BasicFilterUserData *myUserData); +}; + +} // namespace Filters + +#endif diff --git a/src/backend/filters/thmltohtml.cpp b/src/backend/filters/thmltohtml.cpp new file mode 100644 index 0000000..703b362 --- /dev/null +++ b/src/backend/filters/thmltohtml.cpp @@ -0,0 +1,392 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/filters/thmltohtml.h" + +#include <QString> +#include <QRegExp> +#include <QUrl> +#include <QTextCodec> +#include "backend/config/cbtconfig.h" +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/clanguagemgr.h" +#include "backend/managers/referencemanager.h" + +// Sword includes: +#include <swmodule.h> +#include <utilstr.h> +#include <utilxml.h> +#include <versekey.h> + + +namespace Filters { + +ThmlToHtml::ThmlToHtml() { + setEscapeStringCaseSensitive(true); + setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes + + setTokenStart("<"); + setTokenEnd(">"); + setTokenCaseSensitive(true); + + addTokenSubstitute("/foreign", "</span>"); + + removeTokenSubstitute("note"); + removeTokenSubstitute("/note"); +} + +char ThmlToHtml::processText(sword::SWBuf &buf, const sword::SWKey *key, + const sword::SWModule *module) +{ + sword::ThMLHTML::processText(buf, key, module); + + CSwordModuleInfo* m = CSwordBackend::instance()->findModuleByName( module->Name() ); + + if (m && !(m->has(CSwordModuleInfo::lemmas) || m->has(CSwordModuleInfo::strongNumbers))) { //only parse if the module has strongs or lemmas + return 1; + } + + QString result; + + QString t = QString::fromUtf8(buf.c_str()); + QRegExp tag("([.,;]?<sync[^>]+(type|value)=\"([^\"]+)\"[^>]+(type|value)=\"([^\"]+)\"([^<]*)>)+"); + + QStringList list; + int lastMatchEnd = 0; + int pos = tag.indexIn(t, 0); + + if (pos == -1) { //no strong or morph code found in this text + return 1; //WARNING: Return alread here + } + + while (pos != -1) { + list.append(t.mid(lastMatchEnd, pos + tag.matchedLength() - lastMatchEnd)); + + lastMatchEnd = pos + tag.matchedLength(); + pos = tag.indexIn(t, pos + tag.matchedLength()); + } + + if (!t.right(t.length() - lastMatchEnd).isEmpty()) { + list.append(t.right(t.length() - lastMatchEnd)); + } + + tag = QRegExp("<sync[^>]+(type|value|class)=\"([^\"]+)\"[^>]+(type|value|class)=\"([^\"]+)\"[^>]+((type|value|class)=\"([^\"]+)\")*([^<]*)>"); + + for (QStringList::iterator it = list.begin(); it != list.end(); ++it) { + QString e( *it ); + + const bool textPresent = (e.trimmed().remove(QRegExp("[.,;:]")).left(1) != "<"); + + if (!textPresent) { + continue; + } + + + bool hasLemmaAttr = false; + bool hasMorphAttr = false; + + int pos = tag.indexIn(e, 0); + bool insertedTag = false; + QString value; + QString valueClass; + + while (pos != -1) { + bool isMorph = false; + bool isStrongs = false; + value = QString::null; + valueClass = QString::null; + + // check 3 attribute/value pairs + + for (int i = 1; i < 6; i += 2) { + if (i > 4) + i++; + + if (tag.cap(i) == "type") { + isMorph = (tag.cap(i + 1) == "morph"); + isStrongs = (tag.cap(i + 1) == "Strongs"); + } + else if (tag.cap(i) == "value") { + value = tag.cap(i + 1); + } + else if (tag.cap(i) == "class") { + valueClass = tag.cap(i + 1); + } + } + + // prepend the class qualifier to the value + if (!valueClass.isEmpty()) { + value = valueClass + ":" + value; + // value.append(":").append(value); + } + + if (value.isEmpty()) { + break; + } + + //insert the span + if (!insertedTag) { + e.replace(pos, tag.matchedLength(), "</span>"); + pos += 7; + + QString rep = QString("<span lemma=\"").append(value).append("\">"); + int startPos = 0; + QChar c = e[startPos]; + + while ((startPos < pos) && (c.isSpace() || c.isPunct())) { + ++startPos; + c = e[startPos]; + } + + hasLemmaAttr = isStrongs; + hasMorphAttr = isMorph; + + e.insert( startPos, rep ); + pos += rep.length(); + } + else { //add the attribute to the existing tag + e.remove(pos, tag.matchedLength()); + + if ((!isMorph && hasLemmaAttr) || (isMorph && hasMorphAttr)) { //we append another attribute value, e.g. 3000 gets 3000|5000 + //search the existing attribute start + QRegExp attrRegExp( isMorph ? "morph=\".+(?=\")" : "lemma=\".+(?=\")" ); + attrRegExp.setMinimal(true); + const int foundAttrPos = e.indexOf(attrRegExp, pos); + + if (foundAttrPos != -1) { + e.insert(foundAttrPos + attrRegExp.matchedLength(), QString("|").append(value)); + pos += value.length() + 1; + + hasLemmaAttr = !isMorph; + hasMorphAttr = isMorph; + } + } + else { //attribute was not yet inserted + const int attrPos = e.indexOf(QRegExp("morph=|lemma="), 0); + + if (attrPos >= 0) { + QString attr; + attr.append(isMorph ? "morph" : "lemma").append("=\"").append(value).append("\" "); + e.insert(attrPos, attr); + + hasMorphAttr = isMorph; + hasLemmaAttr = !isMorph; + + pos += attr.length(); + } + } + } + + insertedTag = true; + pos = tag.indexIn(e, pos); + } + + result.append( e ); + } + + if (list.count()) { + buf = (const char*)result.toUtf8(); + } + + return 1; +} + + +bool ThmlToHtml::handleToken(sword::SWBuf &buf, const char *token, + sword::BasicFilterUserData *userData) +{ + if (!substituteToken(buf, token) && !substituteEscapeString(buf, token)) { + sword::XMLTag tag(token); + UserData* myUserData = dynamic_cast<UserData*>(userData); + sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack to be able to call stuff like Lang() + + if ( tag.getName() && !sword::stricmp(tag.getName(), "foreign") ) { // a text part in another language, we have to set the right font + + if (tag.getAttribute("lang")) { + const char* abbrev = tag.getAttribute("lang"); + //const CLanguageMgr::Language* const language = CLanguageMgr::instance()->languageForAbbrev( QString::fromLatin1(abbrev) ); + + buf.append("<span class=\"foreign\" lang=\""); + buf.append(abbrev); + buf.append("\">"); + } + } + else if (tag.getName() && !sword::stricmp(tag.getName(), "sync")) { //lemmas, morph codes or strongs + + if (tag.getAttribute("type") && (!sword::stricmp(tag.getAttribute("type"), "morph") || !sword::stricmp(tag.getAttribute("type"), "Strongs") || !sword::stricmp(tag.getAttribute("type"), "lemma"))) { // Morph or Strong + buf.append('<'); + buf.append(token); + buf.append('>'); + } + } + else if (tag.getName() && !sword::stricmp(tag.getName(), "note")) { // <note> tag + + if (!tag.isEndTag() && !tag.isEmpty()) { + //appending is faster than appendFormatted + buf.append(" <span class=\"footnote\" note=\""); + buf.append(myModule->Name()); + buf.append('/'); + buf.append(myUserData->key->getShortText()); + buf.append('/'); + buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); + buf.append("\">*</span> "); + + myUserData->suspendTextPassThru = true; + myUserData->inFootnoteTag = true; + } + else if (tag.isEndTag() && !tag.isEmpty()) { //end tag + //buf += ")</span>"; + myUserData->suspendTextPassThru = false; + myUserData->inFootnoteTag = false; + } + } + else if (tag.getName() && !sword::stricmp(tag.getName(), "scripRef")) { // a scripRef + //scrip refs which are embeded in footnotes may not be displayed! + + if (!myUserData->inFootnoteTag) { + if (tag.isEndTag()) { + if (myUserData->inscriptRef) { // like "<scripRef passage="John 3:16">See John 3:16</scripRef>" + buf.append("</a></span>"); + + myUserData->inscriptRef = false; + myUserData->suspendTextPassThru = false; + } + else { // like "<scripRef>John 3:16</scripRef>" + + CSwordModuleInfo* mod = CBTConfig::get(CBTConfig::standardBible); + //Q_ASSERT(mod); tested later + if (mod) { + ReferenceManager::ParseOptions options; + options.refBase = QString::fromUtf8(myUserData->key->getText()); //current module key + options.refDestinationModule = QString(mod->name()); + options.sourceLanguage = QString(myModule->Lang()); + options.destinationLanguage = QString("en"); + + //it's ok to split the reference, because to descriptive text is given + bool insertSemicolon = false; + buf.append("<span class=\"crossreference\">"); + QStringList refs = QString::fromUtf8(myUserData->lastTextNode.c_str()).split(";"); + QString oldRef; //the previous reference to use as a base for the next refs + for (QStringList::iterator it(refs.begin()); it != refs.end(); ++it) { + + if (! oldRef.isEmpty() ) { + options.refBase = oldRef; //use the last ref as a base, e.g. Rom 1,2-3, when the next ref is only 3:3-10 + } + const QString completeRef( ReferenceManager::parseVerseReference((*it), options) ); + + oldRef = completeRef; //use the parsed result as the base for the next ref. + + if (insertSemicolon) { //prepend a ref divider if we're after the first one + buf.append("; "); + } + + buf.append("<a href=\""); + buf.append( + ReferenceManager::encodeHyperlink( + mod->name(), + completeRef, + ReferenceManager::typeFromModule(mod->type()) + ).toUtf8().constData() + ); + + buf.append("\" crossrefs=\""); + buf.append((const char*)completeRef.toUtf8()); + buf.append("\">"); + + buf.append((const char*)(*it).toUtf8()); + + buf.append("</a>"); + + insertSemicolon = true; + } + buf.append("</span>"); //crossref end + } + + myUserData->suspendTextPassThru = false; + } + } + else if (tag.getAttribute("passage") ) { //the passage was given as a parameter value + myUserData->inscriptRef = true; + myUserData->suspendTextPassThru = false; + + const char* ref = tag.getAttribute("passage"); + Q_ASSERT(ref); + + CSwordModuleInfo* mod = CBTConfig::get(CBTConfig::standardBible); + //Q_ASSERT(mod); tested later + + ReferenceManager::ParseOptions options; + options.refBase = QString::fromUtf8(myUserData->key->getText()); + + options.sourceLanguage = myModule->Lang(); + options.destinationLanguage = QString("en"); + + const QString completeRef = ReferenceManager::parseVerseReference(QString::fromUtf8(ref), options); + + if (mod) { + options.refDestinationModule = QString(mod->name()); + buf.append("<span class=\"crossreference\">"); + buf.append("<a href=\""); + buf.append( + ReferenceManager::encodeHyperlink( + mod->name(), + completeRef, + ReferenceManager::typeFromModule(mod->type()) + ).toUtf8().constData() + ); + buf.append("\" crossrefs=\""); + buf.append((const char*)completeRef.toUtf8()); + buf.append("\">"); + } + else { + buf.append("<span><a>"); + } + } + else if ( !tag.getAttribute("passage") ) { // we're starting a scripRef like "<scripRef>John 3:16</scripRef>" + myUserData->inscriptRef = false; + + // let's stop text from going to output, the text get's added in the -tag handler + myUserData->suspendTextPassThru = true; + } + } + } + else if (tag.getName() && !sword::stricmp(tag.getName(), "div")) { + if (tag.isEndTag()) { + buf.append("</div>"); + } + else if ( tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"), "sechead") ) { + buf.append("<div class=\"sectiontitle\">"); + } + else if (tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"), "title")) { + buf.append("<div class=\"booktitle\">"); + } + } + else if (tag.getName() && !sword::stricmp(tag.getName(), "img") && tag.getAttribute("src")) { + const char* value = tag.getAttribute("src"); + + if (value[0] == '/') { + value++; //strip the first / + } + + buf.append("<img src=\""); + QString absPath(QTextCodec::codecForLocale()->toUnicode(myUserData->module->getConfigEntry("AbsoluteDataPath"))); + QString relPath(QString::fromUtf8(value)); + QString url(QUrl::fromLocalFile(absPath.append('/').append(relPath)).toString()); + buf.append(url.toUtf8().data()); + buf.append("\" />"); + } + else { // let unknown token pass thru + return sword::ThMLHTML::handleToken(buf, token, userData); + } + } + + return true; +} + +} // namespace Filtes diff --git a/src/backend/filters/thmltohtml.h b/src/backend/filters/thmltohtml.h new file mode 100644 index 0000000..99bbabb --- /dev/null +++ b/src/backend/filters/thmltohtml.h @@ -0,0 +1,62 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef FILTERS_THMLTOHTML_H +#define FILTERS_THMLTOHTML_H + +// Sword includes: +#include <swbuf.h> +#include <thmlhtml.h> + + +namespace Filters { + +/** + \brief ThML to HTML conversion filter. +*/ +class ThmlToHtml: public sword::ThMLHTML { + protected: /* Types: */ + class UserData: public sword::ThMLHTML::MyUserData { + public: + inline UserData(const sword::SWModule *module, + const sword::SWKey *key) + : sword::ThMLHTML::MyUserData(module, key), + inscriptRef(false), inFootnoteTag(false), + swordFootnote(1) {} + + bool inscriptRef; + bool inFootnoteTag; + unsigned short int swordFootnote; + }; + + public: /* Methods: */ + ThmlToHtml(); + + /** Reimplemented from sword::OSISHTMLHREF. */ + virtual bool handleToken(sword::SWBuf &buf, + const char *token, + sword::BasicFilterUserData *userData); + + /** Reimplemented from sword::SWFilter. */ + virtual char processText(sword::SWBuf &buf, + const sword::SWKey *key, + const sword::SWModule *module = 0); + + protected: /* Methods: */ + /** Reimplemented from sword::OSISHTMLHREF. */ + virtual inline sword::BasicFilterUserData *createUserData( + const sword::SWModule *module, const sword::SWKey *key) + { + return new UserData(module, key); + } +}; + +} // namespace Filters + +#endif diff --git a/src/backend/filters/thmltoplain.cpp b/src/backend/filters/thmltoplain.cpp new file mode 100644 index 0000000..42f383e --- /dev/null +++ b/src/backend/filters/thmltoplain.cpp @@ -0,0 +1,222 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "backend/filters/thmltoplain.h" + +#include <QtGlobal> + + +namespace Filters { + +char ThmlToPlain::processText(sword::SWBuf &text, + const sword::SWKey *key, + const sword::SWModule *module) +{ + Q_UNUSED(key); + Q_UNUSED(module); + + char token[2048]; + int tokpos = 0; + bool intoken = false; + bool ampersand = false; + + const char *from; + sword::SWBuf orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { + if (*from == 10 || *from == 13) + from++; + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + token[1] = 0; + token[2] = 0; + ampersand = false; + continue; + } + else if (*from == '&') { + intoken = true; + tokpos = 0; + token[0] = 0; + token[1] = 0; + token[2] = 0; + ampersand = true; + continue; + } + if (*from == ';' && ampersand) { + intoken = false; + ampersand = false; + + if (!strncmp("nbsp", token, 4)) text += " "; + else if (!strncmp("quot", token, 4)) text += "\""; + else if (!strncmp("amp", token, 3)) text += "&"; + else if (!strncmp("lt", token, 2)) text += "<"; + else if (!strncmp("gt", token, 2)) text += ">"; + else if (!strncmp("brvbar", token, 6)) text += "¦"; + else if (!strncmp("sect", token, 4)) text += "§"; + else if (!strncmp("copy", token, 4)) text += "©"; + else if (!strncmp("laquo", token, 5)) text += "«"; + else if (!strncmp("reg", token, 3)) text += "®"; + else if (!strncmp("acute", token, 5)) text += "´"; + else if (!strncmp("para", token, 4)) text += "¶"; + else if (!strncmp("raquo", token, 5)) text += "»"; + + else if (!strncmp("Aacute", token, 6)) text += "Á"; + else if (!strncmp("Agrave", token, 6)) text += "À"; + else if (!strncmp("Acirc", token, 5)) text += "Â"; + else if (!strncmp("Auml", token, 4)) text += "Ä"; + else if (!strncmp("Atilde", token, 6)) text += "Ã"; + else if (!strncmp("Aring", token, 5)) text += "Å"; + else if (!strncmp("aacute", token, 6)) text += "á"; + else if (!strncmp("agrave", token, 6)) text += "à"; + else if (!strncmp("acirc", token, 5)) text += "â"; + else if (!strncmp("auml", token, 4)) text += "ä"; + else if (!strncmp("atilde", token, 6)) text += "ã"; + else if (!strncmp("aring", token, 5)) text += "å"; + else if (!strncmp("Eacute", token, 6)) text += "É"; + else if (!strncmp("Egrave", token, 6)) text += "È"; + else if (!strncmp("Ecirc", token, 5)) text += "Ê"; + else if (!strncmp("Euml", token, 4)) text += "Ë"; + else if (!strncmp("eacute", token, 6)) text += "é"; + else if (!strncmp("egrave", token, 6)) text += "è"; + else if (!strncmp("ecirc", token, 5)) text += "ê"; + else if (!strncmp("euml", token, 4)) text += "ë"; + else if (!strncmp("Iacute", token, 6)) text += "Í"; + else if (!strncmp("Igrave", token, 6)) text += "Ì"; + else if (!strncmp("Icirc", token, 5)) text += "Î"; + else if (!strncmp("Iuml", token, 4)) text += "Ï"; + else if (!strncmp("iacute", token, 6)) text += "í"; + else if (!strncmp("igrave", token, 6)) text += "ì"; + else if (!strncmp("icirc", token, 5)) text += "î"; + else if (!strncmp("iuml", token, 4)) text += "ï"; + else if (!strncmp("Oacute", token, 6)) text += "Ó"; + else if (!strncmp("Ograve", token, 6)) text += "Ò"; + else if (!strncmp("Ocirc", token, 5)) text += "Ô"; + else if (!strncmp("Ouml", token, 4)) text += "Ö"; + else if (!strncmp("Otilde", token, 6)) text += "Õ"; + else if (!strncmp("oacute", token, 6)) text += "ó"; + else if (!strncmp("ograve", token, 6)) text += "ò"; + else if (!strncmp("ocirc", token, 5)) text += "ô"; + else if (!strncmp("ouml", token, 4)) text += "ö"; + else if (!strncmp("otilde", token, 6)) text += "õ"; + else if (!strncmp("Uacute", token, 6)) text += "Ú"; + else if (!strncmp("Ugrave", token, 6)) text += "Ù"; + else if (!strncmp("Ucirc", token, 5)) text += "Û"; + else if (!strncmp("Uuml", token, 4)) text += "Ü"; + else if (!strncmp("uacute", token, 6)) text += "ú"; + else if (!strncmp("ugrave", token, 6)) text += "ù"; + else if (!strncmp("ucirc", token, 5)) text += "û"; + else if (!strncmp("uuml", token, 4)) text += "ü"; + else if (!strncmp("Yacute", token, 6)) text += "Ý"; + else if (!strncmp("yacute", token, 6)) text += "ý"; + else if (!strncmp("yuml", token, 4)) text += "ÿ"; + + else if (!strncmp("deg", token, 3)) text += "°"; + else if (!strncmp("plusmn", token, 6)) text += "±"; + else if (!strncmp("sup2", token, 4)) text += "²"; + else if (!strncmp("sup3", token, 4)) text += "³"; + else if (!strncmp("sup1", token, 4)) text += "¹"; + else if (!strncmp("nbsp", token, 4)) text += "º"; + else if (!strncmp("pound", token, 5)) text += "£"; + else if (!strncmp("cent", token, 4)) text += "¢"; + else if (!strncmp("frac14", token, 6)) text += "¼"; + else if (!strncmp("frac12", token, 6)) text += "½"; + else if (!strncmp("frac34", token, 6)) text += "¾"; + else if (!strncmp("iquest", token, 6)) text += "¿"; + else if (!strncmp("iexcl", token, 5)) text += "¡"; + else if (!strncmp("ETH", token, 3)) text += "Ð"; + else if (!strncmp("eth", token, 3)) text += "ð"; + else if (!strncmp("THORN", token, 5)) text += "Þ"; + else if (!strncmp("thorn", token, 5)) text += "þ"; + else if (!strncmp("AElig", token, 5)) text += "Æ"; + else if (!strncmp("aelig", token, 5)) text += "æ"; + else if (!strncmp("Oslash", token, 6)) text += "Ø"; + else if (!strncmp("curren", token, 6)) text += "¤"; + else if (!strncmp("Ccedil", token, 6)) text += "Ç"; + else if (!strncmp("ccedil", token, 6)) text += "ç"; + else if (!strncmp("szlig", token, 5)) text += "ß"; + else if (!strncmp("Ntilde", token, 6)) text += "Ñ"; + else if (!strncmp("ntilde", token, 6)) text += "ñ"; + else if (!strncmp("yen", token, 3)) text += "¥"; + else if (!strncmp("not", token, 3)) text += "¬"; + else if (!strncmp("ordf", token, 4)) text += "ª"; + else if (!strncmp("uml", token, 3)) text += "¨"; + else if (!strncmp("shy", token, 3)) text += "­"; + else if (!strncmp("macr", token, 4)) text += "¯"; + else if (!strncmp("micro", token, 5)) text += "µ"; + else if (!strncmp("middot", token, 6)) text += "·"; + else if (!strncmp("cedil", token, 5)) text += "¸"; + else if (!strncmp("ordm", token, 4)) text += "º"; + else if (!strncmp("times", token, 5)) text += "×"; + else if (!strncmp("divide", token, 6)) text += "÷"; + else if (!strncmp("oslash", token, 6)) text += "ø"; + continue; + + } + else if (*from == '>' && !ampersand) { + intoken = false; + // process desired tokens + if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) { + text += ' '; + text += '<'; + for (unsigned int i = 27; token[i] != '\"'; i++) + text += token[i]; + text += '>'; + continue; + } + if (!strncmp(token, "sync type=\"morph\" value=\"", 25)) { + text += ' '; + text += '('; + for (unsigned int i = 25; token[i] != '\"'; i++) + text += token[i]; + text += ')'; + continue; + } + if (!strncmp("note", token, 4)) { + text += ' '; + text += '('; + } + else if (!strncmp("br", token, 2)) + text += '\n'; + else if (!strncmp("/p", token, 2)) + text += '\n'; + else if (!strncmp("/note", token, 5)) { + text += ')'; + text += ' '; + } + continue; + } + if (intoken) { + if (tokpos < 2045) + token[tokpos++] = *from; + token[tokpos+2] = 0; + } + else text += *from; + } + + orig = text; + from = orig.c_str(); + for (text = ""; *from; from++) { //loop to remove extra spaces + if ((strchr(" \t\n\r", *from))) { + while (*(from + 1) && (strchr(" \t\n\r", *(from + 1)))) { + from++; + } + text += " "; + } + else { + text += *from; + } + } + text += (char)0; + + return 0; +} + +} // namespace Filters diff --git a/src/backend/filters/thmltoplain.h b/src/backend/filters/thmltoplain.h new file mode 100644 index 0000000..77e2a2b --- /dev/null +++ b/src/backend/filters/thmltoplain.h @@ -0,0 +1,33 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef FILTERS_THMLTOPLAIN_H +#define FILTERS_THMLTOPLAIN_H + +// Sword includes: +#include <swbuf.h> +#include <swfilter.h> + + +namespace Filters { + +/** + \brief ThML text to plain text conversion filter +*/ +class ThmlToPlain: public sword::SWFilter { + protected: /* Methods: */ + /** Reimplemented from sword::SWFilter. */ + virtual char processText(sword::SWBuf &text, + const sword::SWKey *key = 0, + const sword::SWModule *module = 0); +}; + +} // namespace Filters + +#endif diff --git a/src/backend/keys/cswordkey.cpp b/src/backend/keys/cswordkey.cpp index 24f4909..9c5b25b 100644 --- a/src/backend/keys/cswordkey.cpp +++ b/src/backend/keys/cswordkey.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,6 +16,7 @@ #include "backend/keys/cswordldkey.h" #include "backend/keys/cswordtreekey.h" #include "backend/keys/cswordversekey.h" +#include "util/btsignal.h" // Sword includes: #include <swkey.h> @@ -26,12 +27,21 @@ #include <versekey.h> -CSwordKey::CSwordKey(CSwordModuleInfo* const module) : m_module(module) {} +const QTextCodec *CSwordKey::m_cp1252Codec = QTextCodec::codecForName("Windows-1252"); -CSwordKey::CSwordKey(const CSwordKey& k) { +CSwordKey::CSwordKey(const CSwordModuleInfo * const module) + : m_module(module), + m_signal(0) {} + +CSwordKey::CSwordKey(const CSwordKey& k) + : m_signal(0) { m_module = k.m_module; } +CSwordKey::~CSwordKey() { + delete m_signal; +} + QString CSwordKey::rawText() { if (!m_module) return QString::null; @@ -51,7 +61,6 @@ QString CSwordKey::renderedText( const CSwordKey::TextRenderType mode ) { if (k) { sword::VerseKey* vk_mod = dynamic_cast<sword::VerseKey*>(m_module->module()->getKey()); - if (vk_mod) { vk_mod->Headings(1); } @@ -74,25 +83,26 @@ QString CSwordKey::renderedText( const CSwordKey::TextRenderType mode ) { //Q_ASSERT(!key().isNull()); if (!key().isNull()) { //we have valid text - bool DoRender = (mode == ProcessEntryAttributesOnly) ? 0 : 1; - QString text = QString::fromUtf8( m_module->module()->RenderText(0, -1, DoRender) ); - if (!DoRender) return QString::null; + bool DoRender = mode != ProcessEntryAttributesOnly; + QString text = QString::fromUtf8( m_module->module()->RenderText(0,-1, DoRender)); + if (!DoRender) + return QString::null; // This is yucky, but if we want strong lexicon refs we have to do it here. if (m_module->type() == CSwordModuleInfo::Lexicon) { QString t(text); - QRegExp rx("(GREEK|HEBREW) for 0*([1-9]\\d*)"); // ignore 0's before number + QRegExp rx("(GREEK|HEBREW) for 0*([1-9]\\d*)"); // ignore 0's before number int pos = 0; while ( (pos = rx.indexIn(t, pos)) != -1 ) { QString language = rx.cap(1); - QString langcode = QString(language.at(0)); // "G" or "H" + QString langcode = QString(language.at(0)); // "G" or "H" QString number = rx.cap(2); - QString paddednumber = number.rightJustified(5, '0'); // Form 00123 + QString paddednumber = number.rightJustified(5, '0'); // Form 00123 text.replace( QRegExp( QString( - "(>[^<>]+)" // Avoid replacing inside tags - "\\b(0*%1)\\b").arg(number) ), // And span around 0's + "(>[^<>]+)" // Avoid replacing inside tags + "\\b(0*%1)\\b").arg(number) ), // And span around 0's QString("\\1<span lemma=\"%1%2\"><a href=\"strongs://%3/%4\">\\2</a></span>") .arg(langcode, paddednumber, language, paddednumber) ); @@ -101,23 +111,22 @@ QString CSwordKey::renderedText( const CSwordKey::TextRenderType mode ) { } if (mode == HTMLEscaped) { - //we have to encode all UTF-8 in HTML escapes - // go though every character and write down the escaped HTML unicode entity - // form is &#<decimal unicode value here>; + /* + Here we encode all non-latin1 characters as HTML unicode entities + in the form &#<decimal unicode value here>; + */ QString ret; - QChar c; - const unsigned int length = text.length(); - for (unsigned int i = 0; i < length; ++i) { - c = text.at(i); + // Reserve characters to reduce number of memory allocations: + ret.reserve(text.size()); + + for (int i = 0; i < text.size(); ++i) { + const QChar c = text.at(i); - if (c.toLatin1()) { //normal latin1 character + if (c.toLatin1()) { ret.append(c); - } - else {//unicode character, needs to be escaped - ret.append("&#") - .append(c.unicode()) - .append(";"); + } else { + ret.append("&#").append(c.unicode()).append(";"); } } @@ -144,14 +153,13 @@ QString CSwordKey::strippedText() { return QString::fromUtf8( m_module->module()->StripText() ); } -const QTextCodec* CSwordKey::cp1252Codec() { - static QTextCodec * codec = QTextCodec::codecForName("Windows-1252"); - return codec; +void CSwordKey::emitChanged() { + if (m_signal.isNull()) return; + m_signal->emitChanged(); } - /** This will create a proper key object from a given module */ -CSwordKey* CSwordKey::createInstance( CSwordModuleInfo* const module ) { +CSwordKey *CSwordKey::createInstance(const CSwordModuleInfo *module) { if (!module) { return 0; } @@ -173,3 +181,9 @@ CSwordKey* CSwordKey::createInstance( CSwordModuleInfo* const module ) { return 0; } } + +const BtSignal* CSwordKey::signaler() { + if (m_signal.isNull()) + m_signal = new BtSignal(); + return m_signal; +} diff --git a/src/backend/keys/cswordkey.h b/src/backend/keys/cswordkey.h index d1924d6..48e511c 100644 --- a/src/backend/keys/cswordkey.h +++ b/src/backend/keys/cswordkey.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,89 +10,103 @@ #ifndef CSWORDKEY_H #define CSWORDKEY_H +#include <QPointer> #include <QString> class CSwordModuleInfo; class QTextCodec; +class BtSignal; /** Base class for all keys. * The base class for all Sword based keys. * @author The BibleTime team * @version $Id: cswordkey.h,v 1.27 2006/10/30 19:53:32 mgruner Exp $ */ - class CSwordKey { - protected: - /** Constructor. May only be called from sublasses because this class contains pure virtual methods. - * @param module The module which belongs to this key, may be NULL - */ - CSwordKey(CSwordModuleInfo* const module = 0); //protected constructor, because CSwordKey shouldn't be used (it's an abstract base class). - /** Copy constructor. + /** + \param module The module which belongs to this key, may be NULL */ - CSwordKey(const CSwordKey&); //copy constructor + CSwordKey(const CSwordModuleInfo * const module = 0); + + CSwordKey(const CSwordKey ©); public: enum TextRenderType { Normal = 0, HTMLEscaped = 1, - ProcessEntryAttributesOnly = 2 // in this case, renderText() will not return text, but only cause EntryAttribute processing + ProcessEntryAttributesOnly = 2 // in this case, renderText() will not return text, but only cause EntryAttribute processing }; - /** Destructor. - * Public, not protected like the constructor, because CSwordKey pointers may be deleted by all others. - */ - virtual ~CSwordKey() {}; - //pure virtual functions + virtual ~CSwordKey(); + /** Returns the current key. - * @return The current key which belongs to the current object. + * @return The key which belongs to the current object. */ virtual QString key() const = 0; - /** Sets the current key. Sets the key using a utf8 enabled QString. - * @param key The key which should be used to set the current one - */ - virtual bool key(const QString& key) = 0; - /** Set the key using a utf8-decoded c-string - * @param key The key which should be used to set the current one - */ - virtual bool key(const char* key) = 0; + + /** + Sets the current key. Sets the key using a utf8 enabled QString. + \param key The key which should be used to set the current one. + */ + virtual bool setKey(const QString &key) = 0; + + /** + Set the key using a utf8-decoded c-string. + \param key The key which should be used to set the current one. + */ + virtual bool setKey(const char *key) = 0; + /** Clone this object. Clone this current object and return it. * @return A clone of the current object. */ virtual CSwordKey* copy() const = 0; - //implemented functions - /** Set/get the module. Set and get the module which belongs to this key. - * @return The module which belongs to this key. - */ - inline virtual CSwordModuleInfo* module(CSwordModuleInfo* const newModule = 0); + /** + \returns the module which belongs to this key. + */ + inline const CSwordModuleInfo *module() const { + return m_module; + } + + /** + Sets the module which belongs to this key. + \param[in] newModule the module to set. + */ + virtual inline void setModule(const CSwordModuleInfo *newModule) { + m_module = newModule; + } + /** Returns the raw, unchanged text. Returns the text without any filter modifications, * just in the way it comes out of the module. */ virtual QString rawText(); - /** Returns the rendered text. Returns the text of the current key after passign it through the + /** Returns the rendered text. Returns the text of the current key after passing it through the * modules filters. */ virtual QString renderedText( const CSwordKey::TextRenderType mode = CSwordKey::Normal ); /** Stripped down text. Returns the text after removing all markup tags from it. */ virtual QString strippedText(); + + const BtSignal *signaler(); + /** * This returns a new object of the right CSwordKey* implementation * (e.g. CSwordVerseKey or CSwordLDKey) * The type is determined by the type of the module. * @see CSwordModuleInfo, CSwordBibleModuleInfo, CSwordCommentaryModuleInfo, CSwordLexiconModukleInfo */ - static CSwordKey* createInstance(CSwordModuleInfo * const module); + static CSwordKey* createInstance(const CSwordModuleInfo *module); protected: /** * Returns the encoded key appropriate for use directly with Sword. */ virtual const char * rawKey() const = 0; - static const QTextCodec* cp1252Codec(); - CSwordModuleInfo* m_module; //module pointer used by all keys + static inline const QTextCodec *cp1252Codec() { return m_cp1252Codec; }; + void emitChanged(); private: /** @@ -100,13 +114,10 @@ class CSwordKey { */ CSwordKey& operator= ( const CSwordKey & ); + protected: + static const QTextCodec *m_cp1252Codec; + const CSwordModuleInfo *m_module; + QPointer<BtSignal> m_signal; }; -inline CSwordModuleInfo* CSwordKey::module(CSwordModuleInfo* const newModule) { - if (newModule) { - m_module = newModule; - } - return m_module; -} - #endif diff --git a/src/backend/keys/cswordldkey.cpp b/src/backend/keys/cswordldkey.cpp index bc1e2c1..ecde8b7 100644 --- a/src/backend/keys/cswordldkey.cpp +++ b/src/backend/keys/cswordldkey.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,8 +18,8 @@ #include <utilstr.h> -CSwordLDKey::CSwordLDKey( CSwordModuleInfo* module ) { - if ((m_module = dynamic_cast<CSwordLexiconModuleInfo*>(module))) { +CSwordLDKey::CSwordLDKey(const CSwordModuleInfo *module) { + if ((m_module = dynamic_cast<const CSwordLexiconModuleInfo*>(module))) { // *(m_module->module()) = TOP; } @@ -30,7 +30,11 @@ CSwordLDKey::CSwordLDKey( CSwordModuleInfo* module ) { CSwordLDKey::CSwordLDKey( const CSwordLDKey &k ) : CSwordKey(k), SWKey((const char*)k) {} /** No descriptions */ -CSwordLDKey::CSwordLDKey( const SWKey *k, CSwordModuleInfo* module) : CSwordKey(module), SWKey(*k) {} +CSwordLDKey::CSwordLDKey(const SWKey *k, const CSwordModuleInfo *module) + : CSwordKey(module), SWKey(*k) +{ + // Intentionally empty +} /** Clones this object by copying the members. */ CSwordLDKey* CSwordLDKey::copy() const { @@ -38,14 +42,14 @@ CSwordLDKey* CSwordLDKey::copy() const { } /** Sets the module of this key. */ -CSwordModuleInfo* CSwordLDKey::module(CSwordModuleInfo* const newModule) { - if (newModule && newModule->type() == CSwordModuleInfo::Lexicon) { - const QString oldKey = key(); - m_module = newModule; - key(oldKey); - } - - return m_module; +void CSwordLDKey::setModule(const CSwordModuleInfo *newModule) { + Q_ASSERT(newModule); + if (m_module == newModule) return; + Q_ASSERT(newModule->type() == CSwordModuleInfo::Lexicon); + + const QString oldKey = key(); + m_module = newModule; + setKey(oldKey); } QString CSwordLDKey::key() const { @@ -61,23 +65,23 @@ QString CSwordLDKey::key() const { } const char * CSwordLDKey::rawKey() const { - return (const char*)*this; + return getText(); } -bool CSwordLDKey::key( const QString& newKey ) { +bool CSwordLDKey::setKey(const QString &newKey) { Q_ASSERT(m_module); if (m_module->isUnicode()) { - return key(newKey.toUtf8().constData()); + return setKey(newKey.toUtf8().constData()); } else { - return key((const char*)cp1252Codec()->fromUnicode(newKey)); + return setKey((const char*)cp1252Codec()->fromUnicode(newKey)); } } /** Sets the key of this instance */ -bool CSwordLDKey::key( const char* newKey ) { +bool CSwordLDKey::setKey(const char *newKey) { Q_ASSERT(newKey); if (newKey) { @@ -98,7 +102,7 @@ CSwordLDKey* CSwordLDKey::NextEntry() { ( *( m_module->module() ) )++; m_module->module()->setSkipConsecutiveLinks(false); - key(m_module->module()->KeyText()); + setKey(m_module->module()->KeyText()); SWKey::operator = (m_module->module()->KeyText()); return this; diff --git a/src/backend/keys/cswordldkey.h b/src/backend/keys/cswordldkey.h index 2e460d7..ed43ce7 100644 --- a/src/backend/keys/cswordldkey.h +++ b/src/backend/keys/cswordldkey.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -52,19 +52,19 @@ class CSwordLDKey : public CSwordKey, public sword::SWKey { public: /** - * Constructor of CSwordLDKey + \todo Document param */ - CSwordLDKey( CSwordModuleInfo* module ); - /** - * Copy constructor for this key class. - */ - CSwordLDKey( const CSwordLDKey &k ); + CSwordLDKey(const CSwordModuleInfo *module); + + CSwordLDKey(const CSwordLDKey ©); + /** - * Copy constructor for this key class. + \todo Document params */ - CSwordLDKey( const sword::SWKey *k, CSwordModuleInfo* module); + CSwordLDKey(const sword::SWKey *k, const CSwordModuleInfo *module); + /** - * Clones this object by copying the members. + Reimplementation of CSwordKey::copy() */ virtual CSwordLDKey* copy() const; /** @@ -75,22 +75,26 @@ class CSwordLDKey : public CSwordKey, public sword::SWKey { * Uses the parameter to returns the previous entry afer this key. */ CSwordLDKey* PreviousEntry( void ); + /** - * Sets the module of this key. + Sets the module of this key. */ - virtual CSwordModuleInfo* module( CSwordModuleInfo* const module = 0 ); + virtual void setModule(const CSwordModuleInfo *module); + /** * Returns the current key as a QString */ virtual QString key() const; + /** - * Set the current key using unicode decoded QString. + Reimplemented from CSwordKey::setKey(const QString &key). */ - virtual bool key( const QString& newKey ); + virtual bool setKey(const QString &newKey); + /** - * Set the current key from char*. To avoid encoding problems use key(QString) instead. + Reimplemented from CSwordKey::setKey(const char *key). */ - virtual bool key( const char* ); + virtual bool setKey(const char *key); protected: /** diff --git a/src/backend/keys/cswordtreekey.cpp b/src/backend/keys/cswordtreekey.cpp index e1ac9c3..4ea624f 100644 --- a/src/backend/keys/cswordtreekey.cpp +++ b/src/backend/keys/cswordtreekey.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,7 +16,12 @@ CSwordTreeKey::CSwordTreeKey( const CSwordTreeKey& k ) : CSwordKey(k), TreeKeyIdx(k) {} -CSwordTreeKey::CSwordTreeKey( const TreeKeyIdx *k, CSwordModuleInfo* module ) : CSwordKey(module), TreeKeyIdx(*k) {} +CSwordTreeKey::CSwordTreeKey(const TreeKeyIdx *k, + const CSwordModuleInfo *module) + : CSwordKey(module), TreeKeyIdx(*k) +{ + // Intentionally empty +} CSwordTreeKey* CSwordTreeKey::copy() const { return new CSwordTreeKey(*this); @@ -38,19 +43,19 @@ const char * CSwordTreeKey::rawKey() const { return getText(); } -bool CSwordTreeKey::key( const QString& newKey ) { +bool CSwordTreeKey::setKey(const QString &newKey) { //return key( newKey.toLocal8Bit().constData() ); //return key(m_module->getTextCodec()->fromUnicode(newKey).constData()); Q_ASSERT(m_module); if (m_module->isUnicode()) { - return key(newKey.toUtf8().constData()); + return setKey(newKey.toUtf8().constData()); } else { - return key((const char*)cp1252Codec()->fromUnicode(newKey)); + return setKey((const char*)cp1252Codec()->fromUnicode(newKey)); } } -bool CSwordTreeKey::key( const char* newKey ) { +bool CSwordTreeKey::setKey(const char *newKey) { Q_ASSERT(newKey); if (newKey) { @@ -75,21 +80,21 @@ QString CSwordTreeKey::getLocalNameUnicode() { } } -CSwordModuleInfo* CSwordTreeKey::module( CSwordModuleInfo* const newModule ) { - if (newModule && (newModule != m_module) && (newModule->type() == CSwordModuleInfo::GenericBook) ) { - m_module = newModule; +void CSwordTreeKey::setModule(const CSwordModuleInfo *newModule) { + Q_ASSERT(newModule); + if (m_module == newModule) return; + Q_ASSERT(newModule->type() == CSwordModuleInfo::GenericBook); - const QString oldKey = key(); + m_module = newModule; - CSwordBookModuleInfo* newBook = dynamic_cast<CSwordBookModuleInfo*>(newModule); - copyFrom( *(newBook->tree()) ); + const QString oldKey = key(); - key(oldKey); //try to restore our old key + const CSwordBookModuleInfo *newBook = dynamic_cast<const CSwordBookModuleInfo*>(newModule); + copyFrom( *(newBook->tree()) ); - //set the key to the root node - root(); - firstChild(); - } + setKey(oldKey); //try to restore our old key - return m_module; + //set the key to the root node + root(); + firstChild(); } diff --git a/src/backend/keys/cswordtreekey.h b/src/backend/keys/cswordtreekey.h index 9a60d5b..d6eb5ec 100644 --- a/src/backend/keys/cswordtreekey.h +++ b/src/backend/keys/cswordtreekey.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,18 +26,20 @@ class CSwordModuleInfo; class CSwordTreeKey : public CSwordKey, public sword::TreeKeyIdx { public: - /** Constructor of this CSwordKey implementation. - * @param k The Sword tree key which belongs to this key - * @param module The module which belongs to this key - */ - CSwordTreeKey( const sword::TreeKeyIdx *k, CSwordModuleInfo* module ); - /** Copy constructor. + /** + \param k The Sword tree key which belongs to this key + \param module The module which belongs to this key */ + CSwordTreeKey(const sword::TreeKeyIdx *k, + const CSwordModuleInfo *module); + CSwordTreeKey( const CSwordTreeKey& k ); - /** The module which belongs to this key. - * @return The module. - */ - virtual CSwordModuleInfo* module( CSwordModuleInfo* const newModule ); + + /** + Reimplemented from CSwordKey. + */ + virtual void setModule(const CSwordModuleInfo *newModule); + /** Copy method. * @return A new copy of this object. */ @@ -53,15 +55,16 @@ class CSwordTreeKey : public CSwordKey, public sword::TreeKeyIdx { * Returns the current key as unicode decoded QString. */ virtual QString key() const; + /** - * Set the key. If the parameter is empty or null, the key will be set to "/" + Reimplemented from CSwordKey::setKey(const QString &key). */ - virtual bool key( const QString& key ); + virtual bool setKey(const QString &key); + /** - * Set the key from char* To avoid encoding problems use key(QString instead), - * otherwise it is caller's responsibility to ensure the correct encoding (utf8/latin1). + Reimplemented from CSwordKey::setKey(const char *key). */ - virtual bool key( const char* key ); + virtual bool setKey(const char *key); protected: /** diff --git a/src/backend/keys/cswordversekey.cpp b/src/backend/keys/cswordversekey.cpp index a7e16c5..5ea1455 100644 --- a/src/backend/keys/cswordversekey.cpp +++ b/src/backend/keys/cswordversekey.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,19 +14,22 @@ #include "backend/drivers/cswordbiblemoduleinfo.h" #include "backend/drivers/cswordcommentarymoduleinfo.h" +#include "util/btsignal.h" // Sword includes: #include <swmodule.h> #include <localemgr.h> -CSwordVerseKey::CSwordVerseKey( CSwordModuleInfo* const module ) : - CSwordKey(module) { - if ( CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module) ) { +CSwordVerseKey::CSwordVerseKey(const CSwordModuleInfo *module) + : CSwordKey(module) +{ + typedef CSwordBibleModuleInfo CSBMI; + if (const CSBMI *bible = dynamic_cast<const CSBMI*>(module) ) { // Copy important settings like versification system copyFrom((sword::VerseKey*) bible->module()->getKey()); - key( bible->lowerBound().key() ); + setKey( bible->lowerBound().key() ); } this->VerseKey::setAutoNormalize(true); } @@ -35,7 +38,12 @@ CSwordVerseKey::CSwordVerseKey( const CSwordVerseKey& k ) : CSwordKey(k), VerseK this->VerseKey::setAutoNormalize(true); } -CSwordVerseKey::CSwordVerseKey( const VerseKey* const k, CSwordModuleInfo* const module ) : CSwordKey(module), VerseKey(*k) {} +CSwordVerseKey::CSwordVerseKey(const VerseKey *k, + const CSwordModuleInfo *module) + : CSwordKey(module), VerseKey(*k) +{ + // Intentionally empty +} /** Clones this object. */ CSwordKey* CSwordVerseKey::copy() const { @@ -43,33 +51,38 @@ CSwordKey* CSwordVerseKey::copy() const { } /** Sets the module for this key */ -CSwordModuleInfo* CSwordVerseKey::module( CSwordModuleInfo* const newModule ) { - if (newModule && ((newModule->type() == CSwordModuleInfo::Bible) || (newModule->type() == CSwordModuleInfo::Commentary) ) ) { - m_module = newModule; +void CSwordVerseKey::setModule(const CSwordModuleInfo *newModule) { + typedef CSwordBibleModuleInfo CSBMI; - //check if the module contains the key we present - CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(newModule); + Q_ASSERT(newModule); + if (m_module == newModule) return; + Q_ASSERT(newModule->type() == CSwordModuleInfo::Bible + || newModule->type() == CSwordModuleInfo::Commentary); - if (_compare(bible->lowerBound()) < 0) { - key( bible->lowerBound() ); - } + m_module = newModule; - if (_compare(bible->upperBound()) > 0) { - key( bible->upperBound() ); - } + //check if the module contains the key we present + const CSBMI* bible = dynamic_cast<const CSBMI*>(newModule); + + if (_compare(bible->lowerBound()) < 0) { + setKey(bible->lowerBound()); } - return dynamic_cast<CSwordBibleModuleInfo*>(m_module); + if (_compare(bible->upperBound()) > 0) { + setKey(bible->upperBound()); + } } /** Returns the current book as Text, not as integer. */ QString CSwordVerseKey::book( const QString& newBook ) { + typedef CSwordBibleModuleInfo CSBMI; int min = 0; int max = 1; - if (CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module())) { - const bool hasOT = bible->hasTestament(CSwordBibleModuleInfo::OldTestament); - const bool hasNT = bible->hasTestament(CSwordBibleModuleInfo::NewTestament); + const CSBMI *bible = dynamic_cast<const CSBMI*>(module()); + if (bible != 0) { + const bool hasOT = bible->hasTestament(CSBMI::OldTestament); + const bool hasNT = bible->hasTestament(CSBMI::NewTestament); if (hasOT && hasNT) { min = 0; @@ -110,26 +123,37 @@ const char * CSwordVerseKey::rawKey() const { return getText(); } -bool CSwordVerseKey::key( const QString& newKey ) { - return key( newKey.toUtf8().constData() ); +bool CSwordVerseKey::setKey(const QString &newKey) { + return setKey(newKey.toUtf8().constData()); } -bool CSwordVerseKey::key( const char* newKey ) { - if (newKey && (strlen(newKey) > 0) ) { - VerseKey::operator = (newKey); - } - else if (newKey && !strlen(newKey)) { - CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module()); - - if ( bible ) { - VerseKey::operator = (bible->lowerBound().key().toUtf8().constData()); +bool CSwordVerseKey::setKey(const char *newKey) { + typedef CSwordBibleModuleInfo CSBMI; + + /// \todo Is this check necessary? + if (newKey) { + /// \todo Is this check necessary? + // Check if empty string: + if (*newKey != '\0') { + positionFrom(newKey); + } else { + const CSwordModuleInfo *m = module(); + if (m->type() == CSwordModuleInfo::Bible) { + Q_ASSERT(dynamic_cast<const CSBMI*>(m) != 0); + const CSBMI *bible = static_cast<const CSBMI*>(m); + positionFrom(bible->lowerBound().key().toUtf8().constData()); + } } } + /// \todo Do we ALWAYS need to emit this signal and check for errors? + emitChanged(); return !Error(); } bool CSwordVerseKey::next( const JumpType type ) { + typedef CSwordBibleModuleInfo CSBMI; + Error(); //clear Error status bool ret = true; @@ -174,7 +198,7 @@ bool CSwordVerseKey::next( const JumpType type ) { m_module->module()->setSkipConsecutiveLinks(oldStatus); if (!m_module->module()->Error()) { - key( QString::fromUtf8(m_module->module()->KeyText()) ); + setKey(QString::fromUtf8(m_module->module()->KeyText())); } else { // Verse(Verse()+1); @@ -196,27 +220,32 @@ bool CSwordVerseKey::next( const JumpType type ) { return false; } - if ( CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module()) ) { + const CSBMI *bible = dynamic_cast<const CSBMI*>(module()); + if (bible != 0) { if (_compare(bible->lowerBound()) < 0 ) { - key( bible->lowerBound() ); + setKey(bible->lowerBound()); ret = false; } if (_compare(bible->upperBound()) > 0 ) { - key( bible->upperBound() ); + setKey(bible->upperBound()); ret = false; } + emitChanged(); return ret; } else if (Error()) { //we have no module, so take care of VerseKey::Error() return false; } + emitChanged(); return ret; } bool CSwordVerseKey::previous( const JumpType type ) { + typedef CSwordBibleModuleInfo CSBMI; + bool ret = true; switch (type) { @@ -256,7 +285,7 @@ bool CSwordVerseKey::previous( const JumpType type ) { m_module->module()->setSkipConsecutiveLinks(oldStatus); if (!m_module->module()->Error()) { - key( QString::fromUtf8(m_module->module()->KeyText()) );//don't use fromUtf8 + setKey(QString::fromUtf8(m_module->module()->KeyText()));//don't use fromUtf8 } else { ret = false; @@ -275,22 +304,25 @@ bool CSwordVerseKey::previous( const JumpType type ) { return false; } - if ( CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module()) ) { + const CSBMI *bible = dynamic_cast<const CSBMI*>(module()); + if (bible != 0) { if (_compare(bible->lowerBound()) < 0 ) { - key( bible->lowerBound() ); + setKey(bible->lowerBound()); ret = false; } if (_compare(bible->upperBound()) > 0 ) { - key( bible->upperBound() ); + setKey(bible->upperBound()); ret = false; } + emitChanged(); return ret; } else if (Error()) { return false; } + emitChanged(); return ret; } diff --git a/src/backend/keys/cswordversekey.h b/src/backend/keys/cswordversekey.h index bfbfa25..2769cbf 100644 --- a/src/backend/keys/cswordversekey.h +++ b/src/backend/keys/cswordversekey.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -35,8 +35,8 @@ class CSwordModuleInfo; * @see NextVerse() * @see PreviousVerse(). * - * Call the constructor only with a valid verse based modules, otherwise this key will be invalid - * and the application will probably crash. + * Call the constructor only with valid verse based modules, otherwise this key + * will be invalid and the application will probably crash. * * @version $Id: cswordversekey.h,v 1.26 2006/02/25 11:38:15 joachim Exp $ * @short CSwordKey implementation for Sword's VerseKey. @@ -53,39 +53,43 @@ class CSwordVerseKey : public CSwordKey, public sword::VerseKey { }; /** - * Constructor of this class. - * - * This function will construct a versekey with the current module position - * and it will setup the m_module members. - * - */ - CSwordVerseKey( CSwordModuleInfo* const module ); - /** - * Copy constructor. + Constructs a versekey with the current module position and setups + the m_module members. */ - CSwordVerseKey( const CSwordVerseKey& k ); + CSwordVerseKey(const CSwordModuleInfo *module); + + CSwordVerseKey(const CSwordVerseKey ©); + /** - * VerseKey based constructor. - */ - CSwordVerseKey( const sword::VerseKey* const k, CSwordModuleInfo* const module ); + * Constructs a CSwordVerseKey using the given module at the position given + * by the versekey. + * + * \param[in] k Position to use. + * \param[in] module Module to use. + */ + CSwordVerseKey(const sword::VerseKey *k, + const CSwordModuleInfo *module); + /** - * Clones this object. + Reimplementation of CSwordKey::copy(). */ virtual CSwordKey* copy() const; + /** * Set/get the key. If the parameter is not set (means equal to QString::null) * the used key is returned. Otherwise the key is set and the new on ei returned. */ virtual QString key() const; + /** - * Set the current key. + Reimplemented from CSwordKey::setKey(const QString &key). */ - virtual bool key( const QString& ); + virtual bool setKey(const QString &key); + /** - * Set/get the key. If the parameter is not set (means equal to QString::null) - * the used key is returned. Otherwise the key is set and the new on ei returned. + Reimplemented from CSwordKey::setKey(const char *key). */ - virtual bool key( const char* key ); + virtual bool setKey(const char *key); /** * Jumps to the next entry of the given type @@ -102,10 +106,11 @@ class CSwordVerseKey : public CSwordKey, public sword::VerseKey { * @return The name of the current book */ QString book(const QString& newBook = QString::null); + /** - * Sets the module for this key + Sets the module for this key. */ - virtual CSwordModuleInfo* module( CSwordModuleInfo* const newModule = 0 ); + virtual void setModule(const CSwordModuleInfo *newModule); protected: /** @@ -114,7 +119,7 @@ class CSwordVerseKey : public CSwordKey, public sword::VerseKey { virtual const char * rawKey() const; private: - /** Disable assignment operator */ + /** Disable assignment operator */ CSwordVerseKey& operator= (const CSwordVerseKey&); /** Disable from base class to prevent compiler warnings */ inline virtual CSwordVerseKey& operator= (const sword::VerseKey&) { diff --git a/src/backend/managers/btstringmgr.cpp b/src/backend/managers/btstringmgr.cpp index a2abc7f..ad1fb3e 100644 --- a/src/backend/managers/btstringmgr.cpp +++ b/src/backend/managers/btstringmgr.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/backend/managers/btstringmgr.h b/src/backend/managers/btstringmgr.h index 7f44df8..1cf7170 100644 --- a/src/backend/managers/btstringmgr.h +++ b/src/backend/managers/btstringmgr.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/backend/managers/cdisplaytemplatemgr.cpp b/src/backend/managers/cdisplaytemplatemgr.cpp index 11d2a59..b3def8c 100644 --- a/src/backend/managers/cdisplaytemplatemgr.cpp +++ b/src/backend/managers/cdisplaytemplatemgr.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,15 +17,38 @@ #include "backend/config/cbtconfig.h" #include "backend/drivers/cswordmoduleinfo.h" #include "backend/managers/clanguagemgr.h" -#include "util/cpointers.h" #include "util/directory.h" -CDisplayTemplateMgr::CDisplayTemplateMgr() { - loadTemplates(); -} +CDisplayTemplateMgr *CDisplayTemplateMgr::m_instance = 0; + +CDisplayTemplateMgr::CDisplayTemplateMgr(QString &errorMessage) { + Q_ASSERT(m_instance == 0); -CDisplayTemplateMgr::~CDisplayTemplateMgr() { + m_instance = this; + namespace DU = util::directory; + + QStringList filter("*.tmpl"); + + // Preload global display templates from disk: + QDir td = DU::getDisplayTemplatesDir(); + Q_FOREACH(QString file, td.entryList(filter, QDir::Files | QDir::Readable)) + loadTemplate(td.canonicalPath() + "/" + file); + + /* + Preload user display templates from disk, overriding any global templates + with the same file name: + */ + QDir utd = DU::getUserDisplayTemplatesDir(); + Q_FOREACH(QString file, utd.entryList(filter, QDir::Files | QDir::Readable)) + loadTemplate(utd.canonicalPath() + "/" + file); + + if (m_templateMap.contains(defaultTemplate())) { + errorMessage = QString::null; + } else { + errorMessage = QObject::tr("Default template \"%1\" not found!") + .arg(defaultTemplate()); + } } const QString CDisplayTemplateMgr::fillTemplate( const QString& name, const QString& content, Settings& settings ) { @@ -70,9 +93,9 @@ const QString CDisplayTemplateMgr::fillTemplate( const QString& name, const QStr qDebug() << "There were more than 1 module, create headers"; QString header; - QList<CSwordModuleInfo*>::iterator end_it = settings.modules.end(); + QList<const CSwordModuleInfo*>::iterator end_it = settings.modules.end(); - for (QList<CSwordModuleInfo*>::iterator it(settings.modules.begin()); it != end_it; ++it) { + for (QList<const CSwordModuleInfo*>::iterator it(settings.modules.begin()); it != end_it; ++it) { header.append("<th style=\"width:") .append(QString::number(int( 100.0 / (float)moduleCount ))) .append("%;\">") @@ -88,7 +111,7 @@ const QString CDisplayTemplateMgr::fillTemplate( const QString& name, const QStr } QString langCSS; - CLanguageMgr::LangMap langMap = CPointers::languageMgr()->availableLanguages(); + CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages(); qDebug() << "langMap length:" << langMap.count(); qDebug() << "loop through langMap"; @@ -118,7 +141,7 @@ const QString CDisplayTemplateMgr::fillTemplate( const QString& name, const QStr //at first append the font standard settings for all languages without configured font // Create a dummy language (the langmap may be empty) - CLanguageMgr::Language lang_v(QString("en"), QString("English"), QString()); + CLanguageMgr::Language lang_v(QString("en"), QString("English"), QString::null); CLanguageMgr::Language* lang = &lang_v; if (lang && !lang->abbrev().isEmpty()/*&& lang->isValid()*/) { @@ -132,7 +155,7 @@ const QString CDisplayTemplateMgr::fillTemplate( const QString& name, const QStr ); } -// qWarning("Outputing unformated text"); +// qWarning("Outputing unformated text"); const QString t = QString(m_templateMap[ templateName ]) //don't change the map's content directly, use a copy .replace("#TITLE#", settings.title) .replace("#LANG_ABBREV#", settings.langAbbrev.isEmpty() ? QString("en") : settings.langAbbrev) @@ -144,25 +167,13 @@ const QString CDisplayTemplateMgr::fillTemplate( const QString& name, const QStr return t; } -void CDisplayTemplateMgr::loadTemplates() { - namespace DU = util::directory; - - QStringList files; - foreach (QString file, DU::getDisplayTemplatesDir().entryList(QStringList("*.tmpl"))) { - files += DU::getDisplayTemplatesDir().canonicalPath() + "/" + file; - } - foreach (QString file, DU::getUserDisplayTemplatesDir().entryList(QStringList("*.tmpl"))) { - files += DU::getUserDisplayTemplatesDir().canonicalPath() + "/" + file; - } - - foreach (QString file, files) { - QFile f(file); - if (f.exists() && f.open( QIODevice::ReadOnly )) { - QString fileContent = QTextStream( &f ).readAll(); +void CDisplayTemplateMgr::loadTemplate(const QString &filename) { + QFile f(filename); + if (f.open(QIODevice::ReadOnly)) { + QString fileContent = QTextStream(&f).readAll(); - if (!fileContent.isEmpty()) { - m_templateMap[ QFileInfo(file).fileName() ] = fileContent; - } + if (!fileContent.isEmpty()) { + m_templateMap[QFileInfo(f).fileName()] = fileContent; } } } diff --git a/src/backend/managers/cdisplaytemplatemgr.h b/src/backend/managers/cdisplaytemplatemgr.h index 16725a5..9b96e8b 100644 --- a/src/backend/managers/cdisplaytemplatemgr.h +++ b/src/backend/managers/cdisplaytemplatemgr.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,71 +18,82 @@ class CSwordModuleInfo; /** - * Manages the display templates used in the filters and display classes. - * @author The BibleTime team + Manages the display templates used in the filters and display classes. + \note This is a singleton. */ class CDisplayTemplateMgr { - public: - /** Settings which are used to fill the content into the template. + public: /* Types: */ + /** + Settings which are used to fill the content into the template. */ - struct Settings { - /** Constructor. Constructs the new settings object. The default values are empty. - */ - Settings() { - title = QString::null; - langAbbrev = QString::null; - pageCSS_ID = QString::null; - pageDirection = QString("ltr"); - }; - - QList<CSwordModuleInfo*> modules; /**< the list of modules */ - QString title; /**< the title which is used for the new processed HTML page */ - QString langAbbrev; /**< the language for the HTML page. */ - QString pageDirection; /**< the language for the HTML page. */ - QString pageCSS_ID; /**< the CSS ID which is used in the content part of the page */ + Settings() : pageDirection("ltr") {} + + /** The list of modules */ + QList<const CSwordModuleInfo*> modules; + + /** The title which is used for the new processed HTML page */ + QString title; + + /** The language for the HTML page. */ + QString langAbbrev; + + /** The language direction for the HTML page. */ + QString pageDirection; + + /** The CSS ID which is used in the content part of the page */ + QString pageCSS_ID; }; - /** Available templates. - * @return The list of templates, which are available. + public: /* Methods: */ + + /** + \param[out] errorMessage Set to error string on error, otherwise set + to QString::null. */ - inline const QStringList availableTemplates(); - /** Fill template. Fill rendered content into the template given by the name. - * @param name The name of the template - * @param content The content which should be filled into the template - * @param settings The settings which are used to process the templating process - * @return The full HTML template HTML code including the CSS data. + explicit CDisplayTemplateMgr(QString &errorMessage); + + /** + \returns the list of available templates. */ - const QString fillTemplate( const QString& name, const QString& content, Settings& settings); - /** Default template. - * @return The i18n'ed name of the default template + inline const QStringList availableTemplates() const { + return m_templateMap.keys(); + } + + /** + \brief Fills the template. + + Fills rendered content into the template given by the name. + + \param name The name of the template to fill. + \param content The content which should be filled into the template. + \param settings The settings which are used to process the templating + process. + + \returns The full HTML template HTML code including the CSS data. */ - inline static const QString defaultTemplate(); - - protected: - friend class CPointers; - /** Display template manager constructor. Protected to just allow CPointers to create objects. */ - CDisplayTemplateMgr(); - /** Destructor. */ - ~CDisplayTemplateMgr(); - /** Does the actual work of loading templates from disk */ - void loadTemplates(); - - private: - QMap<QString, QString> m_templateMap; -}; + const QString fillTemplate( const QString& name, const QString& content, Settings& settings); -inline const QString CDisplayTemplateMgr::defaultTemplate() { - return QString("Blue.tmpl"); -} + /** + \returns the name of the default template. + */ + inline static const char *defaultTemplate() { return "Blue.tmpl"; } -/** - * CDisplayTemplateMgr::availableTemplates() - */ -inline const QStringList CDisplayTemplateMgr::availableTemplates() { - return m_templateMap.keys(); -} + /** + \returns The singleton instance of the instance of this class. + */ + static inline CDisplayTemplateMgr *instance() { + Q_ASSERT(m_instance != 0); + return m_instance; + }; + private: /* Methods: */ + /** Preloads a single template from disk: */ + void loadTemplate(const QString &filename); + private: /* Fields: */ + QMap<QString, QString> m_templateMap; + static CDisplayTemplateMgr *m_instance; +}; #endif diff --git a/src/backend/managers/clanguagemgr.cpp b/src/backend/managers/clanguagemgr.cpp index 5c44405..a8d4e1f 100644 --- a/src/backend/managers/clanguagemgr.cpp +++ b/src/backend/managers/clanguagemgr.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,7 +11,6 @@ #include "backend/drivers/cswordmoduleinfo.h" #include "backend/managers/cswordbackend.h" -#include "util/cpointers.h" CLanguageMgr::Language::Language() {} @@ -37,6 +36,22 @@ CLanguageMgr::Language::~Language() { /****************************************************/ /******************** CLanguageMgr ******************/ /****************************************************/ + +CLanguageMgr *CLanguageMgr::m_instance = 0; + +void CLanguageMgr::destroyInstance() { + delete m_instance; + m_instance = 0; +} + +CLanguageMgr *CLanguageMgr::instance() { + if (m_instance == 0) { + m_instance = new CLanguageMgr(); + } + + return m_instance; +} + CLanguageMgr::CLanguageMgr() : m_langMap() { m_availableModulesCache.moduleCount = 0; init(); @@ -50,7 +65,7 @@ CLanguageMgr::~CLanguageMgr() { } const CLanguageMgr::LangMap& CLanguageMgr::availableLanguages() { - QList<CSwordModuleInfo*> mods = CPointers::backend()->moduleList(); + QList<CSwordModuleInfo*> mods = CSwordBackend::instance()->moduleList(); if ( m_availableModulesCache.moduleCount != (unsigned int)mods.count() ) { //we have to refill the cached map m_availableModulesCache.availableLanguages.clear(); @@ -98,13 +113,6 @@ const CLanguageMgr::Language* CLanguageMgr::languageForAbbrev( const QString& ab return newLang; } -const CLanguageMgr::Language* CLanguageMgr::languageForName( const QString& name ) const { - foreach ( const Language* lang, m_langList ) { - if (lang->name() == name) return lang; - } - return &m_defaultLanguage;//invalid language -} - const CLanguageMgr::Language* CLanguageMgr::languageForTranslatedName( const QString& name ) const { foreach ( const Language* lang, m_langList ) { if (lang->translatedName() == name) return lang; diff --git a/src/backend/managers/clanguagemgr.h b/src/backend/managers/clanguagemgr.h index de716c0..cbe70e9 100644 --- a/src/backend/managers/clanguagemgr.h +++ b/src/backend/managers/clanguagemgr.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,9 +16,10 @@ #include <QStringList> -/** Manages the languages of BibleTime and provides functions to work with them. - * @author The BibleTime team - */ +/** + \brief Manages the languages and provides functions to work with them. + \note This is a singleton. +*/ class CLanguageMgr { public: @@ -27,21 +28,21 @@ class CLanguageMgr { */ class Language { public: - /** Default constructor of a language object. - * Uses the abbreviation parameter to lookup the - * language name and to be able to return the name, flag etc. - * Possible values for abbrev are de, en, fr, it etc. + /** + Uses the abbreviation parameter to lookup the language name + and to be able to return the name, flag etc. Possible values + for abbrev are de, en, fr, it etc. */ Language(); - /** Copy constructor. - */ - Language(const Language&); - /** Constructor which takes all necessary data. - */ - Language(const QString& abbrev, const QString& englishName, const QString& translatedName, const QStringList& altAbbrevs = QStringList()); - /** Destructor. - */ + + Language(const Language ©); + + Language(const QString &abbrev, const QString &englishName, + const QString &translatedName, + const QStringList &altAbbrevs = QStringList()); + ~Language(); + /** Returns the abbreviation. * @return The abbreviation of the chosen language. */ @@ -88,12 +89,17 @@ class CLanguageMgr { typedef QHash<QString, const Language*> LangMap; typedef QHash<QString, const Language*>::const_iterator LangMapIterator; - /** Constructor. - */ + + /** Returns the singleton instance, creating it if one does not exist. */ + static CLanguageMgr *instance(); + + /** Destroys the singleton instance, if one exists. */ + static void destroyInstance(); + CLanguageMgr(); - /** Destructor - */ + virtual ~CLanguageMgr(); + /** * Returns the standard languages available as standard. Does nothing for Sword. * @return A LangMap map which contains all known languages @@ -111,11 +117,7 @@ class CLanguageMgr { * @return Pointer to a language for the given string abbreviation. */ const CLanguageMgr::Language* languageForAbbrev( const QString& abbrev ) const; - /** Language for english name. - * @param abbrev The english language name. - * @return Pointer to a language for the given name - */ - const CLanguageMgr::Language* languageForName( const QString& language ) const; + /** Language for translated language name. * @param abbrev The translated language name * @return Pointer to a language for the given translated language name @@ -142,8 +144,9 @@ class CLanguageMgr { struct ModuleCache { unsigned int moduleCount; LangMap availableLanguages; - } - m_availableModulesCache; + } m_availableModulesCache; + + static CLanguageMgr *m_instance; }; #endif diff --git a/src/backend/managers/cswordbackend.cpp b/src/backend/managers/cswordbackend.cpp index 4596a61..b5c109f 100644 --- a/src/backend/managers/cswordbackend.cpp +++ b/src/backend/managers/cswordbackend.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,16 +20,9 @@ #include "backend/drivers/cswordbookmoduleinfo.h" #include "backend/drivers/cswordcommentarymoduleinfo.h" #include "backend/drivers/cswordlexiconmoduleinfo.h" -#include "backend/filters/bt_gbfhtml.h" -#include "backend/filters/bt_osishtml.h" -#include "backend/filters/bt_teihtml.h" -#include "backend/filters/bt_plainhtml.h" -#include "backend/filters/bt_thmlhtml.h" -#include "backend/filters/bt_thmlplain.h" +#include "backend/filters/thmltoplain.h" #include "backend/filters/osismorphsegmentation.h" -#include "backend/rendering/cbookdisplay.h" -#include "backend/rendering/cchapterdisplay.h" -#include "backend/rendering/centrydisplay.h" +#include "btglobal.h" #include "util/directory.h" // Sword includes: @@ -42,52 +35,25 @@ #include <utilstr.h> -using namespace Filters; using namespace Rendering; -CSwordBackend::CSwordBackend() - : sword::SWMgr(0, 0, false, new sword::EncodingFilterMgr( sword::ENC_UTF8 ), true), - m_dataModel(this) { - m_filters.gbf = new BT_GBFHTML(); - m_filters.plain = new BT_PLAINHTML(); - m_filters.thml = new BT_ThMLHTML(); - m_filters.osis = new BT_OSISHTML(); - m_filters.tei = new BT_TEIHTML(); - - m_displays.entry = new CEntryDisplay(); - m_displays.chapter = new CChapterDisplay(); - m_displays.book = new CBookDisplay(); +CSwordBackend *CSwordBackend::m_instance = 0; +CSwordBackend::CSwordBackend() + : sword::SWMgr(0, 0, false, + new sword::EncodingFilterMgr(sword::ENC_UTF8), true), + m_dataModel(this) +{ filterInit(); } CSwordBackend::CSwordBackend(const QString& path, const bool augmentHome) : sword::SWMgr(!path.isEmpty() ? path.toLocal8Bit().constData() : 0, false, new sword::EncodingFilterMgr( sword::ENC_UTF8 ), false, augmentHome) { // don't allow module renaming, because we load from a path - m_filters.gbf = new BT_GBFHTML(); - m_filters.plain = new BT_PLAINHTML(); - m_filters.thml = new BT_ThMLHTML(); - m_filters.osis = new BT_OSISHTML(); - m_filters.tei = new BT_TEIHTML(); - - m_displays.entry = new CEntryDisplay(); - m_displays.chapter = new CChapterDisplay(); - m_displays.book = new CBookDisplay(); - filterInit(); } CSwordBackend::~CSwordBackend() { shutdownModules(); - - delete m_filters.gbf; - delete m_filters.plain; - delete m_filters.thml; - delete m_filters.osis; - delete m_filters.tei; - - delete m_displays.book; - delete m_displays.chapter; - delete m_displays.entry; } void CSwordBackend::filterInit() { @@ -97,7 +63,7 @@ void CSwordBackend::filterInit() { optionFilters.erase("OSISMorphSegmentation"); delete filter; } - sword::SWOptionFilter* tmpFilter = new OSISMorphSegmentation(); + sword::SWOptionFilter *tmpFilter = new Filters::OSISMorphSegmentation(); optionFilters.insert(sword::OptionFilterMap::value_type("OSISMorphSegmentation", tmpFilter)); cleanupFilters.push_back(tmpFilter); @@ -105,7 +71,7 @@ void CSwordBackend::filterInit() { //remove this hack as soon as Sword is fixed cleanupFilters.remove(thmlplain); delete thmlplain; - thmlplain = new BT_ThMLPlain(); + thmlplain = new Filters::ThmlToPlain(); cleanupFilters.push_back(thmlplain); } @@ -125,10 +91,23 @@ QList<CSwordModuleInfo*> CSwordBackend::takeModulesFromList(QStringList names) { return list; } -QList<CSwordModuleInfo*> CSwordBackend::getPointerList(QStringList names) { +QList<CSwordModuleInfo*> CSwordBackend::getPointerList(const QStringList &names) { QList<CSwordModuleInfo*> list; - foreach(QString name, names) { - CSwordModuleInfo* mInfo = findModuleByName(name); + Q_FOREACH (const QString &name, names) { + CSwordModuleInfo *mInfo = findModuleByName(name); + if (mInfo) { + list.append(mInfo); + } + } + return list; +} + +QList<const CSwordModuleInfo*> CSwordBackend::getConstPointerList( + const QStringList &names) +{ + QList<const CSwordModuleInfo*> list; + Q_FOREACH (const QString &name, names) { + const CSwordModuleInfo *mInfo = findModuleByName(name); if (mInfo) { list.append(mInfo); } @@ -154,19 +133,19 @@ CSwordBackend::LoadError CSwordBackend::initModules(SetupChangedReason reason) { if (!strcmp(curMod->Type(), "Biblical Texts")) { newModule = new CSwordBibleModuleInfo(curMod, this); - newModule->module()->Disp(m_displays.chapter); + newModule->module()->Disp(&m_chapterDisplay); } else if (!strcmp(curMod->Type(), "Commentaries")) { newModule = new CSwordCommentaryModuleInfo(curMod, this); - newModule->module()->Disp(m_displays.entry); + newModule->module()->Disp(&m_entryDisplay); } else if (!strcmp(curMod->Type(), "Lexicons / Dictionaries")) { newModule = new CSwordLexiconModuleInfo(curMod, this); - newModule->module()->Disp(m_displays.entry); + newModule->module()->Disp(&m_entryDisplay); } else if (!strcmp(curMod->Type(), "Generic Books")) { newModule = new CSwordBookModuleInfo(curMod, this); - newModule->module()->Disp(m_displays.book); + newModule->module()->Disp(&m_bookDisplay); } if (newModule) { @@ -181,8 +160,7 @@ CSwordBackend::LoadError CSwordBackend::initModules(SetupChangedReason reason) { } } - Q_FOREACH(CSwordModuleInfo* mod, m_dataModel.modules()) { - m_moduleDescriptionMap.insert( mod->config(CSwordModuleInfo::Description), mod->name() ); + Q_FOREACH(CSwordModuleInfo* mod, m_dataModel.moduleList()) { //unlock modules if keys are present if ( mod->isEncrypted() ) { const QString unlockKey = CBTConfig::getModuleEncryptionKey( mod->name() ); @@ -206,29 +184,29 @@ void CSwordBackend::AddRenderFilters(sword::SWModule *module, sword::ConfigEntMa moduleDriver = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (sword::SWBuf) ""; if (sourceformat == "OSIS") { - module->AddRenderFilter(m_filters.osis); + module->AddRenderFilter(&m_osisFilter); noDriver = false; } else if (sourceformat == "ThML") { - module->AddRenderFilter(m_filters.thml); + module->AddRenderFilter(&m_thmlFilter); noDriver = false; } else if (sourceformat == "TEI") { - module->AddRenderFilter(m_filters.tei); + module->AddRenderFilter(&m_teiFilter); noDriver = false; } else if (sourceformat == "GBF") { - module->AddRenderFilter(m_filters.gbf); + module->AddRenderFilter(&m_gbfFilter); noDriver = false; } else if (sourceformat == "PLAIN") { - module->AddRenderFilter(m_filters.plain); + module->AddRenderFilter(&m_plainFilter); noDriver = false; } if (noDriver) { //no driver found if ( (moduleDriver == "RawCom") || (moduleDriver == "RawLD") ) { - module->AddRenderFilter(m_filters.plain); + module->AddRenderFilter(&m_plainFilter); noDriver = false; } } @@ -284,7 +262,7 @@ void CSwordBackend::setOption( const CSwordModuleInfo::FilterTypes type, const i setGlobalOption(optionName(type).toUtf8().constData(), value.c_str()); } -void CSwordBackend::setFilterOptions( const CSwordBackend::FilterOptions options) { +void CSwordBackend::setFilterOptions(const FilterOptions &options) { setOption( CSwordModuleInfo::footnotes, options.footnotes ); setOption( CSwordModuleInfo::strongNumbers, options.strongNumbers ); setOption( CSwordModuleInfo::headings, options.headings ); @@ -302,93 +280,27 @@ void CSwordBackend::setFilterOptions( const CSwordBackend::FilterOptions options /** This function searches for a module with the specified description */ CSwordModuleInfo* CSwordBackend::findModuleByDescription(const QString& description) { - Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.modules()) { + Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.moduleList()) { if (mod->config(CSwordModuleInfo::Description) == description) return mod; } return 0; } -/** This function searches for a module with the specified description */ -const QString CSwordBackend::findModuleNameByDescription(const QString& description) { - if (m_moduleDescriptionMap.contains(description)) { - return m_moduleDescriptionMap[description]; - } - return QString::null; -} - /** This function searches for a module with the specified name */ CSwordModuleInfo* CSwordBackend::findModuleByName(const QString& name) { - Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.modules()) { + Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.moduleList()) { if (mod->name() == name) return mod; } return 0; } CSwordModuleInfo* CSwordBackend::findSwordModuleByPointer(const sword::SWModule* const swmodule) { - Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.modules()) { + Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.moduleList()) { if (mod->module() == swmodule ) return mod; } return 0; } -CSwordModuleInfo* CSwordBackend::findModuleByPointer(const CSwordModuleInfo* const module) { - Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.modules()) { - if (mod == module) return mod; - } - return 0; -} - -/** Returns our local config object to store the cipher keys etc. locally for each user. The values of the config are merged with the global config. */ -bool CSwordBackend::moduleConfig(const QString& module, sword::SWConfig& moduleConfig) { - - sword::SectionMap::iterator section; - QDir dir(QString::fromUtf8(configPath)); - bool foundConfig = false; - - QFileInfoList list = dir.entryInfoList(); - if (dir.isReadable()) { - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - - moduleConfig = sword::SWConfig( fileInfo.absoluteFilePath().toLocal8Bit().constData() ); - section = moduleConfig.Sections.find( module.toLocal8Bit().constData() ); - foundConfig = ( section != moduleConfig.Sections.end() ); - } - } - else { //try to read mods.conf - moduleConfig = sword::SWConfig("");//global config - section = config->Sections.find( module.toLocal8Bit().constData() ); - foundConfig = ( section != config->Sections.end() ); - - sword::ConfigEntMap::iterator entry; - - if (foundConfig) { //copy module section - - for (entry = section->second.begin(); entry != section->second.end(); entry++) { - moduleConfig.Sections[section->first].insert(sword::ConfigEntMap::value_type(entry->first, entry->second)); - } - } - } - - if (!foundConfig && configType != 2) { //search in $HOME/.sword/ - - QString myPath = util::directory::getUserHomeSwordModsDir().absolutePath(); - dir.setPath(myPath); - - QFileInfoList list = dir.entryInfoList(); - if (dir.isReadable()) { - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - moduleConfig = sword::SWConfig( fileInfo.absoluteFilePath().toLocal8Bit().constData() ); - section = moduleConfig.Sections.find( module.toLocal8Bit().constData() ); - foundConfig = ( section != moduleConfig.Sections.end() ); - } - } - } - - return foundConfig; -} - /** Returns the text used for the option given as parameter. */ const QString CSwordBackend::optionName( const CSwordModuleInfo::FilterTypes option ) { switch (option) { @@ -490,7 +402,7 @@ const QString CSwordBackend::booknameLanguage( const QString& language ) { //use what sword returns, language may be different QString newLocaleName( sword::LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName() ); - Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.modules()) { + Q_FOREACH (CSwordModuleInfo *mod, m_dataModel.moduleList()) { if ( (mod->type() == CSwordModuleInfo::Bible) || (mod->type() == CSwordModuleInfo::Commentary) ) { //Create a new key, it will get the default bookname language ((sword::VerseKey*)(mod->module()->getKey()))->setLocale( newLocaleName.toUtf8().constData() ); @@ -609,3 +521,26 @@ QStringList CSwordBackend::swordDirList() const { return swordDirSet.values(); } + +void CSwordBackend::deleteOrphanedIndices() { + QDir dir(CSwordModuleInfo::getGlobalBaseIndexLocation()); + dir.setFilter(QDir::Dirs); + CSwordModuleInfo* module; + + for (unsigned int i = 0; i < dir.count(); i++) { + if (dir[i] != "." && dir[i] != "..") { + if ( (module = this->findModuleByName(dir[i])) ) { //mod exists + if (!module->hasIndex()) { //index files found, but wrong version etc. + qDebug() << "deleting outdated index for module" << dir[i]; + CSwordModuleInfo::deleteIndexForModule( dir[i] ); + } + } + else { //no module exists + if (CBTConfig::get( CBTConfig::autoDeleteOrphanedIndices ) ) { + qDebug() << "deleting orphaned index in directory" << dir[i]; + CSwordModuleInfo::deleteIndexForModule( dir[i] ); + } + } + } + } +} diff --git a/src/backend/managers/cswordbackend.h b/src/backend/managers/cswordbackend.h index c8b4f77..68be102 100644 --- a/src/backend/managers/cswordbackend.h +++ b/src/backend/managers/cswordbackend.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,6 +16,14 @@ #include <QStringList> #include "backend/drivers/cswordmoduleinfo.h" #include "backend/bookshelfmodel/btbookshelfmodel.h" +#include "backend/filters/gbftohtml.h" +#include "backend/filters/osistohtml.h" +#include "backend/filters/plaintohtml.h" +#include "backend/filters/teitohtml.h" +#include "backend/filters/thmltohtml.h" +#include "backend/rendering/cbookdisplay.h" +#include "backend/rendering/cchapterdisplay.h" +#include "backend/rendering/centrydisplay.h" // Sword includes: #include <swmgr.h> @@ -25,20 +33,17 @@ #include <localemgr.h> #include <utilstr.h> -namespace Rendering { -class CEntryDisplay; -class CChapterDisplay; -class CBookDisplay; -} +/** + \brief The backend layer main class, a backend implementation of Sword. + + This is the implementation of CBackend for Sword. It's additionally derived + from SWMgr to provide functions of Sword. -/** The backend layer main class. - * This is the implementation of CBackend for Sword. It's additionally derived from SWMgr - * to provide functions of Sword. - * - * @short The backend implementation of Sword - * @author The BibleTime team - * @version $Id: cswordbackend.h,v 1.58 2007/03/14 21:32:47 joachim Exp $ - */ + \note Mostly, only one instance of this class is used. This instance is + created by BibleTime::initBackends() and is destroyed by + BibleTimeApp::~BibleTimeApp(). Only when \ref BackendNotSingleton + "managing modules" separate backends are created. +*/ class CSwordBackend : public QObject, public sword::SWMgr { Q_OBJECT public: @@ -52,32 +57,6 @@ class CSwordBackend : public QObject, public sword::SWMgr { OtherChange = 16 }; - /** Filter options. Filter options to - * control the text display of modules. Uses int and not bool because not all - * options have just two toggle values. - */ - struct FilterOptions { - int footnotes; /**< 0 for disabled, 1 for enabled */ - int strongNumbers; /**< 0 for disabled, 1 for enabled */ - int headings; /**< 0 for disabled, 1 for enabled */ - int morphTags; /**< 0 for disabled, 1 for enabled */ - int lemmas; /**< 0 for disabled, 1 for enabled */ - int hebrewPoints; /**< 0 for disabled, 1 for enabled */ - int hebrewCantillation; /**< 0 for disabled, 1 for enabled */ - int greekAccents; /**< 0 for disabled, 1 for enabled */ - int textualVariants; /**< Number n to enabled the n-th variant */ - int redLetterWords; /**< 0 for disabled, 1 for enabled */ - int scriptureReferences; /**< 0 for disabled, 1 for enabled */ - int morphSegmentation; /**< 0 for disabled, 1 for enabled */ - }; - - /** Control the display of a text. - */ - struct DisplayOptions { - int lineBreaks; - int verseNumbers; - }; - /** The error codes which may be returned by the @ref Load() call. */ enum LoadError { // the values exist to cast from the char return of SWMgr::Load @@ -86,12 +65,6 @@ class CSwordBackend : public QObject, public sword::SWMgr { NoModules = 1 }; /** - * The constructor of the Sword backend. - * It creates the SWModule objects using SWMgr's methods, it adds the necessary - * filters for the module format. - */ - CSwordBackend(); - /** * The constructor of the Sword backend. This is actually used nowhere. * Notice that using augmentHome=false can mess up the system because it is true elsewhere. * @param path The path which is used to load modules @@ -104,6 +77,19 @@ class CSwordBackend : public QObject, public sword::SWMgr { */ ~CSwordBackend(); + /** Creates and returns the instance. */ + static inline CSwordBackend *createInstance() { + Q_ASSERT(m_instance == 0); + m_instance = new CSwordBackend(); + return m_instance; + } + + /** Returns the singleton instance, creating it if one does not exist. */ + static inline CSwordBackend *instance() { return m_instance; } + + /** Destroys the singleton instance, if one exists. */ + static void destroyInstance() { delete m_instance; } + /** * This function returns the list of available modules managed by this * backend. You have to call initModules() first; This method is @@ -134,8 +120,8 @@ class CSwordBackend : public QObject, public sword::SWMgr { * @param enable If this is true the option will be enabled, otherwise it will be disabled. */ void setOption( const CSwordModuleInfo::FilterTypes type, const int state ); - /** */ - void setFilterOptions( const CSwordBackend::FilterOptions options ); + + void setFilterOptions(const FilterOptions &options); /** * Sets the language for the international booknames of Sword. * @param langName The abbreviation string which should be used for the Sword backend @@ -147,12 +133,7 @@ class CSwordBackend : public QObject, public sword::SWMgr { * @return pointer to the desired module; null if no module has the specified description */ CSwordModuleInfo* findModuleByDescription(const QString& description); - /** - * This function searches for a module with the specified description - * @param description The description of the desired module - * @return pointer to the desired module; null if no module has the specified description - */ - const QString findModuleNameByDescription(const QString& description); + /** * This function searches for a module with the specified name * @param name The name of the desired module @@ -165,21 +146,12 @@ class CSwordBackend : public QObject, public sword::SWMgr { * @return pointer to the desired module; null if no module has the specified name */ CSwordModuleInfo* findSwordModuleByPointer(const sword::SWModule* const swmodule); - /** - * This function searches for a module which is the same as the passed module. - * @param module The module which should be used for searching the new one. May be child of a different backend. - * @return Pointer to the desired module; null if no module has the specified name - */ - CSwordModuleInfo* findModuleByPointer(const CSwordModuleInfo* const module); + /** * @return Our global config object which contains the configs of all modules merged together. */ inline sword::SWConfig* getConfig() const; - /** - * Tries to find the config object for the module. The second paramter will be the found config. - * @return True if the config was found, false if not. If false is returned the moduleConfig object is in undefined/unknwon state. - */ - bool moduleConfig(const QString& module, sword::SWConfig& moduleConfig ); + /** * Returns the text used for the option given as parameter. * @param The paramter enum @@ -195,11 +167,7 @@ class CSwordBackend : public QObject, public sword::SWMgr { * @param The translated option name */ static const QString translatedOptionName(const CSwordModuleInfo::FilterTypes option ); - /** - * Returns the version of the Sword library. - * @return The version used by this backend - */ - inline const sword::SWVersion Version(); + /** * Reload all Sword modules. */ @@ -212,22 +180,39 @@ class CSwordBackend : public QObject, public sword::SWMgr { QList<CSwordModuleInfo*> takeModulesFromList(QStringList names); /** - * Returns a list of pointers to modules, created from a list of module names. + \returns a list of pointers to modules, created from a list of module + names. + */ + QList<CSwordModuleInfo*> getPointerList(const QStringList &names); + + /** + \returns a list of pointers to const modules, created from a list of + module names. */ - QList<CSwordModuleInfo*> getPointerList(QStringList names); + QList<const CSwordModuleInfo*> getConstPointerList(const QStringList &names); /** Sword prefix list. * @return A list of all known Sword prefix dirs */ QStringList swordDirList() const; + /** + * delete all orphaned indexes (no module present) if autoDeleteOrphanedIndices is true + * delete all indices of modules where hasIndex() returns false (because of wrong index version etc.) + */ + void deleteOrphanedIndices(); signals: void sigSwordSetupChanged(CSwordBackend::SetupChangedReason reason); protected: /** - * Adds a render filter to the module. - * This is used to apply our own render filters to our modules instead of the sword filters + Creates the SWModule objects using SWMgr's methods, it adds the + necessary filters for the module format. + */ + CSwordBackend(); + + /** + * Reimplemented from sword::SWMgr. */ void AddRenderFilters(sword::SWModule *module, sword::ConfigEntMap §ion); /** @@ -239,32 +224,27 @@ class CSwordBackend : public QObject, public sword::SWMgr { QString getPrivateSwordConfigPath() const; QString getPrivateSwordConfigFile() const; - private: - // Filters - struct Filters { - sword::SWFilter* gbf; - sword::SWFilter* plain; - sword::SWFilter* thml; - sword::SWFilter* osis; - sword::SWFilter* tei; - } m_filters; - - struct Displays { - Rendering::CChapterDisplay* chapter; - Rendering::CEntryDisplay* entry; - Rendering::CBookDisplay* book; - } m_displays; + private: /* Fields: */ + // Filters: + Filters::GbfToHtml m_gbfFilter; + Filters::OsisToHtml m_osisFilter; + Filters::PlainToHtml m_plainFilter; + Filters::TeiToHtml m_teiFilter; + Filters::ThmlToHtml m_thmlFilter; + + // Displays: + Rendering::CChapterDisplay m_chapterDisplay; + Rendering::CEntryDisplay m_entryDisplay; + Rendering::CBookDisplay m_bookDisplay; BtBookshelfModel m_dataModel; - QMap<QString, QString> m_moduleDescriptionMap; -}; -Q_DECLARE_METATYPE(CSwordBackend::FilterOptions) -Q_DECLARE_METATYPE(CSwordBackend::DisplayOptions) + static CSwordBackend *m_instance; +}; /**Returns The list of modules managed by this backend*/ inline const QList<CSwordModuleInfo*> &CSwordBackend::moduleList() const { - return m_dataModel.modules(); + return m_dataModel.moduleList(); } inline BtBookshelfModel *CSwordBackend::model() { @@ -276,9 +256,4 @@ inline sword::SWConfig* CSwordBackend::getConfig() const { return config; } -/** Returns the version of the Sword library. */ -inline const sword::SWVersion CSwordBackend::Version() { - return sword::SWVersion::currentVersion; -} - #endif diff --git a/src/backend/managers/referencemanager.cpp b/src/backend/managers/referencemanager.cpp index 4fc5e53..de41af2 100644 --- a/src/backend/managers/referencemanager.cpp +++ b/src/backend/managers/referencemanager.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,12 +10,10 @@ #include "backend/managers/referencemanager.h" #include <algorithm> - #include <QRegExp> #include <QDebug> #include "backend/config/cbtconfig.h" #include "backend/keys/cswordversekey.h" -#include "util/cpointers.h" /** Returns a hyperlink used to be imbedded in the display windows. At the moment the format is sword://module/key */ @@ -87,15 +85,15 @@ const QString ReferenceManager::encodeHyperlink( const QString moduleName, const case Bible: //bibles or commentary keys need parsing case Commentary: { - /* CSwordModuleInfo* mod = CPointers::backend()->findModuleByName(moduleName); + /* CSwordModuleInfo* mod = CSwordBackend::instance()()->findModuleByName(moduleName); - ParseOptions options; - options.refDestinationModule = mod->name(); - options.refBase = - options.sourceLanguage = mod->module()->Lang(); - options.destinationLanguage = "en"; + ParseOptions options; + options.refDestinationModule = mod->name(); + options.refBase = + options.sourceLanguage = mod->module()->Lang(); + options.destinationLanguage = "en"; - ret.append( parseVerseReference(key, options) ); //we add the english key, so drag and drop will work in all cases*/ + ret.append( parseVerseReference(key, options) ); //we add the english key, so drag and drop will work in all cases*/ ret.append(key); break; } @@ -237,20 +235,6 @@ bool ReferenceManager::decodeHyperlink( const QString& hyperlink, QString& modul return true; } -const QString ReferenceManager::encodeReference(const QString &module, const QString &reference) { - //return QString("(%1)%2").arg(module).arg(reference); - return QString("(").append(module).append(")").append(reference); -} - -void ReferenceManager::decodeReference(QString &dragreference, QString &module, QString &reference) { - const int pos = dragreference.indexOf(")"); - const QString fallbackModule = dragreference.mid( 1, pos - 1); - dragreference = dragreference.mid(pos + 1); - - module = fallbackModule; - reference = dragreference; -} - /** Returns true if the parameter is a hyperlink. */ bool ReferenceManager::isHyperlink( const QString& hyperlink ) { return ( hyperlink.left(8) == "sword://") @@ -341,7 +325,7 @@ ReferenceManager::Type ReferenceManager::typeFromModule( const CSwordModuleInfo: /** Parses the given verse references using the given language and the module.*/ const QString ReferenceManager::parseVerseReference( const QString& ref, const ReferenceManager::ParseOptions& options) { - CSwordModuleInfo* const mod = CPointers::backend()->findModuleByName(options.refDestinationModule); + CSwordModuleInfo* const mod = CSwordBackend::instance()->findModuleByName(options.refDestinationModule); //Q_ASSERT(mod); tested later if (!mod) { @@ -371,19 +355,19 @@ const QString ReferenceManager::parseVerseReference( const QString& ref, const R CSwordVerseKey baseKey(0); baseKey.setLocale( sourceLanguage.toUtf8().constData() ); - baseKey.key( options.refBase ); //probably in the sourceLanguage + baseKey.setKey(options.refBase); //probably in the sourceLanguage baseKey.setLocale( "en_US" ); //english works in all environments as base -// CSwordVerseKey dummy(0); +// CSwordVerseKey dummy(0); //HACK: We have to workaround a Sword bug, we have to set the default locale to the same as the sourceLanguage ! - const QString oldLocaleName = CPointers::backend()->booknameLanguage(); - CPointers::backend()->booknameLanguage(sourceLanguage); + const QString oldLocaleName = CSwordBackend::instance()->booknameLanguage(); + CSwordBackend::instance()->booknameLanguage(sourceLanguage); sword::VerseKey dummy; dummy.setLocale( sourceLanguage.toUtf8().constData() ); Q_ASSERT( !strcmp(dummy.getLocale(), sourceLanguage.toUtf8().constData()) ); -// qDebug("Parsing '%s' in '%s' using '%s' as base, source lang '%s', dest lang '%s'", ref.latin1(), options.refDestinationModule.latin1(), baseKey.key().latin1(), sourceLanguage.latin1(), destinationLanguage.latin1()); +// qDebug("Parsing '%s' in '%s' using '%s' as base, source lang '%s', dest lang '%s'", ref.latin1(), options.refDestinationModule.latin1(), baseKey.key().latin1(), sourceLanguage.latin1(), destinationLanguage.latin1()); for (QStringList::iterator it = refList.begin(); it != refList.end(); it++) { //The listkey may contain more than one item, because a ref lik "Gen 1:3,5" is parsed into two single refs @@ -416,6 +400,6 @@ const QString ReferenceManager::parseVerseReference( const QString& ref, const R } - CPointers::backend()->booknameLanguage(oldLocaleName); + CSwordBackend::instance()->booknameLanguage(oldLocaleName); return ret; } diff --git a/src/backend/managers/referencemanager.h b/src/backend/managers/referencemanager.h index fdef8b2..a07b480 100644 --- a/src/backend/managers/referencemanager.h +++ b/src/backend/managers/referencemanager.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -47,20 +47,7 @@ bool decodeHyperlink( const QString& hyperlink, QString& module, QString& key, T * @return The encoded hyperlink */ const QString encodeHyperlink( const QString module, const QString key, const Type type); -/** -* Puts a module Name and a Reference together in the 'draggable' form -* (module)reference -* @param module The name of the module -* @param reference The key reference as text -* @return The encoded reference using module and reference -* @author Martin Gruner -*/ -const QString encodeReference(const QString &module, const QString &reference); -/** -* decodes a 'draggable' reference into a modulename and a reference -* @author Martin Gruner -*/ -void decodeReference(QString &dragreference, QString &module, QString &reference); + /** * Returns true if the parameter is a hyperlink. * @param hyperlink The string which is tested diff --git a/src/backend/rendering/cbookdisplay.cpp b/src/backend/rendering/cbookdisplay.cpp index 9da57f2..259e904 100644 --- a/src/backend/rendering/cbookdisplay.cpp +++ b/src/backend/rendering/cbookdisplay.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "backend/rendering/cbookdisplay.h" -#include <boost/scoped_ptr.hpp> +#include <QSharedPointer> #include <QtAlgorithms> #include "backend/drivers/cswordbookmoduleinfo.h" @@ -17,12 +17,18 @@ #include "backend/rendering/cdisplayrendering.h" -/** Returns the rendered text using the modules in the list and using the key parameter. The displayoptions and filter options are used, too. */ -const QString Rendering::CBookDisplay::text( const QList<CSwordModuleInfo*>& modules, const QString& keyName, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions ) { - CSwordBookModuleInfo* book = dynamic_cast<CSwordBookModuleInfo*>(modules.first()); +const QString Rendering::CBookDisplay::text( + const QList<const CSwordModuleInfo*> &modules, + const QString &keyName, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ + typedef CSwordBookModuleInfo CSBMI; + + const CSBMI* book = dynamic_cast<const CSBMI*>(modules.first()); Q_ASSERT(book); - CSwordBackend::DisplayOptions dOpts = displayOptions; + DisplayOptions dOpts = displayOptions; dOpts.lineBreaks = true; //books should render with blocks, not with inlined sections CDisplayRendering render(dOpts, filterOptions); @@ -32,10 +38,10 @@ const QString Rendering::CBookDisplay::text( const QList<CSwordModuleInfo*>& mod // the number of levels which should be display together, 1 means display no entries together int displayLevel = book->config( CSwordModuleInfo::DisplayLevel ).toInt(); - boost::scoped_ptr<CSwordTreeKey> key ( + QSharedPointer<CSwordTreeKey> key ( dynamic_cast<CSwordTreeKey*>( CSwordKey::createInstance(book) ) ); - key->key(keyName); //set the key to position we'd like to get + key->setKey(keyName); //set the key to position we'd like to get const unsigned long offset = key->getOffset(); @@ -60,7 +66,7 @@ const QString Rendering::CBookDisplay::text( const QList<CSwordModuleInfo*>& mod int possibleLevels = 1; //we start with the default value of displayLevel, which means no entries together - while ( key->parent() && (key->key() != "/") && !key->key().isEmpty() ) {//add parents + while ( key->sword::TreeKeyIdx::parent() && (key->key() != "/") && !key->key().isEmpty() ) {//add parents ++possibleLevels; }; @@ -90,7 +96,7 @@ const QString Rendering::CBookDisplay::text( const QList<CSwordModuleInfo*>& mod // at the moment we're at the lowest level, so we only have to go up! for (int currentLevel = 1; currentLevel < displayLevel; ++currentLevel) { //we start again with 1 == standard of displayLevel - if ( !key->parent() ) { //something went wrong although we checked before! Be safe and return entry's text + if ( !key->sword::TreeKeyIdx::parent() ) { //something went wrong although we checked before! Be safe and return entry's text tree.append( new CDisplayRendering::KeyTreeItem( key->key(), modules, itemSettings ) ); const QString renderedText = render.renderKeyTree(tree); @@ -108,7 +114,7 @@ const QString Rendering::CBookDisplay::text( const QList<CSwordModuleInfo*>& mod //const bool hasToplevelText = !key->strippedText().isEmpty(); key->firstChild(); //go to the first sibling on the same level - setupRenderTree(key.get(), &tree, keyName); + setupRenderTree(key.data(), &tree, keyName); const QString renderedText = render.renderKeyTree(tree); @@ -126,7 +132,9 @@ void Rendering::CBookDisplay::setupRenderTree(CSwordTreeKey * swordTree, CTextRe CTextRendering::KeyTreeItem::Settings settings; settings.highlight = (key == highlightKey); - CTextRendering::KeyTreeItem* item = new CTextRendering::KeyTreeItem(key, swordTree->module(0), settings ); + /// \todo Check whether this is correct: + CTextRendering::KeyTreeItem *item = new CTextRendering::KeyTreeItem( + key, swordTree->module(), settings); renderTree->append( item ); if (swordTree->hasChildren()) { //print tree for the child items diff --git a/src/backend/rendering/cbookdisplay.h b/src/backend/rendering/cbookdisplay.h index 832249f..be5ec9b 100644 --- a/src/backend/rendering/cbookdisplay.h +++ b/src/backend/rendering/cbookdisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,26 +20,27 @@ class CSwordTreeKey; namespace Rendering { /** -* A CEntryDisplay implementation which works on tree-based GenBook modules -* of Sword. -* @short CEntryDisplay implementation for GenBook modules, -* @author The BibleTime team -*/ - -class CBookDisplay : public CEntryDisplay { - public: // Public methods - virtual ~CBookDisplay() {} +* \brief CEntryDisplay implementation for GenBook modules, - /** - * Returns the rendered text using the modules in the list and using the key parameter. - * The displayoptions and filter options are used, too. - */ - virtual const QString text( const QList<CSwordModuleInfo*>& modules, const QString& key, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions); - - protected: - void setupRenderTree(CSwordTreeKey* swordTree, CTextRendering::KeyTree* renderTree, const QString& highlightKey); + A CEntryDisplay implementation which works on tree-based GenBook modules of + Sword. +*/ +class CBookDisplay: public CEntryDisplay { + public: /* Methods: */ + virtual inline ~CBookDisplay() {} + + /** Reimplemented from CEntryDisplay. */ + virtual const QString text(const QList<const CSwordModuleInfo*> &modules, + const QString &key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); + + protected: /* Methods: */ + void setupRenderTree(CSwordTreeKey *swordTree, + CTextRendering::KeyTree *renderTree, + const QString &highlightKey); }; -} +} // namespace Rendering #endif diff --git a/src/backend/rendering/cchapterdisplay.cpp b/src/backend/rendering/cchapterdisplay.cpp index 74063cf..31b56b8 100644 --- a/src/backend/rendering/cchapterdisplay.cpp +++ b/src/backend/rendering/cchapterdisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,11 +14,18 @@ #include "backend/rendering/cdisplayrendering.h" -const QString Rendering::CChapterDisplay::text( const QList<CSwordModuleInfo*>& modules, const QString& keyName, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions ) { +const QString Rendering::CChapterDisplay::text( + const QList<const CSwordModuleInfo*> &modules, + const QString &keyName, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ + typedef CSwordBibleModuleInfo CSBMI; + Q_ASSERT( modules.count() >= 1 ); Q_ASSERT( !keyName.isEmpty() ); - CSwordModuleInfo* module = modules.first(); + const CSwordModuleInfo *module = modules.first(); if (modules.count() == 1) module->module()->setSkipConsecutiveLinks( true ); //skip empty, linked verses @@ -37,14 +44,14 @@ const QString Rendering::CChapterDisplay::text( const QList<CSwordModuleInfo*>& if (module->type() == CSwordModuleInfo::Bible) { ((sword::VerseKey*)(module->module()->getKey()))->Headings(1); //HACK: enable headings for VerseKeys - CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module); - Q_ASSERT(bible); + Q_ASSERT(dynamic_cast<const CSBMI*>(module) != 0); + const CSBMI *bible = static_cast<const CSBMI*>(module); CSwordVerseKey k1(module); k1.Headings(1); - k1.key(keyName); + k1.setKey(keyName); - if (k1.Chapter() == 1) k1.Chapter(0); //Chapter 1, start with 0:0, otherwise X:0 + if (k1.Chapter() == 1) k1.Chapter(0); //Chapter 1, start with 0:0, otherwise X:0 k1.Verse(0); diff --git a/src/backend/rendering/cchapterdisplay.h b/src/backend/rendering/cchapterdisplay.h index 3b3d363..a13ebc3 100644 --- a/src/backend/rendering/cchapterdisplay.h +++ b/src/backend/rendering/cchapterdisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,24 +15,25 @@ namespace Rendering { -/** Chapter rendering. -* A CEntryDisplay implementation mde for Bibles to display whole chapters -* at once. -* @author The BibleTime team -*/ - -class CChapterDisplay : public CEntryDisplay { +/** + \brief CEntryDisplay implementation for whole chapters. - public: // Public methods - virtual ~CChapterDisplay() {} + A CEntryDisplay implementation made for Bibles to display whole chapters at + once. +*/ +class CChapterDisplay: public CEntryDisplay { + public: /* Methods: */ + virtual inline ~CChapterDisplay() {} /** - * Returns the rendered text using the modules in the list and using the key parameter. - * The displayoptions and filter options are used, too. + Reimplemented from CEntryDisplay. */ - virtual const QString text( const QList<CSwordModuleInfo*>& modules, const QString& key, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions); + virtual const QString text(const QList<const CSwordModuleInfo*> &modules, + const QString &key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); }; -} +} // namespace Rendering #endif diff --git a/src/backend/rendering/cdisplayrendering.cpp b/src/backend/rendering/cdisplayrendering.cpp index cc3f7c9..c79cfdf 100644 --- a/src/backend/rendering/cdisplayrendering.cpp +++ b/src/backend/rendering/cdisplayrendering.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,15 +16,21 @@ #include "backend/keys/cswordversekey.h" #include "backend/managers/cdisplaytemplatemgr.h" #include "backend/managers/referencemanager.h" -#include "util/cpointers.h" namespace Rendering { -CDisplayRendering::CDisplayRendering(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) - : CHTMLExportRendering(CHTMLExportRendering::Settings(true), displayOptions, filterOptions) {} +CDisplayRendering::CDisplayRendering(const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) + : CHTMLExportRendering(CHTMLExportRendering::Settings(true), + displayOptions, filterOptions) +{ + // Intentionally empty +} -const QString CDisplayRendering::entryLink( const KeyTreeItem& item, CSwordModuleInfo* module ) { +const QString CDisplayRendering::entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module) +{ QString linkText; const bool isBible = module && (module->type() == CSwordModuleInfo::Bible); @@ -32,7 +38,7 @@ const QString CDisplayRendering::entryLink( const KeyTreeItem& item, CSwordModul vk.Headings(true); if (isBible) { - vk.key(item.key()); + vk.setKey(item.key()); } if (isBible && (vk.Verse() == 0)) { @@ -105,7 +111,7 @@ const QString CDisplayRendering::keyToHTMLAnchor(const QString& key) { } const QString CDisplayRendering::finishText( const QString& oldText, KeyTree& tree ) { - QList<CSwordModuleInfo*> modules = collectModules(&tree); + QList<const CSwordModuleInfo*> modules = collectModules(&tree); qDebug() << "CDisplayRendering::finishText"; //marking words is very slow, we have to find a better solution @@ -139,9 +145,9 @@ const QString CDisplayRendering::finishText( const QString& oldText, KeyTree& tr const CLanguageMgr::Language* const lang = (modules.count() >= 1) ? modules.first()->language() - : CPointers::languageMgr()->defaultLanguage(); + : CLanguageMgr::instance()->defaultLanguage(); - CDisplayTemplateMgr* tMgr = CPointers::displayTemplateManager(); + CDisplayTemplateMgr *tMgr = CDisplayTemplateMgr::instance(); //Q_ASSERT(modules.count() >= 1); diff --git a/src/backend/rendering/cdisplayrendering.h b/src/backend/rendering/cdisplayrendering.h index f66e556..8b222ac 100644 --- a/src/backend/rendering/cdisplayrendering.h +++ b/src/backend/rendering/cdisplayrendering.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,12 +25,14 @@ class CDisplayRendering : public CHTMLExportRendering { static const QString keyToHTMLAnchor(const QString& key); CDisplayRendering( - CSwordBackend::DisplayOptions displayOptions = CBTConfig::getDisplayOptionDefaults(), - CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults() + const DisplayOptions &displayOptions = CBTConfig::getDisplayOptionDefaults(), + const FilterOptions &filterOptions = CBTConfig::getFilterOptionDefaults() ); protected: - virtual const QString entryLink( const KeyTreeItem& item, CSwordModuleInfo* const module ); + virtual const QString entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module); + virtual const QString finishText( const QString&, KeyTree& tree ); }; diff --git a/src/backend/rendering/centrydisplay.cpp b/src/backend/rendering/centrydisplay.cpp index b6c7a27..d1b2a34 100644 --- a/src/backend/rendering/centrydisplay.cpp +++ b/src/backend/rendering/centrydisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -24,15 +24,17 @@ using namespace Rendering; -/** Returns the rendered text using the modules in the list and using the key parameter. - * The displayoptions and filter options are used, too. - */ -const QString CEntryDisplay::text( const QList<CSwordModuleInfo*>& modules, const QString& keyName, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions ) { +const QString CEntryDisplay::text( + const QList<const CSwordModuleInfo*> &modules, + const QString &keyName, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ CDisplayRendering render(displayOptions, filterOptions); //no highlighted key and no extra key link in the text CTextRendering::KeyTreeItem::Settings normal_settings(false, CTextRendering::KeyTreeItem::Settings::CompleteShort); - CSwordModuleInfo* module = modules.first(); + const CSwordModuleInfo *module = modules.first(); Rendering::CTextRendering::KeyTree tree; @@ -42,7 +44,7 @@ const QString CEntryDisplay::text( const QList<CSwordModuleInfo*>& modules, cons CSwordVerseKey k1(module); k1.Headings(1); - k1.key(keyName); + k1.setKey(keyName); // don't print the key CTextRendering::KeyTreeItem::Settings preverse_settings(false, CTextRendering::KeyTreeItem::Settings::NoKey); diff --git a/src/backend/rendering/centrydisplay.h b/src/backend/rendering/centrydisplay.h index 5f410a5..08a55c4 100644 --- a/src/backend/rendering/centrydisplay.h +++ b/src/backend/rendering/centrydisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,35 +10,28 @@ #ifndef CENTRYDISPLAY_H #define CENTRYDISPLAY_H -#include "util/cpointers.h" - #include <QString> -#include "backend/managers/cswordbackend.h" // Sword includes: #include <swdisp.h> class CSwordModuleInfo; +struct DisplayOptions; +struct FilterOptions; namespace Rendering { -/** -* The reimplementation of SWDisplay to fit our needs. -* @short Display implementation -* @author The BibleTime team -*/ - -class CEntryDisplay : public sword::SWDisplay, public CPointers { - +class CEntryDisplay: public sword::SWDisplay { public: - virtual ~CEntryDisplay() {} - /** - * Returns the rendered text using the modules in the list and using the key parameter. - * The displayoptions and filter options are used, too. + \returns the rendered text using the modules in the list and using the + key parameter. */ - virtual const QString text( const QList<CSwordModuleInfo*>& modules, const QString& key, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions); + virtual const QString text(const QList<const CSwordModuleInfo*> &modules, + const QString &key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); }; diff --git a/src/backend/rendering/chtmlexportrendering.cpp b/src/backend/rendering/chtmlexportrendering.cpp index 6a571c6..3d82602 100644 --- a/src/backend/rendering/chtmlexportrendering.cpp +++ b/src/backend/rendering/chtmlexportrendering.cpp @@ -2,15 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "backend/rendering/chtmlexportrendering.h" -#include <boost/scoped_ptr.hpp> -#include <iostream> +#include <QSharedPointer> #include <QDebug> #include "backend/drivers/cswordmoduleinfo.h" @@ -18,42 +17,43 @@ #include "backend/keys/cswordversekey.h" #include "backend/managers/cdisplaytemplatemgr.h" #include "backend/managers/clanguagemgr.h" -#include "util/cpointers.h" +#ifdef BT_DEBUG namespace { -/* - * Helper function to dump a verse with all its enty attributes - */ - +/** Helper function to dump a verse with all its enty attributes. */ void dumpEntryAttributes(sword::SWModule *module) { - std::cout << "Attributes for key: " << module->getKeyText() << std::endl; + qDebug() << "Attributes for key: " << module->getKeyText(); sword::AttributeTypeList::iterator i1; sword::AttributeList::iterator i2; sword::AttributeValue::iterator i3; for (i1 = module->getEntryAttributes().begin(); i1 != module->getEntryAttributes().end(); i1++) { - std::cout << "[ " << i1->first << " ]\n"; + qDebug() << "[ " << i1->first << " ]"; for (i2 = i1->second.begin(); i2 != i1->second.end(); i2++) { - std::cout << "\t[ " << i2->first << " ]\n"; + qDebug() << "\t[ " << i2->first << " ]"; for (i3 = i2->second.begin(); i3 != i2->second.end(); i3++) { - std::cout << "\t\t" << i3->first << " = " << i3->second << "\n"; + qDebug() << "\t\t" << i3->first << " = " << i3->second; } } } - std::cout << std::endl; } -} +} // anonymous namespace +#endif namespace Rendering { -CHTMLExportRendering::CHTMLExportRendering(const CHTMLExportRendering::Settings& settings, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) +CHTMLExportRendering::CHTMLExportRendering( + const CHTMLExportRendering::Settings &settings, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) : m_displayOptions(displayOptions), - m_filterOptions(filterOptions), - m_settings(settings) {} - -CHTMLExportRendering::~CHTMLExportRendering() {} + m_filterOptions(filterOptions), + m_settings(settings) +{ + // Intentionally empty +} const QString CHTMLExportRendering::renderEntry( const KeyTreeItem& i, CSwordKey* k) { @@ -62,13 +62,13 @@ const QString CHTMLExportRendering::renderEntry( const KeyTreeItem& i, CSwordKey ret.append(i.getAlternativeContent()); // Q_ASSERT(i.hasChildItems()); - + if (!i.childList()->isEmpty()) { KeyTree * const tree = i.childList(); - const QList<CSwordModuleInfo*> modules = collectModules(tree); + const QList<const CSwordModuleInfo*> modules = collectModules(tree); - if (modules.count() == 1) { //insert the direction into the sorrounding div + if (modules.count() == 1) { //insert the direction into the surrounding div ret.insert( 5, QString("dir=\"%1\" ").arg((modules.first()->textDirection() == CSwordModuleInfo::LeftToRight) ? "ltr" : "rtl" )); } @@ -82,13 +82,13 @@ const QString CHTMLExportRendering::renderEntry( const KeyTreeItem& i, CSwordKey } - const QList<CSwordModuleInfo*>& modules( i.modules() ); + const QList<const CSwordModuleInfo*> &modules(i.modules()); if (modules.count() == 0) { return QString(""); //no module present for rendering } - boost::scoped_ptr<CSwordKey> scoped_key( !k ? CSwordKey::createInstance(modules.first()) : 0 ); - CSwordKey* key = k ? k : scoped_key.get(); + QSharedPointer<CSwordKey> scoped_key( !k ? CSwordKey::createInstance(modules.first()) : 0 ); + CSwordKey* key = k ? k : scoped_key.data(); Q_ASSERT(key); CSwordVerseKey* myVK = dynamic_cast<CSwordVerseKey*>(key); @@ -100,19 +100,17 @@ const QString CHTMLExportRendering::renderEntry( const KeyTreeItem& i, CSwordKey //declarations out of the loop for optimization QString entry; - QString keyText; bool isRTL; QString preverseHeading; QString langAttr; QString key_renderedText; - QList<CSwordModuleInfo*>::const_iterator end_modItr = modules.end(); + QList<const CSwordModuleInfo*>::const_iterator end_modItr = modules.end(); - for (QList<CSwordModuleInfo*>::const_iterator mod_Itr(modules.begin()); mod_Itr != end_modItr; ++mod_Itr) { - key->module(*mod_Itr); - key->key( i.key() ); + for (QList<const CSwordModuleInfo*>::const_iterator mod_Itr(modules.begin()); mod_Itr != end_modItr; ++mod_Itr) { + key->setModule(*mod_Itr); + key->setKey(i.key()); - keyText = key->key(); isRTL = ((*mod_Itr)->textDirection() == CSwordModuleInfo::RightToLeft); entry = QString::null; @@ -144,7 +142,16 @@ const QString CHTMLExportRendering::renderEntry( const KeyTreeItem& i, CSwordKey (*mod_Itr)->module()->getEntryAttributes()["Heading"]["Preverse"].end(); for (; it != end; ++it) { - preverseHeading = QString::fromUtf8(it->second.c_str()); + QString unfiltered = it->second.c_str(); + + /// \todo This is only a preliminary workaround to strip the tags: + QRegExp filter("<title>(.*)"); + if (unfiltered.indexOf(filter) >= 0) { + preverseHeading = filter.cap(1); + } else { + preverseHeading = unfiltered; + } + /// \todo Take care of the heading type! if (!preverseHeading.isEmpty()) { entry.append("

setDisplayOptions( m_displayOptions ); - CPointers::backend()->setFilterOptions( m_filterOptions ); + //CSwordBackend::instance()()->setDisplayOptions( m_displayOptions ); + CSwordBackend::instance()->setFilterOptions( m_filterOptions ); } const QString CHTMLExportRendering::finishText( const QString& text, KeyTree& tree ) { - const QList modules = collectModules(&tree); + const QList modules = collectModules(&tree); const CLanguageMgr::Language* const lang = modules.first()->language(); - CDisplayTemplateMgr* tMgr = CPointers::displayTemplateManager(); + CDisplayTemplateMgr *tMgr = CDisplayTemplateMgr::instance(); CDisplayTemplateMgr::Settings settings; settings.modules = modules; settings.langAbbrev = ((modules.count() == 1) && lang->isValid()) ? lang->abbrev() : "unknown"; @@ -231,7 +238,11 @@ const QString CHTMLExportRendering::finishText( const QString& text, KeyTree& tr /*! \fn CHTMLExportRendering::entryLink( KeyTreeItem& item ) */ -const QString CHTMLExportRendering::entryLink( const KeyTreeItem& item, CSwordModuleInfo* ) { +const QString CHTMLExportRendering::entryLink(const KeyTreeItem& item, + const CSwordModuleInfo *module) +{ + Q_UNUSED(module); + return item.key(); } diff --git a/src/backend/rendering/chtmlexportrendering.h b/src/backend/rendering/chtmlexportrendering.h index 065bb85..97e632d 100644 --- a/src/backend/rendering/chtmlexportrendering.h +++ b/src/backend/rendering/chtmlexportrendering.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,6 +14,7 @@ #include "backend/config/cbtconfig.h" #include "backend/managers/cswordbackend.h" +#include "btglobal.h" namespace Rendering { @@ -37,20 +38,21 @@ class CHTMLExportRendering : public CTextRendering { }; CHTMLExportRendering( - const Settings& settings, - CSwordBackend::DisplayOptions displayOptions = CBTConfig::getDisplayOptionDefaults(), - CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults() + const Settings &settings, + const DisplayOptions &displayOptions = CBTConfig::getDisplayOptionDefaults(), + const FilterOptions &filterOptions = CBTConfig::getFilterOptionDefaults() ); - virtual ~CHTMLExportRendering(); + virtual inline ~CHTMLExportRendering() {}; protected: virtual const QString renderEntry( const KeyTreeItem&, CSwordKey* = 0 ); virtual const QString finishText( const QString&, KeyTree& tree ); - virtual const QString entryLink( const KeyTreeItem& item, CSwordModuleInfo* module ); + virtual const QString entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module); virtual void initRendering(); - CSwordBackend::DisplayOptions m_displayOptions; - CSwordBackend::FilterOptions m_filterOptions; + DisplayOptions m_displayOptions; + FilterOptions m_filterOptions; Settings m_settings; }; diff --git a/src/backend/rendering/cplaintextexportrendering.cpp b/src/backend/rendering/cplaintextexportrendering.cpp index fdbf78d..cad5eb9 100644 --- a/src/backend/rendering/cplaintextexportrendering.cpp +++ b/src/backend/rendering/cplaintextexportrendering.cpp @@ -2,40 +2,48 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "backend/rendering/cplaintextexportrendering.h" -#include +#include #include "backend/keys/cswordkey.h" namespace Rendering { -CPlainTextExportRendering::CPlainTextExportRendering(const CPlainTextExportRendering::Settings& settings, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) - : CHTMLExportRendering(settings, displayOptions, filterOptions) {} +CPlainTextExportRendering::CPlainTextExportRendering( + const CPlainTextExportRendering::Settings &settings, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) + : CHTMLExportRendering(settings, displayOptions, filterOptions) +{ + // Intentionally empty +} -CPlainTextExportRendering::~CPlainTextExportRendering() {} +const QString CPlainTextExportRendering::renderEntry(const KeyTreeItem &i, + CSwordKey *k) +{ + Q_UNUSED(k); -const QString CPlainTextExportRendering::renderEntry( const KeyTreeItem& i, CSwordKey* ) { if (!m_settings.addText) { return QString(i.key()).append("\n"); } - QList modules = i.modules(); - boost::scoped_ptr key( CSwordKey::createInstance(modules.first()) ); + QList modules = i.modules(); + QSharedPointer key( CSwordKey::createInstance(modules.first()) ); QString renderedText = QString(i.key()).append(":\n"); QString entry; // for (CSwordModuleInfo* m = modules.first(); m; m = modules.next()) { - QList::iterator end_it = modules.end(); + QList::iterator end_it = modules.end(); - for (QList::iterator it(modules.begin()); it != end_it; ++it) { - key->module(*it); - key->key( i.key() ); + for (QList::iterator it(modules.begin()); it != end_it; ++it) { + key->setModule(*it); + key->setKey(i.key()); /// \todo Check this code entry.append(key->strippedText()).append("\n"); diff --git a/src/backend/rendering/cplaintextexportrendering.h b/src/backend/rendering/cplaintextexportrendering.h index 5ebbb24..d14192e 100644 --- a/src/backend/rendering/cplaintextexportrendering.h +++ b/src/backend/rendering/cplaintextexportrendering.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,11 +25,11 @@ class CPlainTextExportRendering : public CHTMLExportRendering { public: CPlainTextExportRendering( - const Settings& settings, - CSwordBackend::DisplayOptions displayOptions = CBTConfig::getDisplayOptionDefaults(), - CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults() + const Settings &settings, + const DisplayOptions &displayOptions = CBTConfig::getDisplayOptionDefaults(), + const FilterOptions &filterOptions = CBTConfig::getFilterOptionDefaults() ); - virtual ~CPlainTextExportRendering(); + virtual inline ~CPlainTextExportRendering() {}; protected: virtual const QString renderEntry( const KeyTreeItem&, CSwordKey* = 0 ); diff --git a/src/backend/rendering/ctextrendering.cpp b/src/backend/rendering/ctextrendering.cpp index 645b5d6..586d11e 100644 --- a/src/backend/rendering/ctextrendering.cpp +++ b/src/backend/rendering/ctextrendering.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "backend/rendering/ctextrendering.h" -#include +#include #include #include @@ -26,17 +26,20 @@ using namespace Rendering; -CTextRendering::KeyTreeItem::KeyTreeItem(const QString& key, CSwordModuleInfo const * mod, const Settings settings ) - : m_settings( settings ), +CTextRendering::KeyTreeItem::KeyTreeItem(const QString &key, + const CSwordModuleInfo *module, + const Settings &settings) + : m_settings(settings), m_moduleList(), m_key( key ), m_childList(), m_stopKey( QString::null ), m_alternativeContent( QString::null ) { - m_moduleList.append( const_cast(mod) ); //BAD CODE + m_moduleList.append( const_cast(module) ); //BAD CODE } -CTextRendering::KeyTreeItem::KeyTreeItem(const QString& content, const Settings settings ) +CTextRendering::KeyTreeItem::KeyTreeItem(const QString &content, + const Settings &settings) : m_settings( settings ), m_moduleList(), m_key( QString::null ), @@ -45,7 +48,9 @@ CTextRendering::KeyTreeItem::KeyTreeItem(const QString& content, const Settings m_alternativeContent( content ) { } -CTextRendering::KeyTreeItem::KeyTreeItem(const QString& key, const QList& mods, const Settings settings ) +CTextRendering::KeyTreeItem::KeyTreeItem(const QString &key, + const QList &mods, + const Settings &settings) : m_settings( settings ), m_moduleList( mods ), m_key( key ), @@ -76,11 +81,10 @@ CTextRendering::KeyTreeItem::KeyTreeItem(const KeyTreeItem& i) } -CTextRendering::KeyTreeItem::~KeyTreeItem() { - qDeleteAll(m_childList); -} - -CTextRendering::KeyTreeItem::KeyTreeItem(const QString& startKey, const QString& stopKey, CSwordModuleInfo* module, const Settings settings) +CTextRendering::KeyTreeItem::KeyTreeItem(const QString &startKey, + const QString &stopKey, + const CSwordModuleInfo *module, + const Settings &settings) : m_settings( settings ), m_moduleList(), m_key( startKey ), @@ -94,10 +98,10 @@ CTextRendering::KeyTreeItem::KeyTreeItem(const QString& startKey, const QString& if (module->type() == CSwordModuleInfo::Bible) { CSwordVerseKey start(module); - start.key(startKey); + start.setKey(startKey); CSwordVerseKey stop(module); - stop.key(stopKey); + stop.setKey(stopKey); if (!m_key.isEmpty() && !m_stopKey.isEmpty()) { //we have a range of keys bool ok = true; @@ -154,13 +158,13 @@ const QString& CTextRendering::KeyTreeItem::getAlternativeContent() const { return m_alternativeContent; } -const QList CTextRendering::collectModules(KeyTree* const tree) const { +const QList CTextRendering::collectModules(KeyTree* const tree) const { //collect all modules which are available and used by child items - QList modules; + QList modules; foreach (KeyTreeItem* c, (*tree)) { Q_ASSERT(c); - foreach (CSwordModuleInfo* mod, c->modules()) { + foreach (const CSwordModuleInfo* mod, c->modules()) { if (!modules.contains(mod)) { modules.append(mod); } @@ -172,20 +176,22 @@ const QList CTextRendering::collectModules(KeyTree* const tre const QString CTextRendering::renderKeyTree( KeyTree& tree ) { initRendering(); - QList modules = collectModules(&tree); + QList modules = collectModules(&tree); QString t; //optimization for entries with the same key - boost::scoped_ptr key( + QSharedPointer key( (modules.count() == 1) ? CSwordKey::createInstance(modules.first()) : 0 ); - foreach (KeyTreeItem* c, tree) { - if (modules.count() == 1) { //this optimizes the rendering, only one key created for all items - key->key( c->key() ); - t.append( renderEntry( *c, key.get()) ); + if (modules.count() == 1) { //this optimizes the rendering, only one key created for all items + foreach (KeyTreeItem* c, tree) { + key->setKey(c->key()); + t.append( renderEntry( *c, key.data()) ); } - else { + } + else { + foreach (KeyTreeItem* c, tree) { t.append( renderEntry( *c ) ); } } @@ -193,19 +199,25 @@ const QString CTextRendering::renderKeyTree( KeyTree& tree ) { return finishText(t, tree); } -const QString CTextRendering::renderKeyRange( const QString& start, const QString& stop, const QList& modules, const QString& highlightKey, const KeyTreeItem::Settings& keySettings ) { +const QString CTextRendering::renderKeyRange( + const QString &start, + const QString &stop, + const QList &modules, + const QString &highlightKey, + const KeyTreeItem::Settings &keySettings) +{ - CSwordModuleInfo* module = modules.first(); + const CSwordModuleInfo *module = modules.first(); //qWarning( "renderKeyRange start %s stop %s \n", start.latin1(), stop.latin1() ); - boost::scoped_ptr lowerBound( CSwordKey::createInstance(module) ); - lowerBound->key(start); + QSharedPointer lowerBound( CSwordKey::createInstance(module) ); + lowerBound->setKey(start); - boost::scoped_ptr upperBound( CSwordKey::createInstance(module) ); - upperBound->key(stop); + QSharedPointer upperBound( CSwordKey::createInstance(module) ); + upperBound->setKey(stop); - sword::SWKey* sw_start = dynamic_cast(lowerBound.get()); - sword::SWKey* sw_stop = dynamic_cast(upperBound.get()); + sword::SWKey* sw_start = dynamic_cast(lowerBound.data()); + sword::SWKey* sw_stop = dynamic_cast(upperBound.data()); Q_ASSERT((*sw_start == *sw_stop) || (*sw_start < *sw_stop)); @@ -216,10 +228,10 @@ const QString CTextRendering::renderKeyRange( const QString& start, const QStrin KeyTree tree; KeyTreeItem::Settings settings = keySettings; - CSwordVerseKey* vk_start = dynamic_cast(lowerBound.get()); + CSwordVerseKey* vk_start = dynamic_cast(lowerBound.data()); Q_ASSERT(vk_start); - CSwordVerseKey* vk_stop = dynamic_cast(upperBound.get()); + CSwordVerseKey* vk_stop = dynamic_cast(upperBound.data()); Q_ASSERT(vk_stop); bool ok = true; @@ -250,13 +262,15 @@ const QString CTextRendering::renderKeyRange( const QString& start, const QStrin return QString::null; } -const QString CTextRendering::renderSingleKey( const QString& key, const QList& moduleList, const KeyTreeItem::Settings& settings ) { +const QString CTextRendering::renderSingleKey( + const QString &key, + const QList &modules, + const KeyTreeItem::Settings &settings) +{ KeyTree tree; - tree.append( new KeyTreeItem(key, moduleList, settings) ); + tree.append( new KeyTreeItem(key, modules, settings) ); const QString renderedText = renderKeyTree(tree); qDeleteAll(tree); return renderedText; } - - diff --git a/src/backend/rendering/ctextrendering.h b/src/backend/rendering/ctextrendering.h index b6dd5e1..c6b187a 100644 --- a/src/backend/rendering/ctextrendering.h +++ b/src/backend/rendering/ctextrendering.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -53,13 +53,26 @@ class CTextRendering { KeyRenderingFace keyRenderingFace; }; - KeyTreeItem(const QString& key, CSwordModuleInfo const * module, const Settings settings); - KeyTreeItem(const QString& key, const QList& modules, const Settings settings); - KeyTreeItem(const QString& startKey, const QString& stopKey, CSwordModuleInfo* module, const Settings settings); - KeyTreeItem(const QString& content, const Settings settings); - KeyTreeItem(const KeyTreeItem& i); + KeyTreeItem(const QString &key, + const CSwordModuleInfo *module, + const Settings &settings); - virtual ~KeyTreeItem(); + KeyTreeItem(const QString &key, + const QList &modules, + const Settings &settings); + + KeyTreeItem(const QString &startKey, + const QString &stopKey, + const CSwordModuleInfo *module, + const Settings &settings); + + KeyTreeItem(const QString &content, const Settings &settings); + + KeyTreeItem(const KeyTreeItem &i); + + virtual inline ~KeyTreeItem() { + qDeleteAll(m_childList); + } const QString& getAlternativeContent() const; inline void setAlternativeContent(const QString& newContent) { @@ -70,7 +83,7 @@ class CTextRendering { return !m_alternativeContent.isNull(); }; - inline const QList& modules() const { + inline const QList& modules() const { return m_moduleList; }; @@ -83,13 +96,13 @@ class CTextRendering { }; inline KeyTree* childList() const; -// inline const bool hasChildItems() const; +// inline const bool hasChildItems() const; protected: KeyTreeItem(); Settings m_settings; - QList m_moduleList; + QList m_moduleList; QString m_key; mutable KeyTree m_childList; @@ -101,12 +114,20 @@ class CTextRendering { const QString renderKeyTree( KeyTree& ); - const QString renderKeyRange( const QString& start, const QString& stop, const QList& modules, const QString& hightlightKey = QString::null, const KeyTreeItem::Settings& settings = KeyTreeItem::Settings() ); + const QString renderKeyRange( + const QString &start, + const QString &stop, + const QList &modules, + const QString &hightlightKey = QString::null, + const KeyTreeItem::Settings &settings = KeyTreeItem::Settings()); - const QString renderSingleKey( const QString& key, const QList&, const KeyTreeItem::Settings& settings = KeyTreeItem::Settings() ); + const QString renderSingleKey( + const QString &key, + const QList &modules, + const KeyTreeItem::Settings &settings = KeyTreeItem::Settings()); protected: - const QList collectModules(KeyTree* const tree) const; + const QList collectModules(KeyTree* const tree) const; virtual const QString renderEntry( const KeyTreeItem&, CSwordKey* = 0 ) = 0; virtual const QString finishText( const QString&, KeyTree& tree ) = 0; virtual void initRendering() = 0; @@ -117,7 +138,7 @@ inline CTextRendering::KeyTree* CTextRendering::KeyTreeItem::childList() const { } // //inline const bool CTextRendering::KeyTreeItem::hasChildItems() const { -// return !m_childList.isEmpty(); +// return !m_childList.isEmpty(); //} } diff --git a/src/bibletime.cpp b/src/bibletime.cpp index f2478d9..d4fa90d 100644 --- a/src/bibletime.cpp +++ b/src/bibletime.cpp @@ -2,16 +2,13 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "bibletime.h" -#include -#include -#include #include #include #include @@ -19,8 +16,10 @@ #include #include #include +#include #include #include +#include #include "backend/config/cbtconfig.h" #include "backend/drivers/cswordbiblemoduleinfo.h" #include "backend/drivers/cswordbookmoduleinfo.h" @@ -38,17 +37,22 @@ #include "frontend/displaywindow/cwritewindow.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/searchdialog/csearchdialog.h" -#include "util/cpointers.h" #include "util/cresmgr.h" #include "util/directory.h" using namespace Profile; -BibleTime::BibleTime() - : m_WindowWasMaximizedBeforeFullScreen(false) { +BibleTime *BibleTime::m_instance = 0; + +BibleTime::BibleTime(QWidget *parent, Qt::WindowFlags flags) + : QMainWindow(parent, flags), m_WindowWasMaximizedBeforeFullScreen(false) +{ namespace DU = util::directory; + Q_ASSERT(m_instance == 0); + m_instance = this; + QSplashScreen splash; bool showSplash = CBTConfig::get(CBTConfig::logo); QString splashHtml; @@ -90,16 +94,23 @@ BibleTime::BibleTime() Qt::AlignCenter); } initActions(); + initMenubar(); + initToolbars(); initConnections(); readSettings(); setWindowTitle("BibleTime " BT_VERSION); setWindowIcon(DU::getIcon(CResMgr::mainWindow::icon)); + retranslateUi(); } BibleTime::~BibleTime() { // delete m_dcopInterface; // The backend is deleted by the BibleTimeApp instance +#ifdef BT_DEBUG + deleteDebugWindow(); +#endif + saveSettings(); } /** Saves the properties of BibleTime to the application wide configfile */ @@ -107,17 +118,18 @@ void BibleTime::saveSettings() { /// \todo how to write settings? //accel()->writeSettings(CBTConfig::getConfig()); - CBTConfig::set(CBTConfig::toolbar, m_viewToolbar_action->isChecked()); + CBTConfig::set(CBTConfig::toolbar, m_viewToolbarAction->isChecked()); // set the default to false /* CBTConfig::set(CBTConfig::autoTileVertical, false); CBTConfig::set(CBTConfig::autoTileHorizontal, false); CBTConfig::set(CBTConfig::autoCascade, false); */ - CBTConfig::set(CBTConfig::autoTileVertical, m_windowAutoTileVertical_action->isChecked()); - CBTConfig::set(CBTConfig::autoTileHorizontal, m_windowAutoTileHorizontal_action->isChecked()); - CBTConfig::set(CBTConfig::autoTile, m_windowAutoTile_action->isChecked()); - CBTConfig::set(CBTConfig::autoCascade, m_windowAutoCascade_action->isChecked()); + CBTConfig::set(CBTConfig::autoTileVertical, m_windowAutoTileVerticalAction->isChecked()); + CBTConfig::set(CBTConfig::autoTileHorizontal, m_windowAutoTileHorizontalAction->isChecked()); + CBTConfig::set(CBTConfig::autoTile, m_windowAutoTileAction->isChecked()); + CBTConfig::set(CBTConfig::autoTabbed, m_windowAutoTabbedAction->isChecked()); + CBTConfig::set(CBTConfig::autoCascade, m_windowAutoCascadeAction->isChecked()); CProfile* p = m_profileMgr.startupProfile(); if (p) { @@ -131,31 +143,36 @@ void BibleTime::readSettings() { // accel()->readSettings(CBTConfig::getConfig()); CBTConfig::setupAccelSettings(CBTConfig::application, m_actionCollection); - m_viewToolbar_action->setChecked( CBTConfig::get(CBTConfig::toolbar) ); - slotToggleToolbar(); + m_viewToolbarAction->setChecked( CBTConfig::get(CBTConfig::toolbar) ); + slotToggleMainToolbar(); if ( CBTConfig::get(CBTConfig::autoTileVertical) ) { - m_windowAutoTileVertical_action->setChecked( true ); - m_windowManualMode_action->setChecked(false); + m_windowAutoTileVerticalAction->setChecked( true ); + m_windowManualModeAction->setChecked(false); slotAutoTileVertical(); } else if ( CBTConfig::get(CBTConfig::autoTileHorizontal) ) { - m_windowAutoTileHorizontal_action->setChecked( true ); - m_windowManualMode_action->setChecked(false); + m_windowAutoTileHorizontalAction->setChecked( true ); + m_windowManualModeAction->setChecked(false); slotAutoTileHorizontal(); } else if ( CBTConfig::get(CBTConfig::autoTile) ) { - m_windowAutoTile_action->setChecked(true); - m_windowManualMode_action->setChecked(false); + m_windowAutoTileAction->setChecked(true); + m_windowManualModeAction->setChecked(false); slotAutoTile(); } + else if ( CBTConfig::get(CBTConfig::autoTabbed) ) { + m_windowAutoTabbedAction->setChecked(true); + m_windowManualModeAction->setChecked(false); + slotAutoTabbed(); + } else if ( CBTConfig::get(CBTConfig::autoCascade) ) { - m_windowAutoCascade_action->setChecked(true); - m_windowManualMode_action->setChecked(false); + m_windowAutoCascadeAction->setChecked(true); + m_windowManualModeAction->setChecked(false); slotAutoCascade(); } else { - m_windowManualMode_action->setChecked(true); + m_windowManualModeAction->setChecked(true); slotManualArrangementMode(); } } @@ -167,10 +184,8 @@ CDisplayWindow* BibleTime::createReadDisplayWindow(QList modu CDisplayWindow* displayWindow = CDisplayWindowFactory::createReadInstance(modules, m_mdi); if ( displayWindow ) { displayWindow->init(); - if (m_mdi->subWindowList().count() == 0) - displayWindow->showMaximized(); - else - displayWindow->show(); + m_mdi->addSubWindow(displayWindow); + displayWindow->show(); // if (!key.isEmpty()) displayWindow->lookupKey(key); } @@ -192,7 +207,7 @@ CDisplayWindow* BibleTime::createReadDisplayWindow(CSwordModuleInfo* module, con return createReadDisplayWindow(list, key); } -CDisplayWindow* BibleTime::createWriteDisplayWindow(CSwordModuleInfo* module, const QString& key, const CDisplayWindow::WriteWindowType& type) { +CDisplayWindow* BibleTime::createWriteDisplayWindow(CSwordModuleInfo* module, const QString& key, const CWriteWindow::WriteWindowType& type) { qApp->setOverrideCursor( QCursor(Qt::WaitCursor) ); QList modules; @@ -201,6 +216,7 @@ CDisplayWindow* BibleTime::createWriteDisplayWindow(CSwordModuleInfo* module, co CDisplayWindow* displayWindow = CDisplayWindowFactory::createWriteInstance(modules, m_mdi, type); if ( displayWindow ) { displayWindow->init(); + m_mdi->addSubWindow(displayWindow); if (m_mdi->subWindowList().count() == 0) displayWindow->showMaximized(); else @@ -216,45 +232,64 @@ CDisplayWindow* BibleTime::moduleEditPlain(CSwordModuleInfo *module) { /// \todo Refactor this. return createWriteDisplayWindow(module, QString::null, - CDisplayWindow::PlainTextWindow); + CWriteWindow::PlainTextWindow); } CDisplayWindow* BibleTime::moduleEditHtml(CSwordModuleInfo *module) { /// \todo Refactor this. return createWriteDisplayWindow(module, QString::null, - CDisplayWindow::HTMLWindow); + CWriteWindow::HTMLWindow); } void BibleTime::searchInModule(CSwordModuleInfo *module) { /// \todo Refactor this. - QList modules; + QList modules; modules.append(module); Search::CSearchDialog::openDialog(modules, QString::null); } -void BibleTime::moduleUnlock(CSwordModuleInfo *module) { +bool BibleTime::moduleUnlock(CSwordModuleInfo *module, QWidget *parent) { + /// \todo Write a proper unlocking dialog with integrated error messages. + QString unlockKey; bool ok; - const QString unlockKey = - QInputDialog::getText( - this, - tr("Unlock Work"), - tr("Enter the unlock key for this work."), - QLineEdit::Normal, - module->config(CSwordModuleInfo::CipherKey), - &ok + for (;;) { + unlockKey = QInputDialog::getText( + parent, tr("Unlock Work"), tr("Enter the unlock key for %1.").arg(module->name()), + QLineEdit::Normal, module->config(CSwordModuleInfo::CipherKey), &ok ); - if (ok) { - /// \todo Refactor. Unlock the module via a global modules model. - if (module->unlock(unlockKey)) { - CPointers::backend()->reloadModules(CSwordBackend::OtherChange); + if (!ok) return false; + module->unlock(unlockKey); + + /// \todo refactor this module reload + /* There is currently a deficiency in sword 1.6.1 in that backend->setCipherKey() does + * not work correctly for modules from which data was already fetched. Therefore we have to + * reload the modules. + */ + { + const QString moduleName(module->name()); + CSwordBackend *backend = CSwordBackend::instance(); + backend->reloadModules(CSwordBackend::OtherChange); + module = backend->findModuleByName(moduleName); + Q_ASSERT(module != 0); } + + if (!module->isLocked()) break; + QMessageBox::warning(parent, tr("Warning: Invalid unlock key!"), + tr("The unlock key you provided did not properly unlock this " + "module. Please try again.")); } + return true; +} + +void BibleTime::slotModuleUnlock(CSwordModuleInfo *module) { + moduleUnlock(module, this); } void BibleTime::moduleAbout(CSwordModuleInfo *module) { - BTAboutModuleDialog *dialog(new BTAboutModuleDialog(this, module)); + BTAboutModuleDialog *dialog = new BTAboutModuleDialog(module, this); + dialog->setAttribute(Qt::WA_DeleteOnClose); // Destroy dialog when closed dialog->show(); dialog->raise(); } @@ -269,28 +304,25 @@ void BibleTime::refreshDisplayWindows() { } /** Refresh main window accelerators */ -void::BibleTime::refreshBibleTimeAccel() { +void BibleTime::refreshBibleTimeAccel() { CBTConfig::setupAccelSettings(CBTConfig::application, m_actionCollection); } -/** Called before quit. */ -void BibleTime::slot_aboutToQuit() { - saveSettings(); -} - -/** Called before a window is closed */ -bool BibleTime::queryClose() { - qDebug() << "BibleTime::queryClose"; - bool ret = true; - - foreach(QMdiSubWindow* subWindow, m_mdi->subWindowList()) { +void BibleTime::closeEvent(QCloseEvent *event) { + /* + Sequentially queries all open subwindows whether its fine to close them. If some sub- + window returns false, the querying is stopped and the close event is ignored. If all + subwindows return true, the close event is accepted. + */ + Q_FOREACH(QMdiSubWindow *subWindow, m_mdi->subWindowList()) { if (CDisplayWindow* window = dynamic_cast(subWindow->widget())) { - ret = ret && window->queryClose(); + if (!window->queryClose()) { + event->ignore(); + return; + } } - qDebug() << "return value:" << ret; } - qDebug() << "final return value:" << ret; - return ret; + event->accept(); } /** Restores the workspace if the flag for this is set in the config. */ @@ -300,32 +332,20 @@ void BibleTime::restoreWorkspace() { } } -/** Processes the commandline options given to BibleTime. */ -void BibleTime::processCommandline() { - QStringList args = qApp->QCoreApplication::arguments(); - - if (args.contains("--help") || args.contains("-h") || args.contains("/h") || args.contains("/?")) { - std::cout << "BibleTime" << std::endl << "--help (-h, /h, /?): Show this help message and exit" - << std::endl << "--ignore-session: open a clean session" << std:: endl << "--open-default-bible : " - << "Open the default Bible with the reference " << std::endl; - std::cout << "Some Qt arguments:" << std::endl << "-reverse: reverse the UI layout direction" - << std::endl; - exit(0); - //printHelpAndExit(); +void BibleTime::processCommandline(bool ignoreSession, const QString &bibleKey) { + if (CBTConfig::get(CBTConfig::crashedTwoTimes)) { + return; } - if ( !CBTConfig::get(CBTConfig::crashedTwoTimes) && - !args.contains("--ignore-session") ) { + + if (!ignoreSession) { restoreWorkspace(); } - if ( args.contains("--open-default-bible") && - !CBTConfig::get(CBTConfig::crashedLastTime) && - !CBTConfig::get(CBTConfig::crashedTwoTimes)) { - int index = args.indexOf("--open-default-bible"); - QString bibleKey; - if (index >= 0 && (index + 1) < args.size()) { - bibleKey = args.at(index + 1); - } + if (CBTConfig::get(CBTConfig::crashedLastTime)) { + return; + } + + if (!bibleKey.isNull()) { CSwordModuleInfo* bible = CBTConfig::get(CBTConfig::standardBible); if (bibleKey == "random") { CSwordVerseKey vk(0); @@ -336,10 +356,16 @@ void BibleTime::processCommandline() { int newIndex = rand() % maxIndex; vk.setPosition(sword::TOP); vk.Index(newIndex); - bibleKey = vk.key(); + createReadDisplayWindow(bible, vk.key()); + } else { + createReadDisplayWindow(bible, bibleKey); } - createReadDisplayWindow(bible, bibleKey); - m_mdi->myTileVertical();//we are sure only one window is open, which should be displayed fullscreen in the working area + + /* + We are sure only one window is open - it should be displayed + fullscreen in the working area: + */ + m_mdi->myTileVertical(); } } @@ -348,9 +374,3 @@ bool BibleTime::event(QEvent* event) { Search::CSearchDialog::closeDialog(); return QMainWindow::event(event); } - -QAction* BibleTime::getAction(const QString& actionName) -{ - return m_actionCollection->action(actionName); -} - diff --git a/src/bibletime.h b/src/bibletime.h index 89d0473..f35be23 100644 --- a/src/bibletime.h +++ b/src/bibletime.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,9 +14,13 @@ #include #include "frontend/displaywindow/cdisplaywindow.h" +#include "frontend/displaywindow/cwritewindow.h" #include "frontend/profile/cprofile.h" #include "frontend/profile/cprofilemgr.h" #include +#ifdef BT_DEBUG +#include +#endif namespace InfoDisplay { @@ -24,11 +28,13 @@ class CInfoDisplay; } class BtActionClass; class BtBookshelfDockWidget; +class BtOpenWorkAction; class CBookmarkIndex; class CDisplayWindow; class CMDIArea; class CSwordModuleInfo; class QAction; +class QLabel; class QMenu; class QToolBar; class QSplitter; @@ -45,7 +51,7 @@ class QSignalMapper; * and SWKey (CSwordLDKey). *

*

- * The classes used to handle all module based stuff are derived from CModuleInfo. + * The classes used to handle all module based stuff are derived from CSwordModuleInfo. * The module classes are: CSwordModuleInfo (for Sword modules), * CSwordBibleModuleInfo (for bibles), CSwordCommentaryModuleInfo (for commentaries) and * CSwordLexiconModuleInfo (for lexicons). @@ -67,44 +73,43 @@ class QSignalMapper; * @page frontend The structure of the frontend * *

- * The frontend contains the classes which interact with the user. For example the main index, - * the display windows, the searchdialog or the other parts. + * The frontend contains the classes which interact with the user. For example the + * display windows, the searchdialog or the other parts. + *

+ * The display windows which provide functionality are CBibleReadWindow for + * Bibles, CBookReadWindow for books, CCommentaryReadWindow for commentaries and CLexiconReadWindow for + * lexicon and dictionaries. CHTMLWriteWindow and CPlainWriteWindows are used for editing the Personal Commentary. *

- * The main index is implemented in the class CGroupManager, the items of the - * main index are implemented in the class CGroupManagerItem. - * Each CGroupManagerItem has a type() function which returns the type of - * the object (Module, Bookmark or Group).
- * The display windows are all derived from the base class CPresenter. - * The display windows which handle Sword modules are all derived from the - * CSwordPresenter class. - * The display windows which provide functionality are CBiblePresenter for - * Bibles, CCommentaryPresenter for commentaries and CLexiconPresenter for - * lexicon and dictionaries. - * CSwordPresenter provides the essential base functions which are - * reimplemented in the derived classes (for example CSwordPresenter::lookup).
+ * + * The class CDisplayWindow is the class that various views with in the windows are derived. *

+ * * Another important part of the frontend are the keychoosers. * They provide an interface to choose a key of a module. * The interface for different module types is different. * The base class is CKeyChooser which is the factory for the derived classes. * Use the function CKeyChooser::createInstance to get the correct * keychooser implementation for the desired module.
+ *

+ * Some major toolbar widgets are CKeyChooser and BtDisplaySettingsButton. *

*/ /** @mainpage BibleTime - sourcecode documentation * BibleTime main page. - *

This is the sourcecode documentation of BibleTime, a Bible study tool for KDE/Linux. - * BibleTime is devided in two major parts, the backend and the frontend. + *

This is the sourcecode documentation of BibleTime, a Bible study tool. + *

+ * The main class of BibleTime is called @ref BibleTime, which is the main window + * and initializes all important parts at startup. + *

+ * BibleTime is divided in two major parts, the backend and the frontend. + * The text display windows belong to the @ref frontend. * The backend is mainly a wrapper around Sword's classes to use Qt functionality * to allow easy access to it's functionality and to have it in a (more or less :) * object oriented structure.


*

- * -Introduction to the backend: @ref backend
* -Introduction to the frontend: @ref frontend.
- * The main class of BibleTime is called @ref BibleTime, which is the main window - * and initializes all important parts at startup. The text display windows - * belong to the @ref frontend. + * -Introduction to the backend: @ref backend
*

*/ @@ -122,16 +127,15 @@ class BibleTime : public QMainWindow { friend class CDisplayWindow; friend class BibleTimeDBusAdaptor; Q_OBJECT + public: - /** - * construtor of BibleTime - */ - BibleTime(); - /** - * destructor of BibleTime - */ + + BibleTime(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~BibleTime(); + static inline BibleTime *instance() { return m_instance; } + /** * Reads the settings from the configfile and sets the right properties. */ @@ -157,9 +161,51 @@ class BibleTime : public QMainWindow { */ void saveConfigSettings(); /** - * Get QAction from actionCollection + * Get pointer to Navigation toolbar + */ + inline QToolBar *navToolBar() const { + return m_navToolBar; + } + /** + * Get pointer to Works toolbar + */ + inline BtModuleChooserBar *worksToolBar() const { + return m_worksToolBar; + } + /** + * Get pointer to Tools toolbar */ - QAction* getAction(const QString& actionName); + inline QToolBar *toolsToolBar() const { + return m_toolsToolBar; + } + /** + * Get pointer to Format toolbar + */ + inline QToolBar *formatToolBar() const { + return m_formatToolBar; + } + + /** + \returns a pointer to the info display. + */ + inline InfoDisplay::CInfoDisplay *infoDisplay() const { + return m_infoDisplay; + } + + /** + * Clears the actions of the MDI related toolbars + */ + void clearMdiToolBars(); + + /** + Displays a dialog which asks the user an unlock key for the given module and tries + to unlock the module. If an invalid unlock key is given, a warning message is + issued and the user is again asked for the key. + \param[in] module The module to unlock. + \param[in] parent The parent widget for the unlock dialogs. + \returns whether the module was successfully unlocked. + */ + static bool moduleUnlock(CSwordModuleInfo *module, QWidget *parent = 0); public slots: /** @@ -178,10 +224,20 @@ class BibleTime : public QMainWindow { * Opens the bible study howto. */ void openOnlineHelp_Howto(); + /** - * Processes the commandline options given to BibleTime. + * Open the Tip Dialog */ - void processCommandline(); + void slotOpenTipDialog(); + + /** + Processes the command-line options given to BibleTime. + \param[in] ignoreSession Specifies whether --ignore-session was used. + \param[in] bibleKey If --open-default-bible was used, the bible key + specified, or null otherwise. + */ + void processCommandline(bool ignoreSession, const QString &bibleKey); + /** * Creates QAction's that have keyboard shortcuts */ @@ -193,6 +249,10 @@ class BibleTime : public QMainWindow { */ bool event(QEvent* event); /** + * Create the main window menu and toolbar + */ + void createMenuAndToolBar(); + /** * Initializes the sword.conf in the $HOME\Sword directory */ void initSwordConfigFile(); @@ -216,6 +276,18 @@ class BibleTime : public QMainWindow { * Initializes the action objects of the GUI */ void initActions(); + /** + Initializes the toolbars. + */ + void initToolbars(); + /** + Retranslates the UI. + */ + void retranslateUi(); + /** + Retranslates the UI actions. + */ + static void retranslateUiActions(BtActionCollection* ac); /** * Initializes one action object */ @@ -229,10 +301,11 @@ class BibleTime : public QMainWindow { * Refresh main window accelerators */ void refreshBibleTimeAccel(); + /** - * Called before a window is closed + * Reimplemented from QWidget. */ - bool queryClose(); + void closeEvent(QCloseEvent *event); protected slots: /** @@ -240,11 +313,11 @@ class BibleTime : public QMainWindow { */ CDisplayWindow* createReadDisplayWindow(QList modules, const QString& key); CDisplayWindow* createReadDisplayWindow(CSwordModuleInfo* module, const QString& key = QString::null); - CDisplayWindow* createWriteDisplayWindow(CSwordModuleInfo* module, const QString& key, const CDisplayWindow::WriteWindowType& type); + CDisplayWindow* createWriteDisplayWindow(CSwordModuleInfo* module, const QString& key, const CWriteWindow::WriteWindowType& type); CDisplayWindow* moduleEditPlain(CSwordModuleInfo *module); CDisplayWindow* moduleEditHtml(CSwordModuleInfo *module); void searchInModule(CSwordModuleInfo *module); - void moduleUnlock(CSwordModuleInfo *module); + void slotModuleUnlock(CSwordModuleInfo *module); void moduleAbout(CSwordModuleInfo *module); void quit(); @@ -257,19 +330,23 @@ class BibleTime : public QMainWindow { */ void slotOpenWindowsMenuAboutToShow(); /** - * This slot is connected with the windowAutoTile_action object + * This slot is connected with the windowAutoTileVerticalAction object */ void slotAutoTileVertical(); /** - * This slot is connected with the windowAutoTile_action object + * This slot is connected with the windowAutoTileHorizontalAction object */ void slotAutoTileHorizontal(); /** - * This slot is connected with the windowAutoCascade_action object + * This slot is connected with the windowAutoTileAction object */ void slotAutoTile(); /** - * This slot is connected with the windowAutoTile_action object + * This slot is connected with the windowAutoTabbedAction object + */ + void slotAutoTabbed(); + /** + * This slot is connected with the windowAutoCascadeAction object */ void slotAutoCascade(); void slotUpdateWindowArrangementActions( QAction* ); @@ -282,20 +359,22 @@ class BibleTime : public QMainWindow { void slotManualArrangementMode(); /** - * Shows/hides the toolbar + * Shows/hides the main toolbar */ - void slotToggleToolbar(); - + void slotToggleMainToolbar(); + void slotToggleToolsToolbar(); + void slotToggleNavigatorToolbar(); + void slotToggleWorksToolbar(); + void slotToggleFormatToolbar(); + + void slotToggleToolBarsInEachWindow(); + /** * Shows/hides the text window text area headers and sets * configuration that newly opened windows don't user headers. */ void slotToggleTextWindowHeader(); - - void slotToggleTextWindowToolButtons(); - void slotToggleTextWindowNavigator(); - void slotToggleTextWindowModuleChooser(); - + /** * Used to set the active menu */ @@ -346,10 +425,7 @@ class BibleTime : public QMainWindow { * Slot to refresh the save profile and load profile menus. */ void refreshProfileMenus(); - /** - * Called before quit. - */ - void slot_aboutToQuit(); + /** * Open the About Dialog */ @@ -360,8 +436,11 @@ class BibleTime : public QMainWindow { void toggledTextWindowNavigator(bool newState); void toggledTextWindowToolButtons(bool newState); void toggledTextWindowModuleChooser(bool newState); + void toggledTextWindowFormatToolbar(bool newState); private: + static BibleTime *m_instance; + // True if window was maximized before last toggle to full screen. bool m_WindowWasMaximizedBeforeFullScreen; @@ -373,29 +452,71 @@ class BibleTime : public QMainWindow { InfoDisplay::CInfoDisplay* m_infoDisplay; QToolBar* m_mainToolBar; - // VIEW menu actions - QAction* m_viewToolbar_action; - QMenu* m_windowMenu; - QMenu* m_openWindowsMenu; - /** WINDOW menu actions */ - QAction* m_windowCascade_action; - QAction* m_windowTile_action; - QAction* m_windowTileHorizontal_action; - QAction* m_windowTileVertical_action; - QAction* m_windowManualMode_action; - QAction* m_windowAutoCascade_action; - QAction* m_windowAutoTile_action; - QAction* m_windowAutoTileVertical_action; - QAction* m_windowAutoTileHorizontal_action; - QAction* m_windowClose_action; - QAction* m_windowCloseAll_action; + QToolBar* m_navToolBar; + BtModuleChooserBar* m_worksToolBar; + QToolBar* m_toolsToolBar; + QToolBar* m_formatToolBar; + + // File menu: + QMenu *m_fileMenu; + BtOpenWorkAction *m_openWorkAction; + QAction *m_quitAction; + + // View menu: + QMenu *m_viewMenu; + QAction* m_viewToolbarAction; + QAction *m_showBookshelfAction; + QAction *m_showBookmarksAction; + QAction *m_showMagAction; + QMenu *m_toolBarsMenu; + QAction *m_showTextAreaHeadersAction; + QAction *m_showTextWindowNavigationAction; + QAction *m_showTextWindowModuleChooserAction; + QAction *m_showTextWindowToolButtonsAction; + QAction *m_showFormatToolbarAction; + QAction *m_toolbarsInEachWindow; + + // Search menu: + QMenu *m_searchMenu; + QAction *m_searchOpenWorksAction; + QAction *m_searchStandardBibleAction; + + // Window menu: + QMenu *m_windowMenu; + QMenu *m_openWindowsMenu; + QAction *m_windowCascadeAction; + QAction *m_windowTileAction; + QAction *m_windowTileHorizontalAction; + QAction *m_windowTileVerticalAction; + QAction *m_windowManualModeAction; + QMenu *m_windowArrangementMenu; + QAction *m_windowAutoCascadeAction; + QAction *m_windowAutoTileAction; + QAction *m_windowAutoTabbedAction; + QAction *m_windowAutoTileVerticalAction; + QAction *m_windowAutoTileHorizontalAction; + QAction *m_windowCloseAction; + QAction *m_windowCloseAllAction; + + // Settings menu: + QMenu *m_settingsMenu; + QAction *m_setPreferencesAction; + QAction *m_bookshelfManagerAction; + + // Help menu: + QMenu *m_helpMenu; + QAction *m_openHandbookAction; + QAction *m_bibleStudyHowtoAction; + QAction *m_aboutBibleTimeAction; + QAction *m_tipOfTheDayAction; + BtActionCollection* m_actionCollection; QMenu* m_windowSaveProfileMenu; - QAction* m_windowSaveToNewProfile_action; + QAction* m_windowSaveToNewProfileAction; QMenu* m_windowLoadProfileMenu; QMenu* m_windowDeleteProfileMenu; - QAction* m_windowFullscreen_action; + QAction* m_windowFullscreenAction; /** * Signal mapper to map windows to menu items. @@ -425,6 +546,20 @@ class BibleTime : public QMainWindow { // Helper function void syncAllModulesByType(const CSwordModuleInfo::ModuleType type, const QString& key); + + private: + void showOrHideToolBars(); +#ifdef BT_DEBUG + void deleteDebugWindow(); + private slots: + void slotDebugWindowClosing(); + void slotDebugTimeout(); + void slotShowDebugWindow(bool); + private: + QAction *m_debugWidgetAction; + static QLabel *m_debugWindow; + static QMutex m_debugWindowLock; +#endif }; #endif diff --git a/src/bibletime_dbus.cpp b/src/bibletime_dbus.cpp index 6adf71c..e3013db 100644 --- a/src/bibletime_dbus.cpp +++ b/src/bibletime_dbus.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -60,7 +60,7 @@ void BibleTime::syncAllVerseBasedModules(const QString& key) { void BibleTime::openWindow(const QString& moduleName, const QString& key) { qDebug() << "DBUS: open window for module" << moduleName.toLatin1() << "and key" << key.toLatin1(); - CSwordModuleInfo* module = CPointers::backend()->findModuleByName(moduleName); + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); if (module) { createReadDisplayWindow(module, key); } @@ -77,16 +77,17 @@ void BibleTime::openDefaultBible(const QString& key) { QStringList BibleTime::searchInModule(const QString& moduleName, const QString& searchText) { qDebug() << "DBUS: searchInModule" << moduleName.toLatin1(); QStringList ret; - CSwordModuleInfo* mod = CPointers::backend()->findModuleByName(moduleName); + CSwordModuleInfo* mod = CSwordBackend::instance()->findModuleByName(moduleName); if (mod) { + sword::ListKey result; + //mod->search(searchText, CSwordModuleSearch::multipleWords, sword::ListKey()); sword::ListKey scope; - mod->searchIndexed( searchText, scope ); + mod->searchIndexed(searchText, scope, result); - sword::ListKey result = mod->searchResult(); const QString lead = QString("[%1] ").arg(moduleName); - ; + for ( int i = 0; i < result.Count(); ++i ) { sword::SWKey* key = result.getElement(i); Q_ASSERT(key); @@ -111,9 +112,9 @@ QStringList BibleTime::searchInOpenModules(const QString& searchText) { QStringList ret; foreach (QMdiSubWindow* subWindow, m_mdi->subWindowList()) { if (CDisplayWindow* w = dynamic_cast(subWindow->widget())) { - QList windowModules = w->modules(); - QList::iterator end_it = windowModules.end(); - for (QList::iterator it(windowModules.begin()); it != end_it; ++it) { + QList windowModules = w->modules(); + QList::iterator end_it = windowModules.end(); + for (QList::iterator it(windowModules.begin()); it != end_it; ++it) { ret += searchInModule((*it)->name(), searchText); } } @@ -189,7 +190,7 @@ QStringList BibleTime::getModulesOfType(const QString& type) { modType = CSwordModuleInfo::GenericBook; } - QList modList = CPointers::backend()->moduleList(); + QList modList = CSwordBackend::instance()->moduleList(); for (QList::iterator it( modList.begin() ); it != modList.end(); ++it) { if ((*it)->type() == modType) { ret.append( (*it)->name() ); diff --git a/src/bibletime_dbus_adaptor.cpp b/src/bibletime_dbus_adaptor.cpp index 30619ec..bf6ba79 100644 --- a/src/bibletime_dbus_adaptor.cpp +++ b/src/bibletime_dbus_adaptor.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/bibletime_dbus_adaptor.h b/src/bibletime_dbus_adaptor.h index ea4ec69..0f9f301 100644 --- a/src/bibletime_dbus_adaptor.h +++ b/src/bibletime_dbus_adaptor.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -63,19 +63,19 @@ class BibleTimeDBusAdaptor : QDBusAbstractAdaptor { void closeAllModuleWindows(); /** Returns the reference used in the current window. * The format of the returned reference is - * [Module] [Type] OSIS_Reference, + * [Module] [Type] OSIS_Reference, * wtih type one of BIBLE/COMMENTARY/BOOK/LEXICON/UNSUPPORTED * If the type is BIBLE or COMMENTARY the reference is an OSIS ref * in the other cases it's the key name, for books /Chapter/Subsection * for Lexicons just the plain key, e.g. "ADAM". * e.g. - * [KJV] [BIBLE] Gen.1.1 - * [MHC] [COMMENTARY] Gen.1.1 - * [ISBE] [LEXICON] REDEMPTION + * [KJV] [BIBLE] Gen.1.1 + * [MHC] [COMMENTARY] Gen.1.1 + * [ISBE] [LEXICON] REDEMPTION * @return The reference displayed in the currently active module window. Empty if none is active. */ QString getCurrentReference(); - /** Seach the searchText in the specified module. + /** Search the searchText in the specified module. * @param moduleName The module to search in * @param searchText Search for this in the modules * @return The search result. It's in the format [modulename] osis_ref_of_the_found_key. For example "[KJV] Gen.1.1". diff --git a/src/bibletime_init.cpp b/src/bibletime_init.cpp index cbff79f..4ac6350 100644 --- a/src/bibletime_init.cpp +++ b/src/bibletime_init.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,53 +18,65 @@ #include #include #include +#include #include #include "backend/config/cbtconfig.h" #include "backend/managers/btstringmgr.h" #include "backend/managers/clanguagemgr.h" #include "backend/managers/cswordbackend.h" #include "frontend/btbookshelfdockwidget.h" +#include "frontend/btopenworkaction.h" #include "frontend/cinfodisplay.h" #include "frontend/cmdiarea.h" #include "frontend/cprinter.h" #include "frontend/displaywindow/btactioncollection.h" -#include "frontend/mainindex/bookmarks/cbookmarkindex.h" +#include "frontend/displaywindow/btmodulechooserbar.h" +#include "frontend/bookmarks/cbookmarkindex.h" #include "frontend/profile/cprofile.h" #include "frontend/profile/cprofilemgr.h" -#include "util/cpointers.h" #include "util/cresmgr.h" #include "util/directory.h" // Sword includes: #include +#ifdef BT_DEBUG +#include +#include +#include +#include +#endif + using namespace InfoDisplay; using namespace Profile; /**Initializes the view of this widget*/ void BibleTime::initView() { + + // Create menu and toolbar before the mdi area + createMenuAndToolBar(); + m_mdi = new CMDIArea(this); setCentralWidget(m_mdi); m_bookshelfDock = new BtBookshelfDockWidget(this); addDockWidget(Qt::LeftDockWidgetArea, m_bookshelfDock); - m_bookmarksDock = new QDockWidget(tr("Bookmarks"), this); + m_bookmarksDock = new QDockWidget(this); m_bookmarksDock->setObjectName("BookmarksDock"); m_bookmarksPage = new CBookmarkIndex(0); m_bookmarksDock->setWidget(m_bookmarksPage); addDockWidget(Qt::LeftDockWidgetArea, m_bookmarksDock); tabifyDockWidget(m_bookmarksDock, m_bookshelfDock); - m_magDock = new QDockWidget(tr("Mag"), this); + m_magDock = new QDockWidget(this); m_magDock->setObjectName("MagDock"); m_infoDisplay = new CInfoDisplay(this); m_infoDisplay->resize(150, 150); m_magDock->setWidget(m_infoDisplay); addDockWidget(Qt::LeftDockWidgetArea, m_magDock); - CPointers::setInfoDisplay(m_infoDisplay); m_mdi->setMinimumSize(100, 100); m_mdi->setFocusPolicy(Qt::ClickFocus); } @@ -157,6 +169,13 @@ void BibleTime::insertKeyboardActions( BtActionCollection* const a ) { action->setToolTip(tr("Automatically tile the open windows")); a->addAction("autoTile", action); + action = new QAction(a); + action->setText(tr("Ta&bbed")); + action->setIcon(DU::getIcon(CResMgr::mainMenu::window::arrangementMode::autoTabbed::icon)); + action->setShortcut(QKeySequence(CResMgr::mainMenu::window::arrangementMode::autoTabbed::accel)); + action->setToolTip(tr("Automatically tab the open windows")); + a->addAction("autoTabbed", action); + action = new QAction(a); action->setText(tr("Auto-&cascade")); action->setIcon(DU::getIcon(CResMgr::mainMenu::window::arrangementMode::autoCascade::icon)); @@ -237,241 +256,431 @@ void BibleTime::insertKeyboardActions( BtActionCollection* const a ) { action->setText(tr("&About BibleTime")); action->setToolTip(tr("Information about the BibleTime program")); a->addAction("aboutBibleTime", action); -} -/** Initializes the action objects of the GUI */ -void BibleTime::initActions() { - m_actionCollection = new BtActionCollection(this); + action = new QAction(a); + action->setText(tr("&Tip of the day...")); + action->setIcon(DU::getIcon(CResMgr::mainMenu::help::tipOfTheDay::icon)); + action->setShortcut(QKeySequence(CResMgr::mainMenu::help::tipOfTheDay::accel)); + action->setToolTip(tr("Show tips about BibleTime")); + a->addAction("tipOfTheDay", action); - /** - * Create the window to signal mapper and connect it up. - */ - m_windowMapper = new QSignalMapper(this); - connect(m_windowMapper, SIGNAL(mapped(QWidget*)), - this, SLOT(slotSetActiveSubWindow(QWidget*))); + action = new QAction(a); + a->addAction("showToolbarsInTextWindows", action); - insertKeyboardActions(m_actionCollection); + action = new QAction(a); + a->addAction("showNavigation", action); - // Main menus - QMenu* fileMenu = menuBar()->addMenu(tr("&File")); - QMenu* viewMenu = menuBar()->addMenu(tr("&View")); - QMenu* searchMenu = menuBar()->addMenu(tr("&Search")); - m_windowMenu = menuBar()->addMenu(tr("&Window")); - QMenu* settingsMenu = menuBar()->addMenu(tr("Se&ttings")); - QMenu* helpMenu = menuBar()->addMenu(tr("&Help")); - - // Name of the main toolbar - m_mainToolBar = addToolBar(tr("Main Toolbar")); - m_mainToolBar->setObjectName("MainToolBar"); - m_mainToolBar->setFloatable(false); - m_mainToolBar->setMovable(false); - - QAction* tmp = m_actionCollection->action("quit"); - fileMenu->addAction(tmp); - connect(tmp, SIGNAL(triggered()), this, SLOT(quit()) ); - - - // ********** View menu ********************* - - m_windowFullscreen_action = m_actionCollection->action("toggleFullscreen"); - m_windowFullscreen_action->setCheckable(true); - viewMenu->addAction(m_windowFullscreen_action); - m_mainToolBar->addAction(m_windowFullscreen_action); - connect(m_windowFullscreen_action, SIGNAL(triggered()), this, SLOT(toggleFullscreen()) ); - - m_viewToolbar_action = m_actionCollection->action("showToolbar"); - m_viewToolbar_action->setCheckable(true); - m_viewToolbar_action->setChecked(true); - viewMenu->addAction(m_viewToolbar_action); - connect(m_viewToolbar_action, SIGNAL(triggered()), this, SLOT(slotToggleToolbar()) ); - - QAction* action = m_bookshelfDock->toggleViewAction(); - action->setText(tr("Show Bookshelf")); - viewMenu->addAction(action); - - action = m_bookmarksDock->toggleViewAction(); - action->setText(tr("Show Bookmarks")); - viewMenu->addAction(action); - - action = m_magDock->toggleViewAction(); - action->setText(tr("Show Mag")); - viewMenu->addAction(action); - - viewMenu->addSeparator(); - QMenu* textWindowsMenu = new QMenu(tr("Text windows")); - viewMenu->addMenu(textWindowsMenu); - - action = new QAction(tr("Show text area headers"), this); - action->setCheckable(true); - action->setChecked(CBTConfig::get(CBTConfig::showTextWindowHeaders)); - connect(action, SIGNAL(toggled(bool)), SLOT(slotToggleTextWindowHeader())); - textWindowsMenu->addAction(action); - - action = new QAction(tr("Show navigation"), this); - action->setCheckable(true); - action->setChecked(CBTConfig::get(CBTConfig::showTextWindowNavigator)); - connect(action, SIGNAL(toggled(bool)), SLOT(slotToggleTextWindowNavigator())); - textWindowsMenu->addAction(action); - - action = new QAction(tr("Show work chooser buttons"), this); - action->setCheckable(true); - action->setChecked(CBTConfig::get(CBTConfig::showTextWindowModuleSelectorButtons)); - connect(action, SIGNAL(toggled(bool)), SLOT(slotToggleTextWindowModuleChooser())); - textWindowsMenu->addAction(action); - - action = new QAction(tr("Show tools"), this); - action->setCheckable(true); - action->setChecked(CBTConfig::get(CBTConfig::showTextWindowToolButtons)); - connect(action, SIGNAL(toggled(bool)), SLOT(slotToggleTextWindowToolButtons())); - textWindowsMenu->addAction(action); - - // ************************************* - m_mainToolBar->addSeparator(); + action = new QAction(a); + a->addAction("showWorks", action); - tmp = m_actionCollection->action("searchOpenWorks"); - searchMenu->addAction(tmp); - m_mainToolBar->addAction(tmp); - m_mainToolBar->addSeparator(); - connect(tmp, SIGNAL(triggered()), this, SLOT(slotSearchModules()) ); + action = new QAction(a); + a->addAction("showTools", action); - tmp = m_actionCollection->action("searchStdBible"); - searchMenu->addAction(tmp); - connect(tmp, SIGNAL(triggered()), this, SLOT(slotSearchDefaultBible()) ); + action = new QAction(a); + a->addAction("showFormat", action); - /** - * Window Menu - */ - m_openWindowsMenu = new QMenu(tr("O&pen Windows"), m_windowMenu); - m_windowMenu->addMenu(m_openWindowsMenu); + action = new QAction(a); + a->addAction("showParallelTextHeaders", action); - m_windowClose_action = m_actionCollection->action("closeWindow"); - m_windowMenu->addAction(m_windowClose_action); - connect(m_windowClose_action, SIGNAL(triggered()), m_mdi, SLOT(closeActiveSubWindow())); + action = new QAction(a); + a->addAction("showBookshelf", action); - m_windowCloseAll_action = m_actionCollection->action("closeAllWindows"); - m_windowMenu->addAction(m_windowCloseAll_action); - connect(m_windowCloseAll_action, SIGNAL(triggered()), m_mdi, SLOT(closeAllSubWindows())); + action = new QAction(a); + a->addAction("showBookmarks", action); - m_windowMenu->addSeparator(); + action = new QAction(a); + a->addAction("showMag", action); - // *** Window arrangement actions *** + retranslateUiActions(a); +} - m_windowCascade_action = m_actionCollection->action("cascade"); - m_windowMenu->addAction(m_windowCascade_action); - connect(m_windowCascade_action, SIGNAL(triggered()), this, SLOT(slotCascade()) ); +static QToolBar* createToolBar(const QString& name, QWidget* parent, bool visible) { + QToolBar* bar = new QToolBar(parent); + bar->setObjectName(name); + bar->setFloatable(false); + bar->setMovable(true); + bar->setVisible(visible); + return bar; +} - m_windowTile_action = m_actionCollection->action("tile"); - m_windowMenu->addAction(m_windowTile_action); - connect(m_windowTile_action, SIGNAL(triggered()), this, SLOT(slotTile()) ); +void BibleTime::clearMdiToolBars() { + // Clear main window toolbars + m_navToolBar->clear(); + m_worksToolBar->clear(); + m_toolsToolBar->clear(); + m_formatToolBar->clear(); +} - m_windowTileVertical_action = m_actionCollection->action("tileVertically"); - m_windowMenu->addAction(m_windowTileVertical_action); - connect(m_windowTileVertical_action, SIGNAL(triggered()), this, SLOT(slotTileVertical()) ); +void BibleTime::createMenuAndToolBar() +{ + // Create menubar + menuBar(); - m_windowTileHorizontal_action = m_actionCollection->action("tileHorizontally"); - m_windowMenu->addAction(m_windowTileHorizontal_action); - connect(m_windowTileHorizontal_action, SIGNAL(triggered()), this, SLOT(slotTileHorizontal()) ); + m_mainToolBar = createToolBar("MainToolBar", this, true); + addToolBar(m_mainToolBar); - QMenu* arrangementMenu = new QMenu(tr("&Arrangement mode")); - m_windowMenu->addMenu(arrangementMenu); + // Set visibility of main window toolbars based on config + bool visible = ! CBTConfig::get(CBTConfig::showToolbarsInEachWindow); - m_windowManualMode_action = m_actionCollection->action("manualArrangement"); - m_windowManualMode_action->setCheckable(true); - arrangementMenu->addAction(m_windowManualMode_action); - connect(m_windowManualMode_action, SIGNAL(triggered()), this, SLOT(slotManualArrangementMode()) ); + m_navToolBar = createToolBar("NavToolBar", this, visible); + addToolBar(m_navToolBar); - //: Vertical tiling means that windows are vertical, placed side by side - m_windowAutoTileVertical_action = m_actionCollection->action("autoVertical"); - m_windowAutoTileVertical_action->setCheckable(true); - arrangementMenu->addAction(m_windowAutoTileVertical_action); - connect(m_windowAutoTileVertical_action, SIGNAL(triggered()), this, SLOT(slotAutoTileVertical()) ); + m_worksToolBar = new BtModuleChooserBar(this); + m_worksToolBar->setObjectName("WorksToolBar"); + m_worksToolBar->setVisible(visible); + addToolBar(m_worksToolBar); - //: Horizontal tiling means that windows are horizontal, placed on top of each other - m_windowAutoTileHorizontal_action = m_actionCollection->action("autoHorizontal"); - m_windowAutoTileHorizontal_action->setCheckable(true); - arrangementMenu->addAction(m_windowAutoTileHorizontal_action); - connect(m_windowAutoTileHorizontal_action, SIGNAL(triggered()), this, SLOT(slotAutoTileHorizontal()) ); + m_toolsToolBar = createToolBar("ToolsToolBar", this, visible); + addToolBar(m_toolsToolBar); - m_windowAutoTile_action = m_actionCollection->action("autoTile"); - m_windowAutoTile_action->setCheckable(true); - arrangementMenu->addAction(m_windowAutoTile_action); - connect(m_windowAutoTile_action, SIGNAL(triggered()), this, SLOT(slotAutoTile()) ); + m_formatToolBar = createToolBar("FormatToolBar", this, visible); + addToolBar(m_formatToolBar); +} - m_windowAutoCascade_action = m_actionCollection->action("autoCascade"); - m_windowAutoCascade_action->setCheckable(true); - arrangementMenu->addAction(m_windowAutoCascade_action); - connect(m_windowAutoCascade_action, SIGNAL(triggered()), this, SLOT(slotAutoCascade()) ); +/** Initializes the action objects of the GUI */ +void BibleTime::initActions() { + m_actionCollection = new BtActionCollection(this); + insertKeyboardActions(m_actionCollection); - m_windowMenu->addSeparator(); + // Create the window to signal mapper and connect it up: + m_windowMapper = new QSignalMapper(this); + connect(m_windowMapper, SIGNAL(mapped(QWidget*)), + this, SLOT(slotSetActiveSubWindow(QWidget*))); + + // File menu actions: + m_openWorkAction = new BtOpenWorkAction("GUI/MainWindow/OpenWorkAction/grouping", this); + connect(m_openWorkAction, SIGNAL(triggered(CSwordModuleInfo*)), + this, SLOT(createReadDisplayWindow(CSwordModuleInfo*))); + + m_quitAction = m_actionCollection->action("quit"); + connect(m_quitAction, SIGNAL(triggered()), + this, SLOT(quit())); + + + // View menu actions: + m_windowFullscreenAction = m_actionCollection->action("toggleFullscreen"); + m_windowFullscreenAction->setCheckable(true); + connect(m_windowFullscreenAction, SIGNAL(triggered()), + this, SLOT(toggleFullscreen())); + + m_viewToolbarAction = m_actionCollection->action("showToolbar"); + m_viewToolbarAction->setCheckable(true); + m_viewToolbarAction->setChecked(true); + connect(m_viewToolbarAction, SIGNAL(triggered()), + this, SLOT(slotToggleMainToolbar())); + + // Special case these actions, overwrite those already in collection + m_showBookshelfAction = m_bookshelfDock->toggleViewAction(); + m_actionCollection->addAction("showBookshelf", m_showBookshelfAction); + m_showBookmarksAction = m_bookmarksDock->toggleViewAction(); + m_actionCollection->addAction("showBookmarks", m_showBookmarksAction); + m_showMagAction = m_magDock->toggleViewAction(); + m_actionCollection->addAction("showMag", m_showMagAction); + + m_showTextAreaHeadersAction = m_actionCollection->action("showParallelTextHeaders"); + m_showTextAreaHeadersAction->setCheckable(true); + m_showTextAreaHeadersAction->setChecked(CBTConfig::get(CBTConfig::showTextWindowHeaders)); + connect(m_showTextAreaHeadersAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleTextWindowHeader())); + + m_showTextWindowNavigationAction = m_actionCollection->action("showNavigation"); + m_showTextWindowNavigationAction->setCheckable(true); + m_showTextWindowNavigationAction->setChecked(CBTConfig::get(CBTConfig::showTextWindowNavigator)); + connect(m_showTextWindowNavigationAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleNavigatorToolbar())); + + m_showTextWindowModuleChooserAction = m_actionCollection->action("showWorks"); + m_showTextWindowModuleChooserAction->setCheckable(true); + m_showTextWindowModuleChooserAction->setChecked(CBTConfig::get(CBTConfig::showTextWindowModuleSelectorButtons)); + connect(m_showTextWindowModuleChooserAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleWorksToolbar())); + + m_showTextWindowToolButtonsAction = m_actionCollection->action("showTools"); + m_showTextWindowToolButtonsAction->setCheckable(true); + m_showTextWindowToolButtonsAction->setChecked(CBTConfig::get(CBTConfig::showTextWindowToolButtons)); + connect(m_showTextWindowToolButtonsAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleToolsToolbar())); + + m_showFormatToolbarAction = m_actionCollection->action("showFormat"); + m_showFormatToolbarAction->setCheckable(true); + m_showFormatToolbarAction->setChecked(CBTConfig::get(CBTConfig::showFormatToolbarButtons)); + bool ok = connect(m_showFormatToolbarAction, SIGNAL(toggled(bool)), + this, SLOT(slotToggleFormatToolbar())); + + m_toolbarsInEachWindow = m_actionCollection->action("showToolbarsInTextWindows"); + m_toolbarsInEachWindow->setCheckable(true); + m_toolbarsInEachWindow->setChecked(CBTConfig::get(CBTConfig::showToolbarsInEachWindow)); + ok = connect(m_toolbarsInEachWindow, SIGNAL(toggled(bool)), + this, SLOT(slotToggleToolBarsInEachWindow())); + Q_ASSERT(ok); - m_windowSaveProfileMenu = new QMenu(tr("&Save session")); - m_windowMenu->addMenu(m_windowSaveProfileMenu); + // Search menu actions: + m_searchOpenWorksAction = m_actionCollection->action("searchOpenWorks"); + connect(m_searchOpenWorksAction, SIGNAL(triggered()), + this, SLOT(slotSearchModules())); - m_windowSaveToNewProfile_action = m_actionCollection->action("saveNewSession"); - m_windowMenu->addAction(m_windowSaveToNewProfile_action); - connect(m_windowSaveToNewProfile_action, SIGNAL(triggered()), this, SLOT(saveToNewProfile()) ); + m_searchStandardBibleAction = m_actionCollection->action("searchStdBible"); + connect(m_searchStandardBibleAction, SIGNAL(triggered()), + this, SLOT(slotSearchDefaultBible())); - m_windowLoadProfileMenu = new QMenu(tr("&Load session")); - m_windowMenu->addMenu(m_windowLoadProfileMenu); + // Window menu actions: + m_windowCloseAction = m_actionCollection->action("closeWindow"); + connect(m_windowCloseAction, SIGNAL(triggered()), + m_mdi, SLOT(closeActiveSubWindow())); - m_windowDeleteProfileMenu = new QMenu(tr("&Delete session")); - m_windowMenu->addMenu(m_windowDeleteProfileMenu); + m_windowCloseAllAction = m_actionCollection->action("closeAllWindows"); + connect(m_windowCloseAllAction, SIGNAL(triggered()), + m_mdi, SLOT(closeAllSubWindows())); - QObject::connect(m_windowLoadProfileMenu, SIGNAL(triggered(QAction*)), SLOT(loadProfile(QAction*))); - QObject::connect(m_windowSaveProfileMenu, SIGNAL(triggered(QAction*)), SLOT(saveProfile(QAction*))); - QObject::connect(m_windowDeleteProfileMenu, SIGNAL(triggered(QAction*)), SLOT(deleteProfile(QAction*))); + m_windowCascadeAction = m_actionCollection->action("cascade"); + connect(m_windowCascadeAction, SIGNAL(triggered()), + this, SLOT(slotCascade())); - refreshProfileMenus(); + m_windowTileAction = m_actionCollection->action("tile"); + connect(m_windowTileAction, SIGNAL(triggered()), + this, SLOT(slotTile())); + + m_windowTileVerticalAction = m_actionCollection->action("tileVertically"); + connect(m_windowTileVerticalAction, SIGNAL(triggered()), + this, SLOT(slotTileVertical())); + + m_windowTileHorizontalAction = m_actionCollection->action("tileHorizontally"); + connect(m_windowTileHorizontalAction, SIGNAL(triggered()), + this, SLOT(slotTileHorizontal())); - tmp = m_actionCollection->action("setPreferences"); - settingsMenu->addAction(tmp); - connect(tmp, SIGNAL(triggered()), this, SLOT(slotSettingsOptions()) ); + m_windowManualModeAction = m_actionCollection->action("manualArrangement"); + m_windowManualModeAction->setCheckable(true); + connect(m_windowManualModeAction, SIGNAL(triggered()), + this, SLOT(slotManualArrangementMode())); - settingsMenu->addSeparator(); + m_windowAutoTabbedAction = m_actionCollection->action("autoTabbed"); + m_windowAutoTabbedAction->setCheckable(true); + connect(m_windowAutoTabbedAction, SIGNAL(triggered()), + this, SLOT(slotAutoTabbed())); - tmp = m_actionCollection->action("bookshelfManager"); - settingsMenu->addAction(tmp); - connect(tmp, SIGNAL(triggered()), this, SLOT(slotSwordSetupDialog()) ); + //: Vertical tiling means that windows are vertical, placed side by side + m_windowAutoTileVerticalAction = m_actionCollection->action("autoVertical"); + m_windowAutoTileVerticalAction->setCheckable(true); + connect(m_windowAutoTileVerticalAction, SIGNAL(triggered()), + this, SLOT(slotAutoTileVertical())); + + //: Horizontal tiling means that windows are horizontal, placed on top of each other + m_windowAutoTileHorizontalAction = m_actionCollection->action("autoHorizontal"); + m_windowAutoTileHorizontalAction->setCheckable(true); + connect(m_windowAutoTileHorizontalAction, SIGNAL(triggered()), + this, SLOT(slotAutoTileHorizontal())); + + m_windowAutoTileAction = m_actionCollection->action("autoTile"); + m_windowAutoTileAction->setCheckable(true); + connect(m_windowAutoTileAction, SIGNAL(triggered()), + this, SLOT(slotAutoTile())); + + m_windowAutoCascadeAction = m_actionCollection->action("autoCascade"); + m_windowAutoCascadeAction->setCheckable(true); + connect(m_windowAutoCascadeAction, SIGNAL(triggered()), + this, SLOT(slotAutoCascade())); + + m_windowSaveToNewProfileAction = m_actionCollection->action("saveNewSession"); + connect(m_windowSaveToNewProfileAction, SIGNAL(triggered()), + this, SLOT(saveToNewProfile())); + + m_setPreferencesAction = m_actionCollection->action("setPreferences"); + connect(m_setPreferencesAction, SIGNAL(triggered()), + this, SLOT(slotSettingsOptions())); + + m_bookshelfManagerAction = m_actionCollection->action("bookshelfManager"); + connect(m_bookshelfManagerAction, SIGNAL(triggered()), + this, SLOT(slotSwordSetupDialog())); + + m_openHandbookAction = m_actionCollection->action("openHandbook"); + connect(m_openHandbookAction, SIGNAL(triggered()), + this, SLOT(openOnlineHelp_Handbook())); + + m_bibleStudyHowtoAction = m_actionCollection->action("bibleStudyHowto"); + connect(m_bibleStudyHowtoAction, SIGNAL(triggered()), + this, SLOT(openOnlineHelp_Howto())); + + m_aboutBibleTimeAction = m_actionCollection->action("aboutBibleTime"); + connect(m_aboutBibleTimeAction, SIGNAL(triggered()), + this, SLOT(slotOpenAboutDialog()) ); + + m_tipOfTheDayAction = m_actionCollection->action("tipOfTheDay"); + connect(m_tipOfTheDayAction, SIGNAL(triggered()), + this, SLOT(slotOpenTipDialog()) ); + + #ifdef BT_DEBUG + m_debugWidgetAction = new QAction(this); + m_debugWidgetAction->setCheckable(true); + connect(m_debugWidgetAction, SIGNAL(triggered(bool)), + this, SLOT(slotShowDebugWindow(bool))); + #endif + + retranslateUiActions(m_actionCollection); +} + +void BibleTime::initMenubar() { + // File menu: + m_fileMenu = new QMenu(this); + m_fileMenu->addAction(m_openWorkAction); + m_fileMenu->addSeparator(); + m_fileMenu->addAction(m_quitAction); + menuBar()->addMenu(m_fileMenu); + + // View menu: + m_viewMenu = new QMenu(this); + m_viewMenu->addAction(m_windowFullscreenAction); + m_viewMenu->addAction(m_showBookshelfAction); + m_viewMenu->addAction(m_showBookmarksAction); + m_viewMenu->addAction(m_showMagAction); + m_viewMenu->addAction(m_showTextAreaHeadersAction); + m_viewMenu->addSeparator(); + m_toolBarsMenu = new QMenu(this); + m_toolBarsMenu->addAction(m_viewToolbarAction); + m_toolBarsMenu->addAction(m_showTextWindowNavigationAction); + m_toolBarsMenu->addAction(m_showTextWindowModuleChooserAction); + m_toolBarsMenu->addAction(m_showTextWindowToolButtonsAction); + m_toolBarsMenu->addAction(m_showFormatToolbarAction); + m_toolBarsMenu->addSeparator(); + m_toolBarsMenu->addAction(m_toolbarsInEachWindow); + m_viewMenu->addMenu(m_toolBarsMenu); + menuBar()->addMenu(m_viewMenu); + + // Search menu: + m_searchMenu = new QMenu(this); + m_searchMenu->addAction(m_searchOpenWorksAction); + m_searchMenu->addAction(m_searchStandardBibleAction); + menuBar()->addMenu(m_searchMenu); + + // Window menu: + m_windowMenu = new QMenu(this); + m_openWindowsMenu = new QMenu(this); + QObject::connect(m_openWindowsMenu, SIGNAL(aboutToShow()), + this, SLOT(slotOpenWindowsMenuAboutToShow())); + m_windowMenu->addMenu(m_openWindowsMenu); + m_windowMenu->addAction(m_windowCloseAction); + m_windowMenu->addAction(m_windowCloseAllAction); + m_windowMenu->addSeparator(); + m_windowMenu->addAction(m_windowCascadeAction); + m_windowMenu->addAction(m_windowTileAction); + m_windowMenu->addAction(m_windowTileVerticalAction); + m_windowMenu->addAction(m_windowTileHorizontalAction); + m_windowArrangementMenu = new QMenu(this); + m_windowArrangementMenu->addAction(m_windowManualModeAction); + m_windowArrangementMenu->addAction(m_windowAutoTabbedAction); + m_windowArrangementMenu->addAction(m_windowAutoTileVerticalAction); + m_windowArrangementMenu->addAction(m_windowAutoTileHorizontalAction); + m_windowArrangementMenu->addAction(m_windowAutoTileAction); + m_windowArrangementMenu->addAction(m_windowAutoCascadeAction); + m_windowMenu->addMenu(m_windowArrangementMenu); + m_windowMenu->addSeparator(); + m_windowSaveProfileMenu = new QMenu(this); + m_windowMenu->addMenu(m_windowSaveProfileMenu); + m_windowMenu->addAction(m_windowSaveToNewProfileAction); + m_windowLoadProfileMenu = new QMenu(this); + m_windowMenu->addMenu(m_windowLoadProfileMenu); + m_windowDeleteProfileMenu = new QMenu(this); + m_windowMenu->addMenu(m_windowDeleteProfileMenu); + connect(m_windowLoadProfileMenu, SIGNAL(triggered(QAction*)), + this, SLOT(loadProfile(QAction*))); + connect(m_windowSaveProfileMenu, SIGNAL(triggered(QAction*)), + this, SLOT(saveProfile(QAction*))); + connect(m_windowDeleteProfileMenu, SIGNAL(triggered(QAction*)), + this, SLOT(deleteProfile(QAction*))); + refreshProfileMenus(); + menuBar()->addMenu(m_windowMenu); + connect(m_windowMenu, SIGNAL(aboutToShow()), + this, SLOT(slotWindowMenuAboutToShow())); + + // Settings menu: + m_settingsMenu = new QMenu(this); + m_settingsMenu->addAction(m_setPreferencesAction); + m_settingsMenu->addSeparator(); + m_settingsMenu->addAction(m_bookshelfManagerAction); + menuBar()->addMenu(m_settingsMenu); + + // Help menu: + m_helpMenu = new QMenu(this); + m_helpMenu->addAction(m_openHandbookAction); + m_helpMenu->addAction(m_bibleStudyHowtoAction); + m_helpMenu->addAction(m_tipOfTheDayAction); + m_helpMenu->addSeparator(); + m_helpMenu->addAction(m_aboutBibleTimeAction); + #ifdef BT_DEBUG + m_helpMenu->addSeparator(); + m_helpMenu->addAction(m_debugWidgetAction); + #endif + menuBar()->addMenu(m_helpMenu); +} - tmp = m_actionCollection->action("openHandbook"); - helpMenu->addAction(tmp); - m_mainToolBar->addAction(tmp); - connect(tmp, SIGNAL(triggered()), this, SLOT(openOnlineHelp_Handbook()) ); +void BibleTime::initToolbars() { + QToolButton *openWorkButton = new QToolButton(this); + openWorkButton->setDefaultAction(m_openWorkAction); + openWorkButton->setPopupMode(QToolButton::InstantPopup); + m_mainToolBar->addWidget(openWorkButton); - tmp = m_actionCollection->action("bibleStudyHowto"); - helpMenu->addAction(tmp); - connect(tmp, SIGNAL(triggered()), this, SLOT(openOnlineHelp_Howto()) ); + m_mainToolBar->addSeparator(); + m_mainToolBar->addAction(m_windowFullscreenAction); + m_mainToolBar->addSeparator(); + m_mainToolBar->addAction(m_searchOpenWorksAction); + m_mainToolBar->addSeparator(); + m_mainToolBar->addAction(m_openHandbookAction); +} - helpMenu->addSeparator(); +void BibleTime::retranslateUi() { + m_bookmarksDock->setWindowTitle(tr("Bookmarks")); + m_magDock->setWindowTitle(tr("Mag")); + m_mainToolBar->setWindowTitle(tr("Main toolbar")); + m_navToolBar->setWindowTitle(tr("Navigation toolbar")); + m_worksToolBar->setWindowTitle(tr("Works toolbar")); + m_toolsToolBar->setWindowTitle(tr("Tools toolbar")); + m_formatToolBar->setWindowTitle(tr("Format toolbar")); + + m_fileMenu->setTitle(tr("&File")); + m_viewMenu->setTitle(tr("&View")); + m_toolBarsMenu->setTitle(tr("Toolbars")); + + m_searchMenu->setTitle(tr("&Search")); + m_windowMenu->setTitle(tr("&Window")); + m_openWindowsMenu->setTitle(tr("O&pen windows")); + m_windowArrangementMenu->setTitle(tr("&Arrangement mode")); + m_windowSaveProfileMenu->setTitle(tr("&Save session")); + m_windowLoadProfileMenu->setTitle(tr("&Load session")); + m_windowDeleteProfileMenu->setTitle(tr("&Delete session")); + m_settingsMenu->setTitle(tr("Se&ttings")); + m_helpMenu->setTitle(tr("&Help")); + + #ifdef BT_DEBUG + m_debugWidgetAction->setText(tr("Show \"Whats this widget\" dialog")); + #endif + + retranslateUiActions(m_actionCollection); +} - tmp = m_actionCollection->action("aboutBibleTime"); - helpMenu->addAction(tmp); - connect(tmp, SIGNAL(triggered()), this, SLOT(slotOpenAboutDialog()) ); +/** retranslation for actions used in this class +* This is called for two different collections of actions +* One set is for the actual use in the menus, etc +* The second is used during the use of the configuration shortcut editor +*/ +void BibleTime::retranslateUiActions(BtActionCollection* ac) { + ac->action("showToolbarsInTextWindows")->setText(tr("Show toolbars in text windows")); + ac->action("showToolbar")->setText(tr("Show main toolbar")); + ac->action("showNavigation")->setText(tr("Show navigation bar")); + ac->action("showWorks")->setText(tr("Show works toolbar")); + ac->action("showTools")->setText(tr("Show tools toolbar")); + ac->action("showFormat")->setText(tr("Show formatting toolbar")); + ac->action("showBookshelf")->setText(tr("Show bookshelf")); + ac->action("showBookmarks")->setText(tr("Show bookmarks")); + ac->action("showMag")->setText(tr("Show mag")); + ac->action("showParallelTextHeaders")->setText(tr("Show parallel text headers")); } /** Initializes the SIGNAL / SLOT connections */ void BibleTime::initConnections() { - if (m_windowMenu) { - QObject::connect(m_windowMenu, SIGNAL(aboutToShow()), this, SLOT(slotWindowMenuAboutToShow())); - } - else { - qWarning() << "Main window: can't find window menu"; - } + // Bookmarks page connections: + connect(m_bookmarksPage, SIGNAL(createReadDisplayWindow(QList, const QString&)), + this, SLOT(createReadDisplayWindow(QList, const QString&))); - if (m_openWindowsMenu) { - QObject::connect(m_openWindowsMenu, SIGNAL(aboutToShow()), - this, SLOT(slotOpenWindowsMenuAboutToShow())); - } - else { - qWarning() << "Main window: can't find open windows menu"; - } - - bool ok; - ok = connect(m_bookmarksPage, - SIGNAL(createReadDisplayWindow(QList, const QString&)), - this, - SLOT(createReadDisplayWindow(QList, const QString&))); - Q_ASSERT(ok); + // Bookshelf dock connections: connect(m_bookshelfDock, SIGNAL(moduleOpenTriggered(CSwordModuleInfo*)), this, SLOT(createReadDisplayWindow(CSwordModuleInfo*))); connect(m_bookshelfDock, SIGNAL(moduleSearchTriggered(CSwordModuleInfo*)), @@ -481,11 +690,9 @@ void BibleTime::initConnections() { connect(m_bookshelfDock, SIGNAL(moduleEditHtmlTriggered(CSwordModuleInfo*)), this, SLOT(moduleEditHtml(CSwordModuleInfo*))); connect(m_bookshelfDock, SIGNAL(moduleUnlockTriggered(CSwordModuleInfo*)), - this, SLOT(moduleUnlock(CSwordModuleInfo*))); + this, SLOT(slotModuleUnlock(CSwordModuleInfo*))); connect(m_bookshelfDock, SIGNAL(moduleAboutTriggered(CSwordModuleInfo*)), this, SLOT(moduleAbout(CSwordModuleInfo*))); - - connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(slot_aboutToQuit())); } void BibleTime::initSwordConfigFile() { @@ -511,6 +718,24 @@ void BibleTime::initSwordConfigFile() { out << "\n"; file.close(); #endif + +#ifdef Q_WS_MAC + namespace DU = util::directory; + QString configFile = util::directory::getUserHomeSwordDir().filePath("sword.conf"); + QFile file(configFile); + if (file.exists()) { + return; + } + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + return; + } + QTextStream out(&file); + out << "\n"; + out << "[Install]\n"; + out << "DataPath=" << DU::convertDirSeparators( DU::getUserHomeSwordDir().absolutePath()) << "\n"; + out << "\n"; + file.close(); +#endif } /** Initializes the backend */ @@ -520,55 +745,64 @@ void BibleTime::initBackends() { initSwordConfigFile(); sword::StringMgr::setSystemStringMgr( new BTStringMgr() ); - sword::SWLog::getSystemLog()->setLogLevel(1); + sword::SWLog::getSystemLog()->setLogLevel(sword::SWLog::LOG_ERROR); + + if (qApp->property("--debug").toBool()) { + sword::SWLog::getSystemLog()->setLogLevel(sword::SWLog::LOG_DEBUG); + } - CSwordBackend* backend = new CSwordBackend(); +#ifdef Q_WS_MAC + // set a LocaleMgr with a fixed path to the locales.d of the DMG image on MacOS + // note: this must be done after setting the BTStringMgr, because this will reset the LocaleMgr + qDebug() << "Using sword locales dir: " << util::directory::getSwordLocalesDir().absolutePath().toUtf8(); + sword::LocaleMgr::setSystemLocaleMgr(new sword::LocaleMgr(util::directory::getSwordLocalesDir().absolutePath().toUtf8())); +#endif + + CSwordBackend *backend = CSwordBackend::createInstance(); backend->booknameLanguage(CBTConfig::get(CBTConfig::language) ); - CPointers::setBackend(backend); - const CSwordBackend::LoadError errorCode = CPointers::backend()->initModules(CSwordBackend::OtherChange); + const CSwordBackend::LoadError errorCode = CSwordBackend::instance()->initModules(CSwordBackend::OtherChange); if (errorCode != CSwordBackend::NoError) { //show error message that initBackend failed /// \todo -// switch (errorCode) { -// case CSwordBackend::NoSwordConfig: //mods.d or mods.conf missing -// { -// KStartupLogo::hideSplash(); -// qDebug() << "case CSwordBackend::NoSwordConfig"; -// BookshelfManager::CSwordSetupDialog dlg; -// dlg.showPart( BookshelfManager::CSwordSetupDialog::Sword ); -// dlg.exec(); -// break; -// } +// switch (errorCode) { +// case CSwordBackend::NoSwordConfig: //mods.d or mods.conf missing +// { +// KStartupLogo::hideSplash(); +// qDebug() << "case CSwordBackend::NoSwordConfig"; +// BookshelfManager::CSwordSetupDialog dlg; +// dlg.showPart( BookshelfManager::CSwordSetupDialog::Sword ); +// dlg.exec(); +// break; +// } // -// case CSwordBackend::NoModules: //no modules installed, but config exists -// { -// KStartupLogo::hideSplash(); -// qDebug() << "case CSwordBackend::NoModules"; -// BookshelfManager::CSwordSetupDialog dlg; -// dlg.showPart( BookshelfManager::CSwordSetupDialog::Install ); -// dlg.exec(); -// break; -// } +// case CSwordBackend::NoModules: //no modules installed, but config exists +// { +// KStartupLogo::hideSplash(); +// qDebug() << "case CSwordBackend::NoModules"; +// BookshelfManager::CSwordSetupDialog dlg; +// dlg.showPart( BookshelfManager::CSwordSetupDialog::Install ); +// dlg.exec(); +// break; +// } // -// default: //unknown error -// { -// KStartupLogo::hideSplash(); -// qDebug() << "unknown error"; -// BookshelfManager::CSwordSetupDialog dlg; -// dlg.showPart( BookshelfManager::CSwordSetupDialog::Sword ); -// dlg.exec(); -// break; -// } -// } +// default: //unknown error +// { +// KStartupLogo::hideSplash(); +// qDebug() << "unknown error"; +// BookshelfManager::CSwordSetupDialog dlg; +// dlg.showPart( BookshelfManager::CSwordSetupDialog::Sword ); +// dlg.exec(); +// break; +// } +// } } - //This function will + // This function will // - delete all orphaned indexes (no module present) if autoDeleteOrphanedIndices is true // - delete all indices of modules where hasIndex() returns false - //BookshelfManager::CManageIndicesWidget::deleteOrphanedIndices(); - /// \todo //backend::deleteOrphanedIndices(); + backend->deleteOrphanedIndices(); } @@ -577,10 +811,10 @@ void BibleTime::applyProfileSettings( CProfile* p ) { Q_ASSERT(p); if (!p) return; - //first Main Window state - restoreState(p->getMainwindowState()); + //first Main Window geometry restoreGeometry(p->getMainwindowGeometry()); - m_windowFullscreen_action->setChecked(isFullScreen()); + restoreState(p->getMainwindowState()); + m_windowFullscreenAction->setChecked(isFullScreen()); const CMDIArea::MDIArrangementMode newArrangementMode = p->getMDIArrangementMode(); //make sure actions are updated by calling the slot functions @@ -598,6 +832,9 @@ void BibleTime::applyProfileSettings( CProfile* p ) { case CMDIArea::ArrangementModeTile: slotAutoTile(); break; + case CMDIArea::ArrangementModeTabbed: + slotAutoTabbed(); + break; case CMDIArea::ArrangementModeManual: slotManualArrangementMode(); break; @@ -605,14 +842,87 @@ void BibleTime::applyProfileSettings( CProfile* p ) { slotAutoTileVertical(); break; } + layout()->invalidate(); } void BibleTime::storeProfileSettings( CProfile* p ) { - Q_ASSERT(p && m_windowFullscreen_action); - if (!p || !m_windowFullscreen_action) return; + Q_ASSERT(p && m_windowFullscreenAction); + if (!p || !m_windowFullscreenAction) return; p->setMainwindowState(saveState()); p->setMainwindowGeometry(saveGeometry()); p->setMDIArrangementMode(m_mdi->getMDIArrangementMode()); } +#if BT_DEBUG + +QLabel *BibleTime::m_debugWindow = 0; +QMutex BibleTime::m_debugWindowLock; + +void BibleTime::slotShowDebugWindow(bool show) { + if (show) { + QMutexLocker lock(&m_debugWindowLock); + if (m_debugWindow == 0) { + m_debugWindow = new QLabel(0, Qt::Dialog); + m_debugWindow->setAttribute(Qt::WA_DeleteOnClose); + m_debugWindow->setTextFormat(Qt::RichText); + m_debugWindow->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_debugWindow->setWindowTitle(tr("Whats this widget?")); + } + m_debugWindow->show(); + connect(m_debugWindow, SIGNAL(destroyed()), + this, SLOT(slotDebugWindowClosing()), Qt::DirectConnection); + QTimer::singleShot(0, this, SLOT(slotDebugTimeout())); + } else { + deleteDebugWindow(); + } +} + +void BibleTime::deleteDebugWindow() { + QMutexLocker lock(&m_debugWindowLock); + if (m_debugWindow != 0) { + m_debugWindow->disconnect(SIGNAL(destroyed()), this, SLOT(slotDebugWindowClosing())); + delete m_debugWindow; + m_debugWindow = 0; + } +} + +void BibleTime::slotDebugWindowClosing() { + QMutexLocker lock(&m_debugWindowLock); + m_debugWindow = 0; + m_debugWidgetAction->setChecked(false); +} + +void BibleTime::slotDebugTimeout() { + QMutexLocker lock(&m_debugWindowLock); + if (m_debugWindow == 0 || m_debugWindow->isVisible() == false) return; + + QTimer::singleShot(0, this, SLOT(slotDebugTimeout())); + QObject *w = QApplication::widgetAt(QCursor::pos()); + if (w != 0) { + QString objectHierarchy; + do { + const QMetaObject *m = w->metaObject(); + QString classHierarchy; + do { + if (!classHierarchy.isEmpty()) classHierarchy += ": "; + classHierarchy += m->className(); + + m = m->superClass(); + } while (m != 0); + if (!objectHierarchy.isEmpty()) { + objectHierarchy += "
child of: "; + } else { + objectHierarchy += "This widget is: "; + } + objectHierarchy += classHierarchy; + w = w->parent(); + } while (w != 0); + m_debugWindow->setText(objectHierarchy); + } else { + m_debugWindow->setText("No widget"); + } + m_debugWindow->resize(m_debugWindow->minimumSizeHint()); +} + +#endif diff --git a/src/bibletime_slots.cpp b/src/bibletime_slots.cpp index b1ee3b3..9fdab62 100644 --- a/src/bibletime_slots.cpp +++ b/src/bibletime_slots.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,20 +20,21 @@ #include #include #include +#include #include "backend/config/cbtconfig.h" #include "backend/keys/cswordversekey.h" +#include "frontend/btaboutdialog.h" #include "frontend/cinfodisplay.h" -#include "frontend/cinputdialog.h" #include "frontend/cmdiarea.h" #include "frontend/bookshelfmanager/btmodulemanagerdialog.h" -#include "frontend/displaywindow/cbiblereadwindow.h" +#include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/displaywindow/cdisplaywindow.h" -#include "frontend/htmldialogs/btaboutdialog.h" #include "frontend/profile/cprofilemgr.h" #include "frontend/profile/cprofile.h" #include "frontend/profile/cprofilewindow.h" #include "frontend/searchdialog/csearchdialog.h" #include "frontend/settingsdialogs/cconfigurationdialog.h" +#include "frontend/tips/bttipdialog.h" #include "util/directory.h" @@ -60,17 +61,17 @@ void BibleTime::saveConfigSettings() { void BibleTime::slotSettingsChanged() { qDebug() << "BibleTime::slotSettingsChanged"; const QString language = CBTConfig::get(CBTConfig::language); - CPointers::backend()->booknameLanguage(language); + CSwordBackend::instance()->booknameLanguage(language); // \todo update the bookmarks after Bible bookname language has been changed -// QTreeWidgetItemIterator it(m_mainIndex); -// while (*it) { -// CIndexItemBase* citem = dynamic_cast(*it); -// if (citem) { -// citem->update(); -// } -// ++it; -// } +// QTreeWidgetItemIterator it(m_mainIndex); +// while (*it) { +// CIndexItemBase* citem = dynamic_cast(*it); +// if (citem) { +// citem->update(); +// } +// ++it; +// } refreshBibleTimeAccel(); refreshDisplayWindows(); @@ -93,26 +94,26 @@ void BibleTime::slotWindowMenuAboutToShow() { Q_ASSERT(m_windowMenu); if ( m_mdi->subWindowList().isEmpty() ) { - m_windowCascade_action->setEnabled(false); - m_windowTileVertical_action->setEnabled(false); - m_windowTileHorizontal_action->setEnabled(false); - m_windowClose_action->setEnabled(false); - m_windowCloseAll_action->setEnabled(false); + m_windowCascadeAction->setEnabled(false); + m_windowTileVerticalAction->setEnabled(false); + m_windowTileHorizontalAction->setEnabled(false); + m_windowCloseAction->setEnabled(false); + m_windowCloseAllAction->setEnabled(false); m_openWindowsMenu->setEnabled(false); } else if (m_mdi->subWindowList().count() == 1) { - m_windowTileVertical_action->setEnabled(false); - m_windowTileHorizontal_action->setEnabled(false); - m_windowCascade_action->setEnabled(false); - m_windowClose_action->setEnabled(true); - m_windowCloseAll_action->setEnabled(true); + m_windowTileVerticalAction->setEnabled(false); + m_windowTileHorizontalAction->setEnabled(false); + m_windowCascadeAction->setEnabled(false); + m_windowCloseAction->setEnabled(true); + m_windowCloseAllAction->setEnabled(true); m_openWindowsMenu->setEnabled(true); // m_windowMenu->insertSeparator(); } else { slotUpdateWindowArrangementActions(0); //update the window tile/cascade states - m_windowClose_action->setEnabled(true); - m_windowCloseAll_action->setEnabled(true); + m_windowCloseAction->setEnabled(true); + m_windowCloseAllAction->setEnabled(true); m_openWindowsMenu->setEnabled(true); } } @@ -132,132 +133,152 @@ void BibleTime::slotOpenWindowsMenuAboutToShow() { } } -/** This slot is connected with the windowAutoTile_action object */ +/** This slot is connected with the windowAutoTileAction object */ void BibleTime::slotUpdateWindowArrangementActions( QAction* clickedAction ) { - /* If a toggle action was clicked we see if it checked ot unchecked and + /* If a toggle action was clicked we see if it is checked or unchecked and * enable/disable the simple cascade and tile options accordingly */ - m_windowTileVertical_action->setEnabled( m_windowManualMode_action->isChecked() ); - m_windowTileHorizontal_action->setEnabled( m_windowManualMode_action->isChecked() ); - m_windowCascade_action->setEnabled( m_windowManualMode_action->isChecked() ); - m_windowTile_action->setEnabled( m_windowManualMode_action->isChecked() ); + m_windowTileVerticalAction->setEnabled( m_windowManualModeAction->isChecked() ); + m_windowTileHorizontalAction->setEnabled( m_windowManualModeAction->isChecked() ); + m_windowCascadeAction->setEnabled( m_windowManualModeAction->isChecked() ); + m_windowTileAction->setEnabled( m_windowManualModeAction->isChecked() ); if (clickedAction) { - m_windowManualMode_action->setEnabled( - m_windowManualMode_action != clickedAction - && m_windowTileHorizontal_action != clickedAction - && m_windowTileVertical_action != clickedAction - && m_windowCascade_action != clickedAction - && m_windowTile_action != clickedAction + m_windowManualModeAction->setEnabled( + m_windowManualModeAction != clickedAction + && m_windowTileHorizontalAction != clickedAction + && m_windowTileVerticalAction != clickedAction + && m_windowCascadeAction != clickedAction + && m_windowTileAction != clickedAction ); - m_windowAutoTileVertical_action->setEnabled( m_windowAutoTileVertical_action != clickedAction ); - m_windowAutoTileHorizontal_action->setEnabled( m_windowAutoTileHorizontal_action != clickedAction ); - m_windowAutoCascade_action->setEnabled( m_windowAutoCascade_action != clickedAction ); - m_windowAutoTile_action->setEnabled( m_windowAutoTile_action != clickedAction ); + m_windowAutoTileVerticalAction->setEnabled( m_windowAutoTileVerticalAction != clickedAction ); + m_windowAutoTileHorizontalAction->setEnabled( m_windowAutoTileHorizontalAction != clickedAction ); + m_windowAutoCascadeAction->setEnabled( m_windowAutoCascadeAction != clickedAction ); + m_windowAutoTileAction->setEnabled( m_windowAutoTileAction != clickedAction ); + m_windowAutoTabbedAction->setEnabled( m_windowAutoTabbedAction != clickedAction ); } - if (clickedAction == m_windowManualMode_action) { - m_windowAutoTileVertical_action->setChecked(false); - m_windowAutoTileHorizontal_action->setChecked(false); - m_windowAutoCascade_action->setChecked(false); - m_windowAutoTile_action->setChecked(false); + if (clickedAction == m_windowManualModeAction) { + m_windowAutoTileVerticalAction->setChecked(false); + m_windowAutoTileHorizontalAction->setChecked(false); + m_windowAutoCascadeAction->setChecked(false); + m_windowAutoTileAction->setChecked(false); + m_windowAutoTabbedAction->setChecked(false); m_mdi->enableWindowMinMaxFlags(true); m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeManual ); } - else if (clickedAction == m_windowAutoTileVertical_action) { - m_windowManualMode_action->setChecked(false); - m_windowAutoTileHorizontal_action->setChecked(false); - m_windowAutoCascade_action->setChecked(false); - m_windowAutoTile_action->setChecked(false); + else if (clickedAction == m_windowAutoTileVerticalAction) { + m_windowManualModeAction->setChecked(false); + m_windowAutoTileHorizontalAction->setChecked(false); + m_windowAutoCascadeAction->setChecked(false); + m_windowAutoTileAction->setChecked(false); + m_windowAutoTabbedAction->setChecked(false); m_mdi->enableWindowMinMaxFlags(false); m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeTileVertical ); } - else if (clickedAction == m_windowAutoTileHorizontal_action) { - m_windowManualMode_action->setChecked(false); - m_windowAutoTileVertical_action->setChecked(false); - m_windowAutoCascade_action->setChecked(false); - m_windowAutoTile_action->setChecked(false); + else if (clickedAction == m_windowAutoTileHorizontalAction) { + m_windowManualModeAction->setChecked(false); + m_windowAutoTileVerticalAction->setChecked(false); + m_windowAutoCascadeAction->setChecked(false); + m_windowAutoTileAction->setChecked(false); + m_windowAutoTabbedAction->setChecked(false); m_mdi->enableWindowMinMaxFlags(false); m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeTileHorizontal ); } - else if (clickedAction == m_windowAutoTile_action) { - m_windowManualMode_action->setChecked(false); - m_windowAutoTileHorizontal_action->setChecked(false); - m_windowAutoTileVertical_action->setChecked(false); - m_windowAutoCascade_action->setChecked(false); + else if (clickedAction == m_windowAutoTileAction) { + m_windowManualModeAction->setChecked(false); + m_windowAutoTileHorizontalAction->setChecked(false); + m_windowAutoTileVerticalAction->setChecked(false); + m_windowAutoTabbedAction->setChecked(false); + m_windowAutoCascadeAction->setChecked(false); m_mdi->enableWindowMinMaxFlags(false); m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeTile ); } - else if (clickedAction == m_windowAutoCascade_action) { - m_windowManualMode_action->setChecked(false); - m_windowAutoTileHorizontal_action->setChecked(false); - m_windowAutoTileVertical_action->setChecked(false); - m_windowAutoTile_action->setChecked(false); + else if (clickedAction == m_windowAutoTabbedAction) { + m_windowManualModeAction->setChecked(false); + m_windowAutoTileHorizontalAction->setChecked(false); + m_windowAutoTileVerticalAction->setChecked(false); + m_windowAutoTileAction->setChecked(false); + m_windowAutoCascadeAction->setChecked(false); + m_mdi->enableWindowMinMaxFlags(false); + m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeTabbed ); + } + else if (clickedAction == m_windowAutoCascadeAction) { + m_windowManualModeAction->setChecked(false); + m_windowAutoTileHorizontalAction->setChecked(false); + m_windowAutoTileVerticalAction->setChecked(false); + m_windowAutoTileAction->setChecked(false); + m_windowAutoTabbedAction->setChecked(false); m_mdi->enableWindowMinMaxFlags(false); m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeCascade ); } - else if (clickedAction == m_windowTile_action) { + else if (clickedAction == m_windowTileAction) { m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeManual ); m_mdi->myTile(); } - else if (clickedAction == m_windowCascade_action) { + else if (clickedAction == m_windowCascadeAction) { m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeManual ); m_mdi->myCascade(); } - else if (clickedAction == m_windowTileVertical_action) { + else if (clickedAction == m_windowTileVerticalAction) { m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeManual ); m_mdi->myTileVertical(); } - else if (clickedAction == m_windowTileHorizontal_action) { + else if (clickedAction == m_windowTileHorizontalAction) { m_mdi->setMDIArrangementMode( CMDIArea::ArrangementModeManual ); m_mdi->myTileHorizontal(); } } void BibleTime::slotManualArrangementMode() { - slotUpdateWindowArrangementActions( m_windowManualMode_action ); + slotUpdateWindowArrangementActions( m_windowManualModeAction ); } -/** This slot is connected with the windowAutoTile_action object */ +/** This slot is connected with the windowAutoTileAction object */ void BibleTime::slotAutoTileHorizontal() { - slotUpdateWindowArrangementActions( m_windowAutoTileHorizontal_action ); + slotUpdateWindowArrangementActions( m_windowAutoTileHorizontalAction ); } -/** This slot is connected with the windowAutoTile_action object */ +/** This slot is connected with the windowAutoTileAction object */ void BibleTime::slotAutoTileVertical() { - slotUpdateWindowArrangementActions( m_windowAutoTileVertical_action ); + slotUpdateWindowArrangementActions( m_windowAutoTileVerticalAction ); } -/** This slot is connected with the windowAutoTile_action object */ +/** This slot is connected with the windowAutoTileAction object */ void BibleTime::slotAutoTile() { - slotUpdateWindowArrangementActions( m_windowAutoTile_action ); + slotUpdateWindowArrangementActions( m_windowAutoTileAction ); +} + +/** This slot is connected with the windowAutoTabbedAction object */ +void BibleTime::slotAutoTabbed() { + slotUpdateWindowArrangementActions( m_windowAutoTabbedAction ); } void BibleTime::slotTile() { - slotUpdateWindowArrangementActions( m_windowTile_action ); + slotUpdateWindowArrangementActions( m_windowTileAction ); } void BibleTime::slotCascade() { - slotUpdateWindowArrangementActions( m_windowCascade_action ); + slotUpdateWindowArrangementActions( m_windowCascadeAction ); } void BibleTime::slotTileVertical() { - slotUpdateWindowArrangementActions( m_windowTileVertical_action ); + slotUpdateWindowArrangementActions( m_windowTileVerticalAction ); } void BibleTime::slotTileHorizontal() { - slotUpdateWindowArrangementActions( m_windowTileHorizontal_action ); + slotUpdateWindowArrangementActions( m_windowTileHorizontalAction ); } -/** This slot is connected with the windowAutoCascade_action object */ +/** This slot is connected with the windowAutoCascadeAction object */ void BibleTime::slotAutoCascade() { - slotUpdateWindowArrangementActions( m_windowAutoCascade_action ); + slotUpdateWindowArrangementActions( m_windowAutoCascadeAction ); } /** Shows/hides the toolbar */ -void BibleTime::slotToggleToolbar() { +void BibleTime::slotToggleMainToolbar() { Q_ASSERT(m_mainToolBar); - if (m_viewToolbar_action->isChecked()) { + if (m_viewToolbarAction->isChecked()) { m_mainToolBar->show(); } else { @@ -271,22 +292,80 @@ void BibleTime::slotToggleTextWindowHeader() { emit toggledTextWindowHeader(!currentState); } -void BibleTime::slotToggleTextWindowNavigator() { +void BibleTime::slotToggleNavigatorToolbar() { bool currentState = CBTConfig::get(CBTConfig::showTextWindowNavigator); CBTConfig::set(CBTConfig::showTextWindowNavigator, !currentState); - emit toggledTextWindowNavigator(!currentState); + showOrHideToolBars(); + if (CBTConfig::get(CBTConfig::showToolbarsInEachWindow)) + emit toggledTextWindowNavigator(!currentState); + else + emit toggledTextWindowNavigator(false); } -void BibleTime::slotToggleTextWindowToolButtons() { +void BibleTime::slotToggleToolsToolbar() { bool currentState = CBTConfig::get(CBTConfig::showTextWindowToolButtons); CBTConfig::set(CBTConfig::showTextWindowToolButtons, !currentState); - emit toggledTextWindowToolButtons(!currentState); + showOrHideToolBars(); + if (CBTConfig::get(CBTConfig::showToolbarsInEachWindow)) + emit toggledTextWindowToolButtons(!currentState); + else + emit toggledTextWindowToolButtons(false); } -void BibleTime::slotToggleTextWindowModuleChooser() { +void BibleTime::slotToggleWorksToolbar() { bool currentState = CBTConfig::get(CBTConfig::showTextWindowModuleSelectorButtons); CBTConfig::set(CBTConfig::showTextWindowModuleSelectorButtons, !currentState); - emit toggledTextWindowModuleChooser(!currentState); + showOrHideToolBars(); + if (CBTConfig::get(CBTConfig::showToolbarsInEachWindow)) + emit toggledTextWindowModuleChooser(!currentState); + else + emit toggledTextWindowModuleChooser(false); +} + +void BibleTime::slotToggleFormatToolbar() { + bool currentState = CBTConfig::get(CBTConfig::showFormatToolbarButtons); + CBTConfig::set(CBTConfig::showFormatToolbarButtons, !currentState); + showOrHideToolBars(); + if (CBTConfig::get(CBTConfig::showToolbarsInEachWindow)) + emit toggledTextWindowFormatToolbar(!currentState); + else + emit toggledTextWindowFormatToolbar(false); +} + +void BibleTime::slotToggleToolBarsInEachWindow() { + bool currentState = CBTConfig::get(CBTConfig::showToolbarsInEachWindow); + CBTConfig::set(CBTConfig::showToolbarsInEachWindow, !currentState); + showOrHideToolBars(); + + if (!currentState) { + emit toggledTextWindowNavigator(CBTConfig::get(CBTConfig::showTextWindowNavigator)); + emit toggledTextWindowToolButtons(CBTConfig::get(CBTConfig::showTextWindowToolButtons)); + emit toggledTextWindowModuleChooser(CBTConfig::get(CBTConfig::showTextWindowModuleSelectorButtons)); + emit toggledTextWindowFormatToolbar(CBTConfig::get(CBTConfig::showFormatToolbarButtons)); + } + else { + emit toggledTextWindowNavigator(false); + emit toggledTextWindowToolButtons(false); + emit toggledTextWindowModuleChooser(false); + emit toggledTextWindowFormatToolbar(false); + } + + +} + +void BibleTime::showOrHideToolBars() { + if (CBTConfig::get(CBTConfig::showToolbarsInEachWindow)) { + m_navToolBar->setVisible(false); + m_worksToolBar->setVisible(false); + m_toolsToolBar->setVisible(false); + m_formatToolBar->setVisible(false); + } + else { + m_navToolBar->setVisible(CBTConfig::get(CBTConfig::showTextWindowNavigator)); + m_worksToolBar->setVisible(CBTConfig::get(CBTConfig::showTextWindowModuleSelectorButtons)); + m_toolsToolBar->setVisible(CBTConfig::get(CBTConfig::showTextWindowToolButtons)); + m_formatToolBar->setVisible(CBTConfig::get(CBTConfig::showFormatToolbarButtons)); + } } /** Sets the active window. */ @@ -298,7 +377,7 @@ void BibleTime::slotSetActiveSubWindow(QWidget* window) { void BibleTime::slotSearchModules() { //get the modules of the open windows - QList modules; + QList modules; foreach(QMdiSubWindow* subWindow, m_mdi->subWindowList()) { if (CDisplayWindow* w = dynamic_cast(subWindow->widget())) { @@ -312,7 +391,7 @@ void BibleTime::slotSearchModules() { * Call CSearchDialog::openDialog with only the default bible module */ void BibleTime::slotSearchDefaultBible() { - QList module; + QList module; CSwordModuleInfo* bible = CBTConfig::get(CBTConfig::standardBible); if (bible) { module.append(bible); @@ -335,6 +414,11 @@ void BibleTime::slotOpenAboutDialog() { dlg->show(); } +void BibleTime::slotOpenTipDialog() { + BtTipDialog* dlg = new BtTipDialog(this); + dlg->show(); +} + /** Saves the current settings into the currently activated profile. */ void BibleTime::saveProfile(QAction* action) { m_mdi->setUpdatesEnabled(false); @@ -405,7 +489,7 @@ void BibleTime::loadProfile(CProfile* p) { QList modules; for ( QStringList::Iterator it = usedModules.begin(); it != usedModules.end(); ++it ) { - if (CSwordModuleInfo* m = CPointers::backend()->findModuleByName(*it)) { + if (CSwordModuleInfo* m = CSwordBackend::instance()->findModuleByName(*it)) { modules.append(m); } } @@ -416,7 +500,7 @@ void BibleTime::loadProfile(CProfile* p) { //is w->isWriteWindow is false we create a write window, otherwise a read window CDisplayWindow* displayWindow = 0; if (w->writeWindowType() > 0) { //create a write window - displayWindow = createWriteDisplayWindow(modules.first(), key, CDisplayWindow::WriteWindowType(w->writeWindowType()) ); + displayWindow = createWriteDisplayWindow(modules.first(), key, CWriteWindow::WriteWindowType(w->writeWindowType()) ); } else { //create a read window displayWindow = createReadDisplayWindow(modules, key); @@ -449,7 +533,7 @@ void BibleTime::deleteProfile(QAction* action) { } void BibleTime::toggleFullscreen() { - if (m_windowFullscreen_action->isChecked()) { + if (m_windowFullscreenAction->isChecked()) { // set full screen mode m_WindowWasMaximizedBeforeFullScreen = isMaximized(); showFullScreen(); diff --git a/src/bibletimeapp.cpp b/src/bibletimeapp.cpp index 73ac468..8521f2a 100644 --- a/src/bibletimeapp.cpp +++ b/src/bibletimeapp.cpp @@ -2,40 +2,36 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "bibletimeapp.h" +#include #include "backend/config/cbtconfig.h" +#include "backend/managers/cdisplaytemplatemgr.h" #include "util/cresmgr.h" -BibleTimeApp::BibleTimeApp( int & argc, char ** argv ) : QApplication(argc, argv) { -// initDCOP(); - CResMgr::init_tr(); -} - BibleTimeApp::~BibleTimeApp() { + // Prevent writing to the log file before the directory cache is init: + if (!m_init) return; //we can set this safely now because we close now (hopyfully without crash) CBTConfig::set(CBTConfig::crashedLastTime, false); CBTConfig::set(CBTConfig::crashedTwoTimes, false); - deleteDisplayTemplateMgr(); - deleteLanguageMgr(); - deleteBackend(); + delete CDisplayTemplateMgr::instance(); + CLanguageMgr::destroyInstance(); + CSwordBackend::destroyInstance(); } -/* -void BibleTimeApp::initDCOP() { - const bool dcopOk = dcopClient()->attach(); - Q_ASSERT(dcopOk); - if (dcopOk) { - const Q3CString appId = dcopClient()->registerAs(kapp->name(), false); - // dcopClient()->setDefaultObject("BibleTimeInterface"); - } +bool BibleTimeApp::initDisplayTemplateManager() { + QString errorMessage; + new CDisplayTemplateMgr(errorMessage); + if (errorMessage.isNull()) return true; + QMessageBox::critical(0, tr("Fatal error!"), errorMessage); + return false; } -*/ diff --git a/src/bibletimeapp.h b/src/bibletimeapp.h index b3d5a0e..7ac1ebf 100644 --- a/src/bibletimeapp.h +++ b/src/bibletimeapp.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,19 +11,22 @@ #define BIBLETIMEAPP_H #include -#include "util/cpointers.h" -/** The BibleTimeApp class is used to clean up all instances of the backend and to delete all created module objects. - * @author The BibleTime team - */ -class BibleTimeApp : public QApplication, public CPointers { +/** + The BibleTimeApp class is used to clean up all instances of the backend and to + delete all created module objects. +*/ +class BibleTimeApp : public QApplication { public: - BibleTimeApp(int &argc, char **argv); + inline BibleTimeApp(int &argc, char **argv) : QApplication(argc, argv), m_init(false) {} ~BibleTimeApp(); - protected: -// void initDCOP(); + inline void startInit() { m_init = true; } + bool initDisplayTemplateManager(); + + private: + bool m_init; }; #endif diff --git a/src/btglobal.h b/src/btglobal.h new file mode 100644 index 0000000..9fa97fe --- /dev/null +++ b/src/btglobal.h @@ -0,0 +1,53 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTGLOBAL_H +#define BTGLOBAL_H + +/** + Filter options to control the text display of modules. Uses int and not bool + because not all options have just two toggle values. +*/ +struct FilterOptions { + int footnotes; /**< 0 for disabled, 1 for enabled */ + int strongNumbers; /**< 0 for disabled, 1 for enabled */ + int headings; /**< 0 for disabled, 1 for enabled */ + int morphTags; /**< 0 for disabled, 1 for enabled */ + int lemmas; /**< 0 for disabled, 1 for enabled */ + int hebrewPoints; /**< 0 for disabled, 1 for enabled */ + int hebrewCantillation; /**< 0 for disabled, 1 for enabled */ + int greekAccents; /**< 0 for disabled, 1 for enabled */ + int textualVariants; /**< Number n to enabled the n-th variant */ + int redLetterWords; /**< 0 for disabled, 1 for enabled */ + int scriptureReferences; /**< 0 for disabled, 1 for enabled */ + int morphSegmentation; /**< 0 for disabled, 1 for enabled */ +}; +Q_DECLARE_METATYPE(FilterOptions) + +/** + Controls the display of a text. +*/ +struct DisplayOptions { + int lineBreaks; + int verseNumbers; + +/** + Work around for Windows compiler bug in Visual Studio 2008 & 2010. The Crash + occurs at the return statement of CBTConfig::getDisplayOptionDefaults and is + caused by a bad calling sequence when called from CDisplayWindow::init. + \todo Properly identify this bug and remove the #ifdef when fix is available. +*/ +#ifdef Q_WS_WIN + int notUsed; +#endif + +}; +Q_DECLARE_METATYPE(DisplayOptions) + +#endif // BTGLOBAL_H diff --git a/src/frontend/bookmarks/btbookmarkfolder.cpp b/src/frontend/bookmarks/btbookmarkfolder.cpp new file mode 100644 index 0000000..1cc2583 --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkfolder.cpp @@ -0,0 +1,140 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookmarks/btbookmarkfolder.h" + +#include +#include +#include "frontend/bookmarks/btbookmarkitembase.h" +#include "frontend/bookmarks/btbookmarkitem.h" +#include "frontend/bookmarks/btbookmarkloader.h" +#include "util/cresmgr.h" +#include "util/directory.h" + + +BtBookmarkFolder::BtBookmarkFolder(const QString &name, QTreeWidgetItem *parent) + : BtBookmarkItemBase(parent) { + setText(0, name); + setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); +} + +bool BtBookmarkFolder::enableAction(MenuAction action) { + if (action == ChangeFolder || action == NewFolder || action == DeleteEntries || action == ImportBookmarks ) + return true; + if (action == SortFolderBookmarks || action == ExportBookmarks || action == ImportBookmarks ) + return true; + if ((action == PrintBookmarks) && childCount()) + return true; + return false; +} + +void BtBookmarkFolder::exportBookmarks() { + QString filter = QObject::tr("BibleTime bookmark files") + QString(" (*.btb);;") + QObject::tr("All files") + QString(" (*.*)"); + QString fileName = QFileDialog::getSaveFileName(0, QObject::tr("Export Bookmarks"), "", filter); + + if (!fileName.isEmpty()) { + qDebug() << "exportBookmarks()"; + BtBookmarkLoader loader; + loader.saveTreeFromRootItem(this, fileName, false ); //false: don't overwrite without asking + }; + +} + +void BtBookmarkFolder::importBookmarks() { + QString filter = QObject::tr("BibleTime bookmark files") + QString(" (*.btb);;") + QObject::tr("All files") + QString(" (*.*)"); + QString fileName = QFileDialog::getOpenFileName(0, QObject::tr("Import bookmarks"), "", filter); + if (!fileName.isEmpty()) { + qDebug() << "import bookmarks"; + BtBookmarkLoader loader; + QList itemList = loader.loadTree(fileName); + this->insertChildren(0, itemList); + }; +} + +QString BtBookmarkFolder::toolTip() const { + return QString::null; +} + +void BtBookmarkFolder::newSubFolder() { + if (dynamic_cast(this)) { + BtBookmarkFolder* f = new BtBookmarkFolder(QObject::tr("New folder"), this); + + treeWidget()->setCurrentItem(f); + f->update(); + f->rename(); + } +} + +QList BtBookmarkFolder::getChildList() const { + QList list; + for (int i = 0; i < childCount(); i++) { + list.append(child(i)); + } + return list; +} + +void BtBookmarkFolder::rename() { + treeWidget()->editItem(this); +} + +void BtBookmarkFolder::update() { + namespace DU = util::directory; + + qDebug() << "BtBookmarkFolder::update()"; + BtBookmarkItemBase::update(); + if (isExpanded() && childCount()) + setIcon(0, DU::getIcon(CResMgr::mainIndex::openedFolder::icon)); + else + setIcon(0, DU::getIcon(CResMgr::mainIndex::closedFolder::icon)); +} + +bool BtBookmarkFolder::hasDescendant(QTreeWidgetItem* item) const { + qDebug() << "BtBookmarkFolder::hasDescendant, this:" << this << "possible descendant:" << item; + + if (this == item) { + qDebug() << "it's this, return true"; + return true; + } + if (getChildList().indexOf(item) > -1) { + qDebug() << "direct child, return true"; + return true; + } + foreach(QTreeWidgetItem* childItem, getChildList()) { + bool subresult = false; + BtBookmarkFolder* folder = 0; + if ( (folder = dynamic_cast(childItem)) ) { + subresult = folder->hasDescendant(childItem); + } + + if (subresult == true) { + qDebug() << "descendand child, return true"; + return true; + } + } + qDebug() << "no child, return false"; + return false; +} + +BtBookmarkFolder* BtBookmarkFolder::deepCopy() { + qDebug() << "BtBookmarkFolder::deepCopy"; + BtBookmarkFolder* newFolder = new BtBookmarkFolder(this->text(0)); + foreach(QTreeWidgetItem* subitem, getChildList()) { + if (BtBookmarkItem* bmItem = dynamic_cast(subitem)) { + newFolder->addChild(new BtBookmarkItem(*bmItem)); + } + else { + if (BtBookmarkFolder* bmFolder = dynamic_cast(subitem)) { + newFolder->addChild(bmFolder->deepCopy()); + } + } + } + newFolder->update(); + return newFolder; +} + diff --git a/src/frontend/bookmarks/btbookmarkfolder.h b/src/frontend/bookmarks/btbookmarkfolder.h new file mode 100644 index 0000000..90021f8 --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkfolder.h @@ -0,0 +1,50 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKMARKFOLDER_H +#define BTBOOKMARKFOLDER_H + +#include "frontend/bookmarks/btbookmarkitembase.h" + + +#define CURRENT_SYNTAX_VERSION 1 + +class BtBookmarkFolder : public BtBookmarkItemBase { + public: + friend class BtBookmarkLoader; + BtBookmarkFolder(const QString &name, QTreeWidgetItem *parent = 0); + ~BtBookmarkFolder() {} + + /** See the base class. */ + virtual bool enableAction(const MenuAction action); + + /** User gives a file from which to load items into this folder. */ + virtual void exportBookmarks(); + /** User gives a file to which items from this folder are saved. */ + virtual void importBookmarks(); + + /** Creates a new folder under this. */ + void newSubFolder(); + + /** Returns a list of direct childs of this item. */ + QList getChildList() const; + + /** Returns true if the given item is this or a direct or indirect subitem of this. */ + bool hasDescendant(QTreeWidgetItem* item) const; + + /** Creates a deep copy of this item. */ + BtBookmarkFolder* deepCopy(); + + void rename(); + void update(); + + QString toolTip() const; +}; + +#endif diff --git a/src/frontend/bookmarks/btbookmarkitem.cpp b/src/frontend/bookmarks/btbookmarkitem.cpp new file mode 100644 index 0000000..fff3d2c --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkitem.cpp @@ -0,0 +1,149 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookmarks/btbookmarkitem.h" + +#include +#include +#include "backend/config/cbtconfig.h" +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/keys/cswordversekey.h" +#include "btglobal.h" +#include "frontend/bookmarks/btbookmarkfolder.h" +#include "frontend/bookmarks/bteditbookmarkdialog.h" +#include "util/cresmgr.h" +#include "util/directory.h" + + +BtBookmarkItem::BtBookmarkItem(const CSwordModuleInfo *module, + const QString &key, + const QString &description, + const QString &title) + : m_description(description), + m_moduleName(module ? module->name() : QString::null), + m_title(title) +{ + if (((module && (module->type() == CSwordModuleInfo::Bible)) || (module->type() == CSwordModuleInfo::Commentary)) ) { + CSwordVerseKey vk(0); + vk.setKey(key); + vk.setLocale("en"); + m_key = vk.key(); //the m_key member is always the english key! + } + else { + m_key = key; + }; + + update(); +} + +BtBookmarkItem::BtBookmarkItem(QTreeWidgetItem* parent) + : BtBookmarkItemBase(parent) {} + +BtBookmarkItem::BtBookmarkItem(const BtBookmarkItem& other) + : BtBookmarkItemBase(0), + m_key(other.m_key), + m_description(other.m_description), + m_moduleName(other.m_moduleName), + m_title(other.m_title) +{ + update(); +} + +CSwordModuleInfo *BtBookmarkItem::module() const { + return CSwordBackend::instance()->findModuleByName(m_moduleName); +} + +QString BtBookmarkItem::key() const { + const QString englishKeyName = englishKey(); + if (!module()) { + return englishKeyName; + } + + QString returnKeyName = englishKeyName; + if ((module()->type() == CSwordModuleInfo::Bible) || (module()->type() == CSwordModuleInfo::Commentary)) { + CSwordVerseKey vk(0); + vk.setKey(englishKeyName); + vk.setLocale(CSwordBackend::instance()->booknameLanguage().toLatin1() ); + + returnKeyName = vk.key(); //the returned key is always in the currently set bookname language + } + + return returnKeyName; +} + +QString BtBookmarkItem::toolTip() const { + if (!module()) { + return QString::null; + } + + FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults(); + filterOptions.footnotes = false; + filterOptions.scriptureReferences = false; + CSwordBackend::instance()->setFilterOptions(filterOptions); + + QString ret; + QSharedPointer k( CSwordKey::createInstance(module()) ); + k->setKey(key()); + + // const CLanguageMgr::Language* lang = module()->language(); + // CBTConfig::FontSettingsPair fontPair = CBTConfig::get(lang); + + Q_ASSERT(k.data()); + QString header = QString::fromLatin1("%1 (%2)") + .arg(key()) + .arg(module()->name()); + if (title() != header) { + ret = QString::fromLatin1("%1
%2
%3") + .arg(header) + .arg(title()) + .arg(description()) + ; + } + else { + ret = QString::fromLatin1("%1
%2") + .arg(header) + .arg(description()) + ; + } + + return ret; +} + +bool BtBookmarkItem::enableAction(MenuAction action) { + if (action == EditBookmark || (module() && (action == PrintBookmarks)) || action == DeleteEntries) + return true; + + return false; +} + +void BtBookmarkItem::rename() { + BtEditBookmarkDialog d(QString::fromLatin1("%1 (%2)").arg(key()).arg(module() ? module()->name() : QObject::tr("unknown")), + m_title, + m_description, treeWidget()); + + if (d.exec() == QDialog::Accepted) { + m_title = d.titleText(); + m_description = d.descriptionText(); + update(); + } +} + +void BtBookmarkItem::update() { + namespace DU = util::directory; + + qDebug() << "BtBookmarkItem::update"; + setIcon(0, DU::getIcon(CResMgr::mainIndex::bookmark::icon)); + + if (m_title.isEmpty()) { + m_title = QString::fromLatin1("%1 (%2)").arg(key()).arg(module() ? module()->name() : QObject::tr("unknown")); + } + setText(0,m_title); + setToolTip(0, toolTip()); +} + diff --git a/src/frontend/bookmarks/btbookmarkitem.h b/src/frontend/bookmarks/btbookmarkitem.h new file mode 100644 index 0000000..3166e61 --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkitem.h @@ -0,0 +1,76 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKMARKITEM_H +#define BTBOOKMARKITEM_H + +#include "frontend/bookmarks/btbookmarkitembase.h" + +#include + + +class BtBookmarkFolder; +class CSwordModuleInfo; + +class BtBookmarkItem : public BtBookmarkItemBase { + public: + friend class BtBookmarkLoader; + + BtBookmarkItem(QTreeWidgetItem* parent); + + /** Creates a bookmark with module, key and description. */ + BtBookmarkItem(const CSwordModuleInfo *module, const QString &key, + const QString &description, const QString &title); + + /** Creates a copy. */ + BtBookmarkItem(const BtBookmarkItem& other); + + ~BtBookmarkItem() {} + + /** Returns the used module, 0 if there is no such module. */ + CSwordModuleInfo *module() const; + + /** Returns the used key. */ + QString key() const; + + /** Returns the used description. */ + inline const QString &description() const { + return m_description; + } + + /** Returns the title. */ + inline const QString &title() const { + return m_title; + } + + /** Returns a tooltip for this bookmark. */ + virtual QString toolTip() const; + + /** Returns whether the action is supported by this item. */ + virtual bool enableAction(MenuAction action); + + /** Changes this bookmark. */ + virtual void rename(); + + void update(); + + private: + /** Returns the english key.*/ + inline const QString &englishKey() const { + return m_key; + } + + private: + QString m_key; + QString m_description; + QString m_moduleName; + QString m_title; +}; + +#endif diff --git a/src/frontend/bookmarks/btbookmarkitembase.cpp b/src/frontend/bookmarks/btbookmarkitembase.cpp new file mode 100644 index 0000000..1a80f7d --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkitembase.cpp @@ -0,0 +1,21 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookmarks/btbookmarkitembase.h" + + +BtBookmarkItemBase::BtBookmarkItemBase() { + // Intentionally empty +} + +BtBookmarkItemBase::BtBookmarkItemBase(QTreeWidgetItem *parent) + : QTreeWidgetItem(parent) +{ + // Intentionally empty +} diff --git a/src/frontend/bookmarks/btbookmarkitembase.h b/src/frontend/bookmarks/btbookmarkitembase.h new file mode 100644 index 0000000..8452473 --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkitembase.h @@ -0,0 +1,62 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKMARKITEMBASE_H +#define BTBOOKMARKITEMBASE_H + +#include + +#include +#include +#include + + +class CBookmarkIndex; + +class BtBookmarkItemBase : public QTreeWidgetItem { + public: + enum MenuAction { + NewFolder = 0, + ChangeFolder, + + EditBookmark, + SortFolderBookmarks, + SortAllBookmarks, + ImportBookmarks, + ExportBookmarks, + PrintBookmarks, + + DeleteEntries, + + ActionBegin = NewFolder, + ActionEnd = DeleteEntries + }; + + /** Where to drop/create item(s): above, below or inside an item.*/ + enum Location {Above, Below, Inside}; + + BtBookmarkItemBase(); + BtBookmarkItemBase(QTreeWidgetItem* parent); + virtual ~BtBookmarkItemBase() {} + + virtual QString toolTip() const = 0; + + /** Returns true if the given action should be enabled in the popup menu. */ + virtual bool enableAction( MenuAction action ) = 0; + + /** Rename the item. */ + virtual void rename() = 0; + + /** Update the item (icon etc.) after creating or changing it. */ + virtual void update() {} + +}; + +#endif + diff --git a/src/frontend/bookmarks/btbookmarkloader.cpp b/src/frontend/bookmarks/btbookmarkloader.cpp new file mode 100644 index 0000000..ed1dd29 --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkloader.cpp @@ -0,0 +1,177 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookmarks/btbookmarkloader.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "backend/drivers/cswordmoduleinfo.h" +#include "frontend/bookmarks/btbookmarkitem.h" +#include "frontend/bookmarks/btbookmarkfolder.h" +#include "util/tool.h" + + +#define CURRENT_SYNTAX_VERSION 1 + +QList BtBookmarkLoader::loadTree(QString fileName) { + qDebug() << "BtBookmarkLoader::loadTree"; + QList itemList; + + QDomDocument doc; + doc.setContent(loadXmlFromFile(fileName)); + + //bookmarkfolder::loadBookmarksFromXML() + + QDomElement document = doc.documentElement(); + if ( document.tagName() != "SwordBookmarks" ) { + qWarning("Not a BibleTime Bookmark XML file"); + return QList(); + } + + QDomElement child = document.firstChild().toElement(); + + while ( !child.isNull() && child.parentNode() == document) { + qDebug() << "BtBookmarkLoader::loadTree while start"; + QTreeWidgetItem* i = handleXmlElement(child, 0); + itemList.append(i); + if (!child.nextSibling().isNull()) { + child = child.nextSibling().toElement(); + } + else { + child = QDomElement(); //null + } + + } + + return itemList; +} + +QTreeWidgetItem* BtBookmarkLoader::handleXmlElement(QDomElement& element, QTreeWidgetItem* parent) { + qDebug() << "BtBookmarkLoader::handleXmlElement"; + QTreeWidgetItem* newItem = 0; + if (element.tagName() == "Folder") { + qDebug() << "BtBookmarkLoader::handleXmlElement: found folder"; + BtBookmarkFolder* newFolder = new BtBookmarkFolder(QString::null, parent); + if (element.hasAttribute("caption")) { + newFolder->setText(0, element.attribute("caption")); + } + QDomNodeList childList = element.childNodes(); + for (unsigned int i = 0; i < childList.length(); i++) { + qDebug() << "BtBookmarkLoader::handleXmlElement: go through child list of folder"; + QDomElement newElement = childList.at(i).toElement(); + QTreeWidgetItem* newChildItem = handleXmlElement(newElement, newFolder); + newFolder->addChild(newChildItem); + } + newFolder->update(); + newItem = newFolder; + } + else if (element.tagName() == "Bookmark") { + qDebug() << "BtBookmarkLoader::handleXmlElement: found bookmark"; + BtBookmarkItem* newBookmarkItem = new BtBookmarkItem(parent); + if (element.hasAttribute("modulename")) { + //we use the name in all cases, even if the module isn't installed anymore + newBookmarkItem->m_moduleName = element.attribute("modulename"); + } + if (element.hasAttribute("key")) { + newBookmarkItem->m_key = element.attribute("key"); + } + if (element.hasAttribute("description")) { + newBookmarkItem->m_description = element.attribute("description"); + } + if (element.hasAttribute("title")) { + newBookmarkItem->m_title = element.attribute("title"); + } + newBookmarkItem->update(); + newItem = newBookmarkItem; + } + qDebug() << "BtBookmarkLoader::handleXmlElement: return new item"; + return newItem; +} + + +QString BtBookmarkLoader::loadXmlFromFile(QString fileName) { + namespace DU = util::directory; + + if (fileName.isNull()) { + fileName = DU::getUserBaseDir().absolutePath() + "/bookmarks.xml"; + } + QFile file(fileName); + if (!file.exists()) + return QString::null; + + QString xml; + if (file.open(QIODevice::ReadOnly)) { + QTextStream t; + t.setAutoDetectUnicode(false); + t.setCodec(QTextCodec::codecForName("UTF-8")); + t.setDevice(&file); + xml = t.readAll(); + file.close(); + } + return xml; +} + +void BtBookmarkLoader::saveTreeFromRootItem(QTreeWidgetItem* rootItem, QString fileName, bool forceOverwrite) { + namespace DU = util::directory; + + Q_ASSERT(rootItem); + if (fileName.isNull()) { + fileName = DU::getUserBaseDir().absolutePath() + "/bookmarks.xml"; + } + + QDomDocument doc("DOC"); + doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = doc.createElement("SwordBookmarks"); + content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION); + doc.appendChild(content); + + //append the XML nodes of all child items + + for (int i = 0; i < rootItem->childCount(); i++) { + saveItem(rootItem->child(i), content); + } + util::tool::savePlainFile(fileName, doc.toString(), forceOverwrite, QTextCodec::codecForName("UTF-8")); + +} + +void BtBookmarkLoader::saveItem(QTreeWidgetItem* item, QDomElement& parentElement) { + BtBookmarkFolder* folderItem = 0; + BtBookmarkItem* bookmarkItem = 0; + + if ((folderItem = dynamic_cast(item))) { + QDomElement elem = parentElement.ownerDocument().createElement("Folder"); + elem.setAttribute("caption", folderItem->text(0)); + + parentElement.appendChild(elem); + + for (int i = 0; i < folderItem->childCount(); i++) { + saveItem(folderItem->child(i), elem); + } + } + else if ((bookmarkItem = dynamic_cast(item))) { + QDomElement elem = parentElement.ownerDocument().createElement("Bookmark"); + + elem.setAttribute("key", bookmarkItem->englishKey()); + elem.setAttribute("description", bookmarkItem->description()); + elem.setAttribute("modulename", bookmarkItem->m_moduleName); + elem.setAttribute("moduledescription", bookmarkItem->module() ? bookmarkItem->module()->config(CSwordModuleInfo::Description) : QString::null); + if ( ! bookmarkItem->title().isEmpty()) { + elem.setAttribute("title", bookmarkItem->m_title); + } + parentElement.appendChild(elem); + } +} diff --git a/src/frontend/bookmarks/btbookmarkloader.h b/src/frontend/bookmarks/btbookmarkloader.h new file mode 100644 index 0000000..8b819ce --- /dev/null +++ b/src/frontend/bookmarks/btbookmarkloader.h @@ -0,0 +1,46 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBOOKMARKLOADER_H +#define BTBOOKMARKLOADER_H + +#include "util/directory.h" + +#include +#include +#include + + +class QTreeWidgetItem; + +/** +* Class for loading and saving bookmarks. +*/ +class BtBookmarkLoader { + public: + /** Loads a list of items (with subitem trees) from a named file + * or from the default bookmarks file. */ + QList loadTree(QString fileName = QString::null); + + /** Takes one item and saves the tree which is under it to a named file + * or to the default bookmarks file, asking the user about overwriting if necessary. */ + void saveTreeFromRootItem(QTreeWidgetItem* rootItem, QString fileName = QString::null, bool forceOverwrite = true); + + private: + /** Create a new item from a document element. */ + QTreeWidgetItem* handleXmlElement(QDomElement& element, QTreeWidgetItem* parent); + + /** Writes one item to a document element. */ + void saveItem(QTreeWidgetItem* item, QDomElement& parentElement); + + /** Loads a bookmark XML document from a named file or from the default bookmarks file. */ + QString loadXmlFromFile(QString fileName = QString::null); +}; + +#endif diff --git a/src/frontend/bookmarks/bteditbookmarkdialog.cpp b/src/frontend/bookmarks/bteditbookmarkdialog.cpp new file mode 100644 index 0000000..614498f --- /dev/null +++ b/src/frontend/bookmarks/bteditbookmarkdialog.cpp @@ -0,0 +1,78 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "bteditbookmarkdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include "util/cresmgr.h" +#include "util/dialogutil.h" +#include "util/directory.h" + + +BtEditBookmarkDialog::BtEditBookmarkDialog(const QString &key, + const QString &title, + const QString &description, + QWidget *parent, + Qt::WindowFlags wflags) + : QDialog(parent, wflags) +{ + namespace DU = util::directory; + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + resize(400, 300); + setWindowIcon(DU::getIcon(CResMgr::mainIndex::bookmark::icon)); + + m_layout = new QFormLayout; + + m_keyLabel = new QLabel(this); + m_keyTextLabel = new QLabel(key, this); + m_layout->addRow(m_keyLabel, m_keyTextLabel); + + m_titleLabel = new QLabel(this); + m_titleEdit = new QLineEdit(title, this); + m_layout->addRow(m_titleLabel, m_titleEdit); + + m_descriptionLabel = new QLabel(this); + m_descriptionEdit = new QTextEdit(description, this); + m_descriptionEdit->setWordWrapMode(QTextOption::WordWrap); + m_layout->addRow(m_descriptionLabel, m_descriptionEdit); + + mainLayout->addLayout(m_layout); + + m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel + | QDialogButtonBox::NoButton + | QDialogButtonBox::Ok, + Qt::Horizontal, + this); + util::prepareDialogBox(m_buttonBox); + mainLayout->addWidget(m_buttonBox); + + QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + retranslateUi(); + + m_titleEdit->setFocus(); +} + +void BtEditBookmarkDialog::retranslateUi() { + setWindowTitle(tr("Edit Bookmark")); + m_keyLabel->setText(tr("Location:")); + m_titleLabel->setText(tr("Title:")); + m_descriptionLabel->setText(tr("Description:")); + + /// \todo Add tooltips and what's this texts etc. +} diff --git a/src/frontend/bookmarks/bteditbookmarkdialog.h b/src/frontend/bookmarks/bteditbookmarkdialog.h new file mode 100644 index 0000000..c3455e2 --- /dev/null +++ b/src/frontend/bookmarks/bteditbookmarkdialog.h @@ -0,0 +1,62 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTEDITBOOKMARKDIALOG_H +#define BTEDITBOOKMARKDIALOG_H + +#include +#include +#include + +class QDialogButtonBox; +class QFormLayout; +class QLabel; +class QWidget; + +/** + \brief A dialog box for editing bookmarks. +*/ +class BtEditBookmarkDialog : public QDialog { + Q_OBJECT + + public: /* Methods: */ + BtEditBookmarkDialog(const QString &key, + const QString &title, + const QString &description, + QWidget *parent = 0, + Qt::WindowFlags wflags = Qt::Dialog); + + /** + * Returns the description written in the description box. + */ + inline const QString descriptionText() { + return m_descriptionEdit->toPlainText(); + } + + /** + * Returns the title written in the title box. + */ + inline const QString titleText() { return m_titleEdit->text(); } + + protected: /* Methods: */ + void retranslateUi(); + + private: /* Fields: */ + QFormLayout *m_layout; + QLabel *m_keyLabel; + QLabel *m_keyTextLabel; + QLabel *m_titleLabel; + QLineEdit *m_titleEdit; + QLabel *m_descriptionLabel; + QTextEdit *m_descriptionEdit; + QDialogButtonBox *m_buttonBox; + +}; + +#endif diff --git a/src/frontend/bookmarks/cbookmarkindex.cpp b/src/frontend/bookmarks/cbookmarkindex.cpp new file mode 100644 index 0000000..b6adbfa --- /dev/null +++ b/src/frontend/bookmarks/cbookmarkindex.cpp @@ -0,0 +1,937 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookmarks/cbookmarkindex.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "backend/config/cbtconfig.h" +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/referencemanager.h" +#include "frontend/cdragdrop.h" +#include "frontend/cinfodisplay.h" +#include "frontend/cprinter.h" +#include "frontend/bookmarks/btbookmarkitembase.h" +#include "frontend/bookmarks/btbookmarkitem.h" +#include "frontend/bookmarks/btbookmarkfolder.h" +#include "frontend/bookmarks/btbookmarkloader.h" +#include "frontend/searchdialog/csearchdialog.h" +#include "util/cresmgr.h" +#include "util/tool.h" +#include "util/directory.h" +#include "util/dialogutil.h" +#include "bibletime.h" + + +CBookmarkIndex::CBookmarkIndex(QWidget *parent) + : QTreeWidget(parent), + m_magTimer(this), + m_previousEventItem(0) { + setMouseTracking(true); + m_magTimer.setSingleShot(true); + m_magTimer.setInterval(CBTConfig::get(CBTConfig::magDelay)); + setContextMenuPolicy(Qt::CustomContextMenu); + initView(); + initConnections(); + initTree(); +} + +CBookmarkIndex::~CBookmarkIndex() { + saveBookmarks(); +} + + +/** Initializes the view. */ +void CBookmarkIndex::initView() { + //qDebug() << "CBookmarkIndex::initView"; + + setHeaderHidden(true); + + setFocusPolicy(Qt::WheelFocus); + + //d'n'd related settings + setDragEnabled( true ); + setAcceptDrops( true ); + setDragDropMode(QAbstractItemView::DragDrop); + viewport()->setAcceptDrops(true); + setAutoScroll(true); + setAutoExpandDelay(800); + + setItemsExpandable(true); + setRootIsDecorated(true); + setAllColumnsShowFocus(true); + setSelectionMode(QAbstractItemView::ExtendedSelection); + + //setup the popup menu + m_popup = new QMenu(viewport()); + m_popup->setTitle(tr("Bookmarks")); + + m_actions.newFolder = newQAction(tr("New folder"), CResMgr::mainIndex::newFolder::icon, 0, this, SLOT(createNewFolder()), this); + m_actions.changeFolder = newQAction(tr("Rename folder"), CResMgr::mainIndex::changeFolder::icon, 0, this, SLOT(changeFolder()), this); + + m_actions.editBookmark = newQAction(tr("Edit bookmark..."), CResMgr::mainIndex::editBookmark::icon, 0, this, SLOT(editBookmark()), this); + /// \todo Add icons for sorting bookmarks + m_actions.sortFolderBookmarks = newQAction(tr("Sort folder bookmarks..."), QString::null, 0, this, SLOT(sortFolderBookmarks()), this); + m_actions.sortAllBookmarks = newQAction(tr("Sort all bookmarks..."), QString::null, 0, this, SLOT(sortAllBookmarks()), this); + m_actions.importBookmarks = newQAction(tr("Import to folder..."), CResMgr::mainIndex::importBookmarks::icon, 0, this, SLOT(importBookmarks()), this); + m_actions.exportBookmarks = newQAction(tr("Export from folder..."), CResMgr::mainIndex::exportBookmarks::icon, 0, this, SLOT(exportBookmarks()), this); + m_actions.printBookmarks = newQAction(tr("Print bookmarks..."), CResMgr::mainIndex::printBookmarks::icon, 0, this, SLOT(printBookmarks()), this); + + m_actions.deleteEntries = newQAction(tr("Remove selected items..."), CResMgr::mainIndex::deleteItems::icon, 0, this, SLOT(deleteEntries()), this); + + + //fill the popup menu itself + m_popup->addAction(m_actions.newFolder); + m_popup->addAction(m_actions.changeFolder); + QAction* separator = new QAction(this); + separator->setSeparator(true); + m_popup->addAction(separator); + m_popup->addAction(m_actions.editBookmark); + m_popup->addAction(m_actions.sortFolderBookmarks); + m_popup->addAction(m_actions.sortAllBookmarks); + m_popup->addAction(m_actions.importBookmarks); + m_popup->addAction(m_actions.exportBookmarks); + m_popup->addAction(m_actions.printBookmarks); + separator = new QAction(this); + separator->setSeparator(true); + m_popup->addAction(separator); + m_popup->addAction(m_actions.deleteEntries); + + m_bookmarksModified = false; + //qDebug() << "CBookmarkIndex::initView end"; +} + +/** Convenience function for creating a new QAction. +* Should be replaced with something better; it was easier to make a new function +* than to modify all QAction constructors. +*/ +QAction* CBookmarkIndex::newQAction(const QString& text, const QString& pix, const int /*shortcut*/, const QObject* receiver, const char* slot, QObject* parent) { + namespace DU = util::directory; + QAction *action; + if (pix.isEmpty()) { + action = new QAction(text, parent); + } else { + action = new QAction(DU::getIcon(pix), text, parent); + } + QObject::connect(action, SIGNAL(triggered()), receiver, slot); + return action; +} + +/** Initialize the SIGNAL<->SLOT connections */ +void CBookmarkIndex::initConnections() { + //qDebug() << "CBookmarkIndex::initConnections"; + bool ok; + ok = connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(slotExecuted(QTreeWidgetItem*))); + Q_ASSERT(ok); + ok = connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), + SLOT(contextMenu(const QPoint&))); + Q_ASSERT(ok); + ok = connect(&m_magTimer, SIGNAL(timeout()), this, SLOT(magTimeout())); + Q_ASSERT(ok); + ok = connect(this, SIGNAL(itemEntered(QTreeWidgetItem*, int)), this, SLOT(slotItemEntered(QTreeWidgetItem*, int)) ); + Q_ASSERT(ok); + + // Connection to detect changes in the items themselves (e.g. renames, + // description changes) so that we can consider saving the bookmarks. + connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(needToSaveBookmarks(QTreeWidgetItem*)) ); + + // Connect the bookmark saving timer. + bookmarkSaveTimer.setSingleShot(true); + connect(&bookmarkSaveTimer, SIGNAL(timeout()), this, SLOT(considerSavingBookmarks()) ); +} + + +/** +* Hack to get single click and selection working. See slotExecuted. +*/ +void CBookmarkIndex::mouseReleaseEvent(QMouseEvent* event) { + //qDebug() << "CBookmarkIndex::mouseReleaseEvent"; + m_mouseReleaseEventModifiers = event->modifiers(); + QTreeWidget::mouseReleaseEvent(event); +} + +/** Called when an item is clicked with mouse or activated with keyboard. */ +void CBookmarkIndex::slotExecuted( QTreeWidgetItem* i ) { + qDebug() << "CBookmarkIndex::slotExecuted"; + + //HACK: checking the modifier keys from the last mouseReleaseEvent + //depends on executing order: mouseReleaseEvent first, then itemClicked signal + int modifiers = m_mouseReleaseEventModifiers; + m_mouseReleaseEventModifiers = Qt::NoModifier; + if (modifiers != Qt::NoModifier) { + return; + } + + BtBookmarkItemBase* btItem = dynamic_cast(i); + if (!btItem) { + return; + } + + BtBookmarkFolder* folderItem = 0; + BtBookmarkItem* bookmarkItem = 0; + if ((folderItem = dynamic_cast(btItem))) { + i->setExpanded( !i->isExpanded() ); + } + else if (( bookmarkItem = dynamic_cast(btItem) )) { //clicked on a bookmark + if (CSwordModuleInfo* mod = bookmarkItem->module()) { + QList modules; + modules.append(mod); + emit createReadDisplayWindow(modules, bookmarkItem->key()); + } + } +} + +/** Creates a drag mime data object for the current selection. */ +QMimeData* CBookmarkIndex::dragObject() { + BTMimeData::ItemList dndItems; + BTMimeData* mimeData = new BTMimeData; + + foreach( QTreeWidgetItem* widgetItem, selectedItems() ) { + if (!widgetItem) + break; + if (dynamic_cast(widgetItem)) { + if (BtBookmarkItem* bookmark = dynamic_cast( widgetItem )) { + //take care of bookmarks which have no valid module any more, e.g. if it was uninstalled + const QString moduleName = bookmark->module() ? bookmark->module()->name() : QString::null; + mimeData->appendBookmark(moduleName, bookmark->key(), bookmark->description()); + } + } + } + return mimeData; +} + +void CBookmarkIndex::dragEnterEvent( QDragEnterEvent* event ) { + //qDebug() << "CBookmarkIndex::dragEnterEvent"; + setState(QAbstractItemView::DraggingState); + QTreeWidget::dragEnterEvent(event); + if (event->source() == this || event->mimeData()->hasFormat("BibleTime/Bookmark")) { + event->acceptProposedAction(); + } +} + + +void CBookmarkIndex::dragMoveEvent( QDragMoveEvent* event ) { + //qDebug() << "CBookmarkIndex::dragMoveEvent"; + + // do this first, otherwise the event may be ignored + QTreeWidget::dragMoveEvent(event); + + event->acceptProposedAction(); + event->accept(); + + // do this to paint the arrow + m_dragMovementPosition = event->pos(); + viewport()->update(); + +} + +void CBookmarkIndex::dragLeaveEvent( QDragLeaveEvent* ) { + qDebug() << "CBookmarkIndex::dragLeaveEvent"; + setState(QAbstractItemView::NoState); // not dragging anymore + viewport()->update(); // clear the arrow +} + + +void CBookmarkIndex::paintEvent(QPaintEvent* event) { + namespace DU = util::directory; + + static QPixmap pix; + static int halfPixHeight; + static bool arrowInitialized = false; + + // Initialize the static variables, including the arrow pixmap + if (!arrowInitialized) { + arrowInitialized = true; + int arrowSize = util::tool::mWidth(this, 1); + QString fileName; + if (DU::getIconDir().exists("pointing_arrow.svg")) { + fileName = DU::getIconDir().filePath("pointing_arrow.svg"); + } + else { + if (DU::getIconDir().exists("pointing_arrow.png")) { + fileName = DU::getIconDir().filePath("pointing_arrow.png"); + } + else { + qWarning() << "Picture file pointing_arrow.svg or .png not found!"; + } + } + + pix = QPixmap(fileName); + pix = pix.scaled(arrowSize, arrowSize, Qt::KeepAspectRatioByExpanding); + halfPixHeight = pix.height() / 2; + } + + // Do the normal painting first + QTreeWidget::paintEvent(event); + + // Paint the arrow if the drag is going on + if (QAbstractItemView::DraggingState == state()) { + bool rtol = QApplication::isRightToLeft(); + + QPainter painter(this->viewport()); + QTreeWidgetItem* item = itemAt(m_dragMovementPosition); + bool isFolder = dynamic_cast(item); + bool isBookmark = dynamic_cast(item); + + // Find the place for the arrow + QRect rect = visualItemRect(item); + int xCoord = rtol ? rect.right() : rect.left(); + int yCoord; + if (isFolder) { + if (m_dragMovementPosition.y() > rect.bottom() - (2* rect.height() / 3) ) { + yCoord = rect.bottom() - halfPixHeight; // bottom + xCoord = rtol ? (xCoord - indentation()) : (xCoord + indentation()); + } + else { + yCoord = rect.top() - halfPixHeight - 1; // top + } + + } + else { + if (isBookmark) { + if (m_dragMovementPosition.y() > rect.bottom() - rect.height() / 2) { + yCoord = rect.bottom() - halfPixHeight; // bottom + } + else { + yCoord = rect.top() - halfPixHeight - 1; // top + } + } + else { + if (item) { // the extra item + yCoord = rect.top() - halfPixHeight - 1; + } + else { // empty area + rect = visualItemRect(m_extraItem); + yCoord = rect.top() - halfPixHeight - 1; + xCoord = rtol ? rect.right() : rect.left(); + } + } + } + + painter.drawPixmap(xCoord, yCoord, pix); + } +} + + +void CBookmarkIndex::dropEvent( QDropEvent* event ) { + qDebug() << "CBookmarkIndex::dropEvent"; + + //setState(QAbstractItemView::NoState); + // Try to prevent annoying timed autocollapsing. Remember to disconnect before return. + QObject::connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); + QTreeWidgetItem* item = itemAt(event->pos()); + QTreeWidgetItem* parentItem = 0; + int indexUnderParent = 0; + + // Find the place where the drag is dropped + if (item) { + qDebug() << "there was item"; + + QRect rect = visualItemRect(item); + bool isFolder = dynamic_cast(item); + bool isBookmark = dynamic_cast(item); + + if (isFolder) { // item is a folder + qDebug() << "item was folder"; + if (event->pos().y() > rect.bottom() - (2* rect.height() / 3) ) { + parentItem = item; + } + else { + parentItem = item->parent(); + if (!parentItem) { + parentItem = invisibleRootItem(); + } + qDebug() << "item:" << item << "parent:" << parentItem; + indexUnderParent = parentItem->indexOfChild(item); // before the current folder + } + } + else { + if (isBookmark) { // item is a bookmark + qDebug() << "item was bookmark"; + parentItem = item->parent(); + if (!parentItem) { + parentItem = invisibleRootItem(); + } + indexUnderParent = parentItem->indexOfChild(item); // before the current bookmark + if (event->pos().y() > rect.bottom() - rect.height() / 2) { + indexUnderParent++; // after the current bookmark + } + } + else { // item is the extra item + parentItem = item->parent(); + if (!parentItem) { + parentItem = invisibleRootItem(); + } + indexUnderParent = parentItem->indexOfChild(item); // before the current bookmark + } + } + + } + else { // no item under event point: drop to the end + qDebug() << "there was no item"; + parentItem = invisibleRootItem(); + indexUnderParent = parentItem->childCount() - 1; + } + + + if ( event->source() == this ) { + qDebug() << "dropping internal drag"; + event->accept(); + + bool bookmarksOnly = true; + bool targetIncluded = false; + bool moreThanOneFolder = false; + + QList newItems = addItemsToDropTree(parentItem, bookmarksOnly, targetIncluded, moreThanOneFolder); + + if (moreThanOneFolder) { + QToolTip::showText(QCursor::pos(), tr("Can drop only bookmarks or one folder")); + QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); + return; + } + if (targetIncluded) { + QToolTip::showText(QCursor::pos(), tr("Can't drop folder into the folder itself or into its subfolder")); + QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); + return; + } + // Ask whether to copy or move with a popup menu + + QMenu* dropPopupMenu = new QMenu(this); + QAction* copy = dropPopupMenu->addAction(tr("Copy")); + QAction* move = dropPopupMenu->addAction(tr("Move")); + QAction* dropAction = dropPopupMenu->exec(QCursor::pos()); + if (dropAction == copy) { + qDebug() << "copy"; + parentItem->insertChildren(indexUnderParent, newItems); + // Need this here because the "move" case goes through + // "deleteEntries" which has a save call. + needToSaveBookmarks(); + } + else { + if (dropAction == move) { + qDebug() << "move"; + parentItem->insertChildren(indexUnderParent, newItems); + deleteEntries(false); + } + else { + QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), + this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); + return; // user canceled + } + } + } + else { + qDebug() << "the source was outside this"; + createBookmarkFromDrop(event, parentItem, indexUnderParent); + } + QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); + setState(QAbstractItemView::NoState); +} + + +void CBookmarkIndex::createBookmarkFromDrop(QDropEvent* event, QTreeWidgetItem* parentItem, int indexInParent) { + //qDebug() << "CBookmarkIndex::createBookmarkFromDrop"; + //take the bookmark data from the mime source + const BTMimeData* mdata = dynamic_cast(event->mimeData()); + if (mdata) { + //create the new bookmark + QString moduleName = mdata->bookmark().module(); + QString keyText = mdata->bookmark().key(); + QString description = mdata->bookmark().description(); + CSwordModuleInfo *minfo = CSwordBackend::instance()->findModuleByName(moduleName); + QString title; // TODO + + QTreeWidgetItem* newItem = new BtBookmarkItem(minfo, keyText, description, title); + // connect(newItem, SIGNAL(bookmarkModified()), this, SLOT(needToSaveBookmarks()) ); + parentItem->insertChild(indexInParent, newItem); + + qDebug() << "Saving in...CBookmarkIndex::createBookmarkFromDrop"; + needToSaveBookmarks(); + } +} + + +/** Load the tree from file */ +void CBookmarkIndex::initTree() { + qDebug() << "CBookmarkIndex::initTree"; + BtBookmarkLoader loader; + addTopLevelItems(loader.loadTree()); + + // add the invisible extra item at the end + m_extraItem = new QTreeWidgetItem(); + m_extraItem->setFlags(Qt::ItemIsDropEnabled); + addTopLevelItem(m_extraItem); +} + +void CBookmarkIndex::slotItemEntered(QTreeWidgetItem* item, int) { + qDebug() << "CBookmarkIndex::slotItemEntered"; + if (item == m_extraItem) { + m_extraItem->setText(0, tr("Drag references from text views to this view")); + } + else { + m_extraItem->setText(0, QString::null); + } +} + + +/** Returns the correct QAction object for the given type of action. */ +QAction* CBookmarkIndex::action( BtBookmarkItemBase::MenuAction type ) const { + switch (type) { + case BtBookmarkItemBase::NewFolder: + return m_actions.newFolder; + case BtBookmarkItemBase::ChangeFolder: + return m_actions.changeFolder; + + case BtBookmarkItemBase::EditBookmark: + return m_actions.editBookmark; + case BtBookmarkItemBase::SortFolderBookmarks: + return m_actions.sortFolderBookmarks; + case BtBookmarkItemBase::SortAllBookmarks: + return m_actions.sortAllBookmarks; + case BtBookmarkItemBase::ImportBookmarks: + return m_actions.importBookmarks; + case BtBookmarkItemBase::ExportBookmarks: + return m_actions.exportBookmarks; + case BtBookmarkItemBase::PrintBookmarks: + return m_actions.printBookmarks; + + case BtBookmarkItemBase::DeleteEntries: + return m_actions.deleteEntries; + + default: + return 0; + } +} + +/** Shows the context menu at the given position. */ +void CBookmarkIndex::contextMenu(const QPoint& p) { + //qDebug() << "CBookmarkIndex::contextMenu"; + //setup menu entries depending on current selection + QTreeWidgetItem* i = itemAt(p); + QList items = selectedItems(); + //The item which was clicked may not be selected + if (i && !items.contains(i) && i != m_extraItem) + items.append(i); + + if (items.count() == 0) { + //special handling for no selection + BtBookmarkItemBase::MenuAction actionType; + for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { + actionType = static_cast(index); + if (QAction* a = action(actionType)) { + switch (index) { + //case BtBookmarkItemBase::ExportBookmarks: + //case BtBookmarkItemBase::ImportBookmarks: + case BtBookmarkItemBase::NewFolder: + case BtBookmarkItemBase::SortAllBookmarks: + //case BtBookmarkItemBase::PrintBookmarks: + a->setEnabled(true); + break; + default: + a->setEnabled(false); + } + } + } + } + else if (items.count() == 1) { + //special handling for one selected item + + BtBookmarkItemBase* item = dynamic_cast(items.at(0)); + BtBookmarkItemBase::MenuAction actionType; + for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { + actionType = static_cast(index); + if (QAction* a = action(actionType)) + a->setEnabled( item->enableAction(actionType) ); + } + } + else { + //first disable all actions + BtBookmarkItemBase::MenuAction actionType; + for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { + actionType = static_cast(index); + if (QAction* a = action(actionType)) + a->setEnabled(false); + } + //enable the menu items depending on the types of the selected items. + for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { + actionType = static_cast(index); + bool enableAction = isMultiAction(actionType); + QListIterator it(items); + while (it.hasNext()) { + BtBookmarkItemBase* i = dynamic_cast(it.next()); + enableAction = enableAction && i->enableAction(actionType); + } + if (enableAction) { + QAction* a = action(actionType) ; + if (i && a) + a->setEnabled(enableAction); + } + } + } + //finally, open the popup + m_popup->exec(mapToGlobal(p)); + //qDebug() << "CBookmarkIndex::contextMenu end"; +} + +/** Adds a new subfolder to the current item. */ +void CBookmarkIndex::createNewFolder() { + //qDebug() << "CBookmarkIndex::createNewFolder"; + QList selected = selectedItems(); + if (selected.count() > 0) { + BtBookmarkFolder* i = dynamic_cast(currentItem()); + if (i) { + i->newSubFolder(); + } + } + else { + // create a top level folder + BtBookmarkFolder* newFolder = new BtBookmarkFolder(tr("New folder")); + //parentFolder->addChild(newFolder); + insertTopLevelItem(topLevelItemCount() - 1, newFolder); + newFolder->update(); + newFolder->rename(); + } + needToSaveBookmarks(); +} + +/** Opens a dialog to change the current folder. */ +void CBookmarkIndex::changeFolder() { + BtBookmarkFolder* i = dynamic_cast(currentItem()); + Q_ASSERT(i); + if (i) { + i->rename(); + } +} + +/** Edits the current bookmark. */ +void CBookmarkIndex::editBookmark() { + BtBookmarkItem* i = dynamic_cast(currentItem()); + Q_ASSERT(i); + + if (i) { + i->rename(); + } +} + +/** Sorts the current folder bookmarks. */ +void CBookmarkIndex::sortFolderBookmarks() { + BtBookmarkFolder* i = dynamic_cast(currentItem()); + Q_ASSERT(i); + + if (i) { + i->sortChildren(0, Qt::AscendingOrder); + } +} + +/** Sorts all bookmarks. */ +void CBookmarkIndex::sortAllBookmarks() { + sortItems(0, Qt::AscendingOrder); + int index = indexOfTopLevelItem(m_extraItem); + if (index >= 0) { + QTreeWidgetItem* item = takeTopLevelItem(index); + if (item != 0) { + addTopLevelItem(m_extraItem); + } + } +} + +/** Exports the bookmarks being in the selected folder. */ +void CBookmarkIndex::exportBookmarks() { + BtBookmarkFolder* i = dynamic_cast(currentItem()); + Q_ASSERT(i); + + if (i) { + i->exportBookmarks(); + } +} + +/** Import bookmarks from a file and add them to the selected folder. */ +void CBookmarkIndex::importBookmarks() { + BtBookmarkFolder* i = dynamic_cast(currentItem()); + Q_ASSERT(i); + + if (i) { + i->importBookmarks(); + } + needToSaveBookmarks(); +} + +/** Prints the selected bookmarks. */ +void CBookmarkIndex::printBookmarks() { + Printing::CPrinter::KeyTree tree; + Printing::CPrinter::KeyTreeItem::Settings settings; + settings.keyRenderingFace = Printing::CPrinter::KeyTreeItem::Settings::CompleteShort; + + QList items; + BtBookmarkFolder* bf = dynamic_cast(currentItem()); + + if (bf) { + items = bf->getChildList(); + } + else { + items = selectedItems(); + } + + //create a tree of keytreeitems using the bookmark hierarchy. + QListIterator it(items); + while (it.hasNext()) { + BtBookmarkItem* i = dynamic_cast(it.next()); + if (i) { + qDebug() << "printBookmarks: add to list" << i->key(); + tree.append( new Printing::CPrinter::KeyTreeItem( i->key(), i->module(), settings ) ); + } + } + + if (items.count() == 0) { + qWarning("Tried to print empty bookmark list."); + return; + } + QSharedPointer printer( + new Printing::CPrinter( this, CBTConfig::getDisplayOptionDefaults(), CBTConfig::getFilterOptionDefaults() ) + ); + printer->printKeyTree(tree); +} + +/** Deletes the selected entries. */ +void CBookmarkIndex::deleteEntries(bool confirm) { + if (confirm) { + if (!selectedItems().count()) { + BtBookmarkItemBase* f = dynamic_cast(currentItem()); + if (f) { + currentItem()->setSelected(true); + } + else { + return; + } + } + + if (util::showQuestion(this, tr("Delete Items"), + tr("Do you really want to delete the selected items and child-items?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) + != QMessageBox::Yes) { + return; + } + } + + while (selectedItems().size() > 0) { + delete selectedItems().at(0); // deleting all does not work because it may cause double deletion + } + // Save the bookmarks. One way would be to signal that the bookmarks have + // changed emit a signal so that a number of changes may be saved at once. + // Another way is to simply save the bookmarks after each change, which can + // be inefficient. + needToSaveBookmarks(); +} + + +/* +Reimplementation from QAbstractItemView/QTreeWidget. Takes care of movable items. +It's easier to use this than to start drag with mouse event handlers. +The default implementation would drag items, but we don't call it. Instead we create +a BibleTime mimedata object. It can be dragged and dropped to a text view or somewhere else. +The internal drag is handled differently, it doesn't use the mimedata (see dropEvent()). +*/ +void CBookmarkIndex::startDrag(Qt::DropActions) { + qDebug() << "CBookmarkIndex::startDrag"; + + QMimeData* mData = dragObject(); // create the data which can be used in other widgets + QDrag* drag = new QDrag(this); + drag->setMimeData(mData); + drag->exec(); + + viewport()->update(); // because of the arrow +} + + + + + + +/* Returns true if more than one entry is supported by this action type. Returns false for actions which support only one entry, e.g. about module etc. */ +bool CBookmarkIndex::isMultiAction( const BtBookmarkItemBase::MenuAction type ) const { + switch (type) { + case BtBookmarkItemBase::NewFolder: + return false; + case BtBookmarkItemBase::ChangeFolder: + return false; + + case BtBookmarkItemBase::EditBookmark: + return false; + case BtBookmarkItemBase::SortFolderBookmarks: + return false; + case BtBookmarkItemBase::SortAllBookmarks: + return false; + case BtBookmarkItemBase::ImportBookmarks: + return false; + case BtBookmarkItemBase::ExportBookmarks: + return false; + case BtBookmarkItemBase::PrintBookmarks: + return true; + + case BtBookmarkItemBase::DeleteEntries: + return true; + } + + return false; +} + +/* Saves the bookmarks to the default bookmarks file. */ +void CBookmarkIndex::saveBookmarks() { + + qDebug() << "CBookmarkIndex::saveBookmarks()"; + BtBookmarkLoader loader; + loader.saveTreeFromRootItem(invisibleRootItem()); +} + +void CBookmarkIndex::mouseMoveEvent(QMouseEvent* event) { + //qDebug() << "CBookmarkIndex::mouseMoveEvent"; + + // Restart the mag timer if we have moved to another item and shift was not pressed. + QTreeWidgetItem* itemUnderPointer = itemAt(event->pos()); + if (itemUnderPointer && (itemUnderPointer != m_previousEventItem) ) { + //qDebug() << "CBookmarkIndex::mouseMoveEvent, moved onto another item"; + if ( !(event->modifiers() & Qt::ShiftModifier)) { + m_magTimer.start(); // see the ctor for the timer properties + } + } + m_previousEventItem = itemUnderPointer; + + // Clear the extra item text unless we are on top of it + if ( (itemUnderPointer != m_extraItem) && !m_extraItem->text(0).isNull()) { + m_extraItem->setText(0, QString::null); + } + + QTreeWidget::mouseMoveEvent(event); +} + +void CBookmarkIndex::magTimeout() { + //qDebug() << "CBookmarkIndex::magTimeout"; + + QTreeWidgetItem* itemUnderPointer = 0; + if (underMouse()) { + itemUnderPointer = itemAt(mapFromGlobal(QCursor::pos())); + } + // if the mouse pointer have been over the same item since the timer was started + if (itemUnderPointer && (m_previousEventItem == itemUnderPointer)) { + BtBookmarkItem* bitem = dynamic_cast(itemUnderPointer); + if (bitem) { + //qDebug() << "CBookmarkIndex::timerEvent: update the infodisplay"; + // Update the mag + if (bitem->module()) { + (BibleTime::instance()->infoDisplay())->setInfo( + InfoDisplay::CInfoDisplay::CrossReference, + bitem->module()->name() + ":" + bitem->key() + ); + } + else { + (BibleTime::instance()->infoDisplay())->setInfo(InfoDisplay::CInfoDisplay::Text, tr("The work to which the bookmark points to is not installed.")); + } + + } + } +} + +/* +Creates a list of new items based on the current selection. +If there are only bookmarks in the selection they are all included. +If there is one folder it's included as a deep copy. +Sets bookmarksOnly=false if it finds a folder. +Sets targetIncluded=true if the target is in the list. +Sets moreThanOneFolder=true if selection includes one folder and something more. +If moreThanOneFolder or targetIncluded is detected the creation of list is stopped +and the list is incomplete. +*/ +QList CBookmarkIndex::addItemsToDropTree( + QTreeWidgetItem* target, bool& bookmarksOnly, bool& targetIncluded, bool& moreThanOneFolder) { + qDebug() << "CBookmarkIndex::addItemsToDropTree"; + QList selectedList = selectedItems(); + QList newList; + + foreach(QTreeWidgetItem* item, selectedList) { + qDebug() << "go through all items:" << item; + if ( BtBookmarkFolder* folder = dynamic_cast(item)) { + bookmarksOnly = false; + if (selectedList.count() > 1) { // only one item allowed if a folder is selected + qDebug() << "one folder and something else is selected"; + moreThanOneFolder = true; + break; + } + if (folder->hasDescendant(target)) { // dropping to self or descendand not allowed + qDebug() << "addItemsToDropTree: target is included"; + targetIncluded = true; + break; + } + } + else { + qDebug() << "append new QTreeWidget item (should be BtBookmarkItem?)"; + newList.append(new BtBookmarkItem( *(dynamic_cast(item)) )); + } + } + if (!bookmarksOnly && selectedList.count() == 1) { + qDebug() << "exactly one folder"; + BtBookmarkFolder* folder = dynamic_cast(selectedList.value(0)); + BtBookmarkFolder* copy = folder->deepCopy(); + newList.append(copy); + } + if (!bookmarksOnly && selectedList.count() > 1) { + // wrong amount of items + qDebug() << "one folder and something else is selected 2"; + moreThanOneFolder = true; + } + qDebug() << "return the new list" << newList; + return newList; +} + +/// Bookmark saving code. To avoid many saves during a short period of time, +/// bookmark modification is first noted. Then, after a wait (1.5s), if no more +/// modifications are made, the bookmarks are saved. The timer is reset when a +/// new modification is made. The timer bookmarkSaveTimer is set to be oneshot. +void CBookmarkIndex::needToSaveBookmarks() { + qDebug() << "Got signal to save bookmarks!"; + m_bookmarksModified = true; + bookmarkSaveTimer.start(1500); // Only save after 1.5s. +} +void CBookmarkIndex::needToSaveBookmarks(QTreeWidgetItem* treeItem) { + // Need to test whether the item that changed is not just a display item, + // but actually a folder or bookmark. + BtBookmarkItemBase* bookmark = dynamic_cast(treeItem); + if (bookmark) { + qDebug() << "Got signal to save bookmarks!"; + m_bookmarksModified = true; + bookmarkSaveTimer.start(1500); // Only save after 1.5s. + } +} + +/// Considers saving bookmarks only if they have been modified. This procedure +/// should be called by the qtimer bookmarkTimer. +void CBookmarkIndex::considerSavingBookmarks() { + qDebug() << "Considering to save bookmarks!"; + if (m_bookmarksModified) { + saveBookmarks(); + m_bookmarksModified = false; + } +} + diff --git a/src/frontend/bookmarks/cbookmarkindex.h b/src/frontend/bookmarks/cbookmarkindex.h new file mode 100644 index 0000000..2875a5d --- /dev/null +++ b/src/frontend/bookmarks/cbookmarkindex.h @@ -0,0 +1,214 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef CBOOKMARKINDEX_H +#define CBOOKMARKINDEX_H + +#include "frontend/bookmarks/btbookmarkitembase.h" + +#include +#include +#include +#include +#include +#include "frontend/displaywindow/cdisplaywindow.h" + + +class BTMimeData; +class CSearchDialog; +class CSwordModuleInfo; +class QAction; +class QDragLeaveEvent; +class QDragMoveEvent; +class QDropEvent; +class QMenu; +class QMouseEvent; +class QPaintEvent; +class QWidget; + +/** +* The widget which manages all bookmarks. +* @author The BibleTime team +*/ +class CBookmarkIndex : public QTreeWidget { + Q_OBJECT + public: + CBookmarkIndex(QWidget *parent); + virtual ~CBookmarkIndex(); + + void initTree(); + + /** + * Saves the bookmarks to disk + */ + void saveBookmarks(); + + signals: + /** + * Is emitted when a module should be opened, + */ + void createReadDisplayWindow( QList, const QString& ); + + public slots: + + /** + * Indicates a need to save the bookmarks. + * This is needed to provide a way for a bookmarkitem stored in the + * treeWidget to inform us that it has been modified, namely its + * description text. It only sets a dirty-bit so we don't execute many + * consecutive saves. + */ + void needToSaveBookmarks(); + void needToSaveBookmarks(QTreeWidgetItem* treeItem); + + + protected: // Protected methods + + /** A hack to get the modifiers. */ + virtual void mouseReleaseEvent(QMouseEvent* event); + + /** Needed to paint an drag pointer arrow. */ + virtual void paintEvent(QPaintEvent* event); + + /** Initialize the SIGNAL<->SLOT connections. */ + void initConnections(); + + /** Returns the drag object for the current selection. */ + virtual QMimeData* dragObject(); + + /** + * D'n'd methods are reimplementations from QTreeWidget or its ancestors. + * In these we handle creating, moving and copying bookmarks with d'n'd. + */ + virtual void dragEnterEvent( QDragEnterEvent* event ); + virtual void dragMoveEvent( QDragMoveEvent* event ); + virtual void dropEvent( QDropEvent* event ); + virtual void dragLeaveEvent( QDragLeaveEvent* event ); + + /** Returns the correct action object for the given type of action. */ + QAction* action( BtBookmarkItemBase::MenuAction type ) const; + + /** Reimplementation from QAbstractItemView. Takes care of movable items. */ + virtual void startDrag(Qt::DropActions supportedActions); + + + /** Handle mouse moving (mag updates) */ + virtual void mouseMoveEvent(QMouseEvent* event); + + + protected slots: + + /** Prevents annoying folder collapsing while dropping. */ + void expandAutoCollapsedItem(QTreeWidgetItem* i) { + expandItem(i); + } + + /** Is called when an item was clicked or activated. */ + void slotExecuted( QTreeWidgetItem* ); + + /** Shows the context menu at the given position. */ + void contextMenu(const QPoint&); + + /** Adds a new subfolder to the current item. */ + void createNewFolder(); + + /** Opens a dialog to change the current folder. */ + void changeFolder(); + + /** Exports the bookmarks from the selected folder. */ + void exportBookmarks(); + + /** Changes the current bookmark. */ + void editBookmark(); + + /** Sorts the current folder bookmarks. */ + void sortFolderBookmarks(); + + /** Sorts all bookmarks. */ + void sortAllBookmarks(); + + /** Helps with the extra item. */ + void slotItemEntered(QTreeWidgetItem*, int); + + /** Import bookmarks from a file and add them to the selected folder. */ + void importBookmarks(); + + /** Deletes the selected entries. */ + void deleteEntries(bool confirm = true); + + /** Prints the selected bookmarks. */ + void printBookmarks(); + + /** Slot for the mag update timer. */ + void magTimeout(); + + private: + + /** Initializes the view. */ + void initView(); + + /** Convenience function for creating a new action. */ + QAction* newQAction(const QString& text, const QString& pix, int shortcut, const QObject* receiver, const char* slot, QObject* parent); + + /** + * Returns true if more than one entry is supported by this action type. + * Returns false for actions which support only one entry. + */ + bool isMultiAction( const BtBookmarkItemBase::MenuAction type ) const; + + /** A helper function for d'n'd which creates a new bookmark item when drop happens. */ + void createBookmarkFromDrop(QDropEvent* event, QTreeWidgetItem* parentItem, int indexInParent); + + /** + * Returns a list of new items created from the selection. + * Sets flags which indicate whether the selection was legal for dropping. + */ + QList addItemsToDropTree(QTreeWidgetItem* target, bool& bookmarksOnly, bool& targetIncluded, bool& moreThanOneFolder); + + struct Actions { + QAction* newFolder; + QAction* changeFolder; + + QAction* editBookmark; + QAction* sortFolderBookmarks; + QAction* sortAllBookmarks; + QAction* importBookmarks; + QAction* exportBookmarks; + QAction* printBookmarks; + + QAction* deleteEntries; + } + m_actions; + + QMenu* m_popup; + QTimer m_magTimer; + int m_mouseReleaseEventModifiers; + QTreeWidgetItem* m_previousEventItem; + QPoint m_dragMovementPosition; + QPoint m_dragStartPosition; + QTreeWidgetItem* m_extraItem; + + // The following is for managing saving bookmarks. It uses a QTimer to + // determine whether the bookmarks should be saved. This may seem like + // a hassle, but it is to prevent many saves from being executed at a + // time. + + /** Flag indicating that bookmarks have been modified. */ + bool m_bookmarksModified; + QTimer bookmarkSaveTimer; + + private slots: + /** + * Saves the bookmarks. + * It checks m_bookmarksModified and resets it at the end. It should be + * connected to a timer that periodically calls this. */ + void considerSavingBookmarks(); +}; + +#endif diff --git a/src/frontend/bookshelfmanager/btconfigdialog.cpp b/src/frontend/bookshelfmanager/btconfigdialog.cpp index 565765d..3d02388 100644 --- a/src/frontend/bookshelfmanager/btconfigdialog.cpp +++ b/src/frontend/bookshelfmanager/btconfigdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,8 +20,6 @@ #include #include #include -#include "util/directory.h" -#include "util/tool.h" BtConfigDialog::BtConfigDialog(QWidget* parent) @@ -44,14 +42,6 @@ BtConfigDialog::BtConfigDialog(QWidget* parent) m_pageLayout->addWidget(m_pageWidget); - // Horizontal line - QFrame* line = new QFrame(); - line->setGeometry(QRect(1, 1, 1, 3)); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - line->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - m_pageLayout->addWidget(line); - connect(m_contentsList, SIGNAL(currentRowChanged(int)), this, SLOT(slotChangePage(int)) @@ -62,22 +52,14 @@ BtConfigDialog::BtConfigDialog(QWidget* parent) BtConfigDialog::~BtConfigDialog() {} void BtConfigDialog::addPage(BtConfigPage* pageWidget) { - namespace DU = util::directory; - // this is a friend pageWidget->m_parentDialog = this; - QVBoxLayout* containerLayout = new QVBoxLayout; - QLabel* headerLabel = util::tool::explanationLabel(pageWidget, pageWidget->header(), pageWidget->label()); - containerLayout->addWidget(headerLabel); - containerLayout->addWidget(pageWidget); - QWidget* containerWidget = new QWidget(m_pageWidget); - containerWidget->setLayout(containerLayout); - m_pageWidget->addWidget(containerWidget); + m_pageWidget->addWidget(pageWidget); QListWidgetItem* item = new QListWidgetItem(m_contentsList); - item->setIcon(DU::getIcon(pageWidget->iconName())); + item->setIcon(pageWidget->icon()); item->setText(pageWidget->header()); item->setTextAlignment(Qt::AlignHCenter); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); @@ -96,11 +78,16 @@ void BtConfigDialog::addPage(BtConfigPage* pageWidget) { } void BtConfigDialog::addButtonBox(QDialogButtonBox* box) { - m_pageLayout->addWidget(box); -} + // First add a horizontal ruler: + QFrame *line = new QFrame(); + line->setGeometry(QRect(1, 1, 1, 3)); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + line->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_pageLayout->addWidget(line); -BtConfigPage* BtConfigDialog::currentPage() { - return dynamic_cast(m_pageWidget->currentWidget()); + // Add button box: + m_pageLayout->addWidget(box); } void BtConfigDialog::slotChangePage(int newIndex) { @@ -113,6 +100,13 @@ void BtConfigDialog::slotChangePage(int newIndex) { -BtConfigPage::BtConfigPage() {} +BtConfigPage::BtConfigPage(QWidget *parent) + : QWidget(parent) + , m_parentDialog(0) +{ + setLayout(new QVBoxLayout); +} -BtConfigPage::~BtConfigPage() {} +BtConfigPage::~BtConfigPage() { + // Intentionally empty +} diff --git a/src/frontend/bookshelfmanager/btconfigdialog.h b/src/frontend/bookshelfmanager/btconfigdialog.h index 547cb4e..dce22ab 100644 --- a/src/frontend/bookshelfmanager/btconfigdialog.h +++ b/src/frontend/bookshelfmanager/btconfigdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,10 +17,11 @@ class BtConfigPage; -class QListWidgetItem; +class QDialogButtonBox; +class QLabel; class QListWidget; +class QListWidgetItem; class QStackedWidget; -class QDialogButtonBox; class QVBoxLayout; /** @@ -34,7 +35,7 @@ class QVBoxLayout; class BtConfigDialog : public QDialog { Q_OBJECT public: - BtConfigDialog(QWidget* parent); + BtConfigDialog(QWidget *parent = 0); virtual ~BtConfigDialog(); /** Adds a BtConfigPage to the paged widget stack. The new page will be the current page.*/ @@ -42,9 +43,6 @@ class BtConfigDialog : public QDialog { /** Adds a button box to the lower edge of the dialog. */ void addButtonBox(QDialogButtonBox* buttonBox); - /** Returns the currently selected page. */ - BtConfigPage* currentPage(); - public slots: /** Changes the current page using the given index number. */ void slotChangePage(int newIndex); @@ -64,24 +62,29 @@ class BtConfigDialog : public QDialog { */ class BtConfigPage : public QWidget { Q_OBJECT + friend class BtConfigDialog; + public: - BtConfigPage(); + /** + Constructs a configuration dialog base, with QVBoxLayout as layout() and a header + label as the first widget in this layout. + \param[in] parent The parent widget. + */ + BtConfigPage(QWidget *parent = 0); virtual ~BtConfigPage(); /** Implement these to return the correct values. * For example: header(){return tr("General");} */ - virtual QString iconName() = 0; - virtual QString label() = 0; - virtual QString header() = 0; - BtConfigDialog* parentDialog() { + virtual const QIcon &icon() const = 0; + virtual QString header() const = 0; + + inline BtConfigDialog *parentDialog() const { return m_parentDialog; } private: - friend class BtConfigDialog; - BtConfigDialog* m_parentDialog; - + BtConfigDialog *m_parentDialog; }; diff --git a/src/frontend/bookshelfmanager/btinstallmgr.cpp b/src/frontend/bookshelfmanager/btinstallmgr.cpp index ace804f..756fcae 100644 --- a/src/frontend/bookshelfmanager/btinstallmgr.cpp +++ b/src/frontend/bookshelfmanager/btinstallmgr.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,7 +10,7 @@ #include "frontend/bookshelfmanager/btinstallmgr.h" #include "backend/managers/cswordbackend.h" -#include "frontend/bookshelfmanager/instbackend.h" +#include "backend/btinstallbackend.h" #include #include #include @@ -25,8 +25,9 @@ using namespace sword; BtInstallMgr::BtInstallMgr() - : InstallMgr(instbackend::configPath().toLatin1(), this), - m_firstCallOfPreStatus(true) { //use this class also as status reporter + : InstallMgr(BtInstallBackend::configPath().toLatin1(), this), + m_totalBytes(1), m_completedBytes(0), m_firstCallOfPreStatus(true) +{ //use this class also as status reporter qDebug() << "BtInstallMgr::BtInstallMgr"; this->setFTPPassive(true); } diff --git a/src/frontend/bookshelfmanager/btinstallmgr.h b/src/frontend/bookshelfmanager/btinstallmgr.h index 7eff1ae..7d39440 100644 --- a/src/frontend/bookshelfmanager/btinstallmgr.h +++ b/src/frontend/bookshelfmanager/btinstallmgr.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,53 +21,42 @@ #include -class CSwordBackend; - -typedef QList InstallSourceList; - /** * Our own reimplementation to provide installation and status bar updates. */ class BtInstallMgr : public QObject, public sword::InstallMgr, public sword::StatusReporter { Q_OBJECT public: - BtInstallMgr(); - virtual ~BtInstallMgr(); - - /** - * Refreshing the source should be cancellable (othewise it might freeze the app if there is - * for example something wrong with the network). - */ - void slotRefreshCanceled(); + ~BtInstallMgr(); /** Re-implemented from sword::InstallMgr. */ - virtual bool isUserDisclaimerConfirmed() const; + bool isUserDisclaimerConfirmed() const; + + signals: + /** Download status. Percent of total and file.*/ + void percentCompleted(const int total, const int file); + void downloadStarted(); protected: - /* Reimplementations of methods in StatusReporter */ /** - * Gets the total and current file status, emits the signal with those values as percents. + Reimplementation of sword::StatusReporter::statusUpdate(). */ - virtual void statusUpdate(double dltotal, double dlnow); + void statusUpdate(double dltotal, double dlnow); + /** + * Reimplementation of sword::StatusReporter::preStatus(). + * \warning This method is not always called before statusUpdate(). * Called before starting to download each file of the module package. * The sword message is not i18n'ed, it's in the form "Downloading (1 of 6): nt.bzs". * This function is not utilized in the UI ATM. */ - virtual void preStatus(long totalBytes, long completedBytes, const char *message); + void preStatus(long totalBytes, long completedBytes, const char *message); + private: long m_totalBytes; long m_completedBytes; - - private: bool m_firstCallOfPreStatus; - - signals: - /** Download status. Percent of total and file.*/ - void percentCompleted( const int, const int); - void downloadStarted(); }; - #endif diff --git a/src/frontend/bookshelfmanager/btmodulemanagerdialog.cpp b/src/frontend/bookshelfmanager/btmodulemanagerdialog.cpp index b261305..f0547b8 100644 --- a/src/frontend/bookshelfmanager/btmodulemanagerdialog.cpp +++ b/src/frontend/bookshelfmanager/btmodulemanagerdialog.cpp @@ -2,21 +2,18 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/bookshelfmanager/btmodulemanagerdialog.h" -#include #include "backend/config/cbtconfig.h" #include "backend/managers/cswordbackend.h" #include "frontend/bookshelfmanager/indexpage/btindexpage.h" #include "frontend/bookshelfmanager/installpage/btinstallpage.h" #include "frontend/bookshelfmanager/removepage/btremovepage.h" -#include "util/cpointers.h" -#include "util/dialogutil.h" static BtModuleManagerDialog *m_staticModuleManagerDialog = 0; @@ -48,13 +45,6 @@ BtModuleManagerDialog::BtModuleManagerDialog(QWidget* parent) slotChangePage(0); - // Dialog button (Close) - QDialogButtonBox* bbox = new QDialogButtonBox(this); - bbox->addButton(QDialogButtonBox::Close); - util::prepareDialogBox(bbox); - addButtonBox(bbox); - connect(bbox, SIGNAL(rejected()), SLOT(close())); - loadDialogSettings(); } diff --git a/src/frontend/bookshelfmanager/btmodulemanagerdialog.h b/src/frontend/bookshelfmanager/btmodulemanagerdialog.h index c51efd2..0392cc2 100644 --- a/src/frontend/bookshelfmanager/btmodulemanagerdialog.h +++ b/src/frontend/bookshelfmanager/btmodulemanagerdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -44,7 +44,7 @@ class BtModuleManagerDialog : public BtConfigDialog { //signals: -// void swordSetupChanged(); +// void swordSetupChanged(); }; diff --git a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.cpp b/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.cpp index e326641..14aecb9 100644 --- a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.cpp +++ b/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h" -#include +#include #include #include #include @@ -25,7 +25,7 @@ #include #include #include -#include "frontend/bookshelfmanager/instbackend.h" +#include "backend/btinstallbackend.h" #include "util/dialogutil.h" const QString PROTO_FILE( QObject::tr("Local") ); //Local path @@ -102,11 +102,10 @@ void CSwordSetupInstallSourcesDialog::slotOk() { //BTInstallMgr iMgr; //sword::InstallSource is = BTInstallMgr::Tool::RemoteConfig::source( &iMgr, m_captionEdit->text() ); - sword::InstallSource is = instbackend::source(m_captionEdit->text()); + sword::InstallSource is = BtInstallBackend::source(m_captionEdit->text()); if ( (QString)is.caption.c_str() == m_captionEdit->text() ) { //source already exists util::showInformation( this, tr( "Error" ), - /** \bug Double space in the following string: */ - tr("A source with this caption already exists. Please provide a different caption.")); + tr("A source with this caption already exists. Please provide a different caption.")); return; } @@ -177,17 +176,15 @@ void CSwordSetupInstallSourcesDialog::slotGetListClicked() { qApp->processEvents(); qWarning() << "Start downloading the list of sources"; int ret = iMgr.refreshRemoteSourceConfiguration(); - bool success = false; + if ( !ret ) { //make sure the sources were updated sucessfully qDebug() << "download succeeded"; - success = true; m_progressDialog->setValue(100); //make sure the dialog closes m_remoteListAdded = true; accept(); } else { qWarning("InstallMgr: getting remote list returned an error."); - success = false; } delete m_progressDialog; m_progressDialog = 0; diff --git a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h b/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h index 12df221..e69e9a9 100644 --- a/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h +++ b/src/frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp b/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp index 984700c..026aad5 100644 --- a/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp +++ b/src/frontend/bookshelfmanager/indexpage/btindexpage.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -19,20 +19,20 @@ #include "backend/config/cbtconfig.h" #include "backend/drivers/cswordmoduleinfo.h" #include "backend/managers/cswordbackend.h" -#include "frontend/cmoduleindexdialog.h" +#include "frontend/btmoduleindexdialog.h" #include "util/directory.h" -#include "util/cpointers.h" #include "util/cresmgr.h" #include "util/tool.h" -BtIndexPage::BtIndexPage() - : BtConfigPage() { +BtIndexPage::BtIndexPage(QWidget *parent) + : BtConfigPage(parent) +{ namespace DU = util::directory; - QVBoxLayout *vboxLayout; + Q_ASSERT(qobject_cast(layout()) != 0); + QVBoxLayout *vboxLayout = static_cast(layout()); QHBoxLayout *hboxLayout; - vboxLayout = new QVBoxLayout(this); m_autoDeleteOrphanedIndicesBox = new QCheckBox(this); m_autoDeleteOrphanedIndicesBox->setToolTip(tr("If selected, those indexes which have no corresponding work will be deleted when BibleTime starts")); @@ -75,22 +75,20 @@ BtIndexPage::BtIndexPage() // connect our signals/slots connect(m_createButton, SIGNAL(clicked()), this, SLOT(createIndices())); connect(m_deleteButton, SIGNAL(clicked()), this, SLOT(deleteIndices())); - connect(CPointers::backend(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), SLOT(slotSwordSetupChanged())); + connect(CSwordBackend::instance(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), SLOT(slotSwordSetupChanged())); populateModuleList(); } BtIndexPage::~BtIndexPage() { CBTConfig::set( CBTConfig::autoDeleteOrphanedIndices, m_autoDeleteOrphanedIndicesBox->isChecked() ); - -} -QString BtIndexPage::label() { - return tr("Create new search indexes and delete created indexes for the installed works."); } -QString BtIndexPage::iconName() { - return CResMgr::bookshelfmgr::indexpage::icon; + +const QIcon &BtIndexPage::icon() const { + return util::directory::getIcon(CResMgr::bookshelfmgr::indexpage::icon); } -QString BtIndexPage::header() { + +QString BtIndexPage::header() const { return tr("Search Indexes"); } @@ -114,7 +112,7 @@ void BtIndexPage::populateModuleList() { - const QList &modules(CPointers::backend()->moduleList()); + const QList &modules(CSwordBackend::instance()->moduleList()); for (MLCI it(modules.begin()); it != modules.end(); ++it) { QTreeWidgetItem* item = 0; @@ -138,11 +136,11 @@ void BtIndexPage::populateModuleList() { /** Creates indices for selected modules if no index currently exists */ void BtIndexPage::createIndices() { bool indicesCreated = false; - QList moduleList; + QList moduleList; for (int i = 0; i < m_modsWithoutIndices->childCount(); i++) { if (m_modsWithoutIndices->child(i)->checkState(0) == Qt::Checked) { - CSwordModuleInfo* module = CPointers::backend()->findModuleByName(m_modsWithoutIndices->child(i)->text(0).toUtf8()); + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(m_modsWithoutIndices->child(i)->text(0).toUtf8()); if (module) { moduleList.append( module ); indicesCreated = true; @@ -152,7 +150,7 @@ void BtIndexPage::createIndices() { //Shows the progress dialog if (indicesCreated) { - CModuleIndexDialog::getInstance()->indexAllModules( moduleList ); + BtModuleIndexDialog::indexAllModules(moduleList); populateModuleList(); } } @@ -163,7 +161,7 @@ void BtIndexPage::deleteIndices() { for (int i = 0; i < m_modsWithIndices->childCount(); i++) { if (m_modsWithIndices->child(i)->checkState(0) == Qt::Checked) { - CSwordModuleInfo* module = CPointers::backend()->findModuleByName(m_modsWithIndices->child(i)->text(0).toUtf8()); + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(m_modsWithIndices->child(i)->text(0).toUtf8()); if (module) { module->deleteIndex(); indicesDeleted = true; @@ -177,27 +175,6 @@ void BtIndexPage::deleteIndices() { } } -void BtIndexPage::deleteOrphanedIndices() { - QDir dir(CSwordModuleInfo::getGlobalBaseIndexLocation()); - dir.setFilter(QDir::Dirs); - CSwordModuleInfo* module; - - for (unsigned int i = 0; i < dir.count(); i++) { - if (dir[i] != "." && dir[i] != "..") { - if ( (module = CPointers::backend()->findModuleByName(dir[i])) ) { //mod exists - if (!module->hasIndex()) { //index files found, but wrong version etc. - CSwordModuleInfo::deleteIndexForModule( dir[i] ); - } - } - else { //no module exists - if (CBTConfig::get( CBTConfig::autoDeleteOrphanedIndices ) ) { - CSwordModuleInfo::deleteIndexForModule( dir[i] ); - } - } - } - } -} - void BtIndexPage::slotSwordSetupChanged() { populateModuleList(); } diff --git a/src/frontend/bookshelfmanager/indexpage/btindexpage.h b/src/frontend/bookshelfmanager/indexpage/btindexpage.h index 795cc0b..89a7e35 100644 --- a/src/frontend/bookshelfmanager/indexpage/btindexpage.h +++ b/src/frontend/bookshelfmanager/indexpage/btindexpage.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,20 +26,14 @@ class BtIndexPage : public BtConfigPage { Q_OBJECT public: - /** - * Constructor - */ - BtIndexPage(); - - /** - * Destructor - */ + BtIndexPage(QWidget *parent = 0); ~BtIndexPage(); - // BtConfigPage methods - QString header(); - QString iconName(); - QString label(); + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; + + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; public slots: void slotSwordSetupChanged(); @@ -63,13 +57,6 @@ class BtIndexPage : public BtConfigPage { */ void deleteIndices(); - public: - /** - * Deletes orphaned indices if the autoDeleteOrphanedIndices is true - * Always deletes indices of existing modules where hasIndex() returns false - */ - static void deleteOrphanedIndices(); - private: QCheckBox *m_autoDeleteOrphanedIndicesBox; diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp index 8fd87ec..01ca55b 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp +++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp @@ -1,127 +1,83 @@ /********* * +* In the name of the Father, and of the Son, and of the Holy Spirit. +* * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. * **********/ #include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h" -#include -#include -#include -#include -#include -#include -#include -#include "backend/btmoduletreeitem.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "frontend/cmodulechooserdialog.h" +#include +#include +#include +#include "backend/bookshelfmodel/btbookshelffiltermodel.h" +#include "frontend/btbookshelfview.h" +#include "util/tool.h" -BtInstallModuleChooserDialog::BtInstallModuleChooserDialog(QWidget* parent, QString title, QString label, QList* empty) - : CModuleChooserDialog(parent, title, label, empty) { - qDebug() << "BtInstallModuleChooserDialog::BtInstallModuleChooserDialog start"; - init(); - okButton()->setText(tr("Install")); - m_nameList = QStringList(); +namespace { +const QString groupingOrderKey("GUI/BookshelfManager/InstallConfirmDialog/grouping"); } -// Do nothing, the tree is initialized outside this class. -void BtInstallModuleChooserDialog::initModuleItem(BTModuleTreeItem*, QTreeWidgetItem*) {} - -void BtInstallModuleChooserDialog::initModuleItem(QString name, QTreeWidgetItem* sourceItem) { - /// \todo Use new bookshelf model instead - /// \bug Valgrind reports memory leak: - QTreeWidgetItem* moduleItem = new QTreeWidgetItem(sourceItem); - moduleItem->setText(0, name); - moduleItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - moduleItem->setCheckState(0, Qt::Checked); +BtInstallModuleChooserDialog::BtInstallModuleChooserDialog(const BtBookshelfTreeModel::Grouping &g, + QWidget *parent, + Qt::WindowFlags flags) + : BtModuleChooserDialog(parent, flags), m_shown(false) +{ + resize(550, 340); - // prevent double items - if (m_nameList.contains(name)) { - qDebug() << "item already in list:" << name; - //moduleItem->setCheckState(0, Qt::Unchecked); - QBrush bg(Qt::red); - moduleItem->setBackground(0, bg); - //find and change the other offending items - foreach (QTreeWidgetItem* doubleItem, treeWidget()->findItems(name, Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0)) { - //doubleItem->setCheckState(0, Qt::Unchecked); - //qDebug() << "CInstallModuleChooserDialog::initModuleItem" << doubleItem; - doubleItem->setBackground(0, bg); - } - m_doubleCheckedModules[name] = true; - enableOk(false); + // Read grouping order from settings or the default from argument: + BtBookshelfTreeModel::Grouping groupingOrder(false); + if (!groupingOrder.loadFrom(groupingOrderKey)) { + groupingOrder = g; } - m_nameList << name; -} -void BtInstallModuleChooserDialog::slotItemChecked(QTreeWidgetItem* item, int column) { - QString moduleName = item->text(0); - qDebug() << "BtInstallModuleChooserDialog::slotItemChecked start"; - // handle only non-toplevel items which has duplicates and where the first column was changed - if (item->parent() && column == 0 && (findModuleItemsByName(moduleName).count() > 1)) { - //prevent handling when the color is changed - if (item->data(1, Qt::UserRole).toBool() == false) { - qDebug() << "was not updating"; - item->setData(1, Qt::UserRole, true); - } - else { - qDebug() << "was updating"; - item->setData(1, Qt::UserRole, false); - return; - } + BtInstallModuleChooserDialogModel *treeModel; + treeModel = new BtInstallModuleChooserDialogModel(groupingOrder, this); + connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); - QList doubleNameItems = findModuleItemsByName(moduleName); - QList doubleCheckedItems; - foreach (QTreeWidgetItem* nItem, doubleNameItems) { - if (nItem->checkState(0) == Qt::Checked) { - doubleCheckedItems << nItem; - } - } + m_bookshelfModel = new BtBookshelfModel(this); + bookshelfWidget()->postFilterModel()->setShowShown(true); + bookshelfWidget()->setTreeModel(treeModel); + bookshelfWidget()->setSourceModel(m_bookshelfModel); + bookshelfWidget()->showHideAction()->setVisible(false); + bookshelfWidget()->showHideButton()->hide(); + bookshelfWidget()->treeView()->header()->show(); - if (doubleCheckedItems.count() > 1) { - enableOk(false); - // color the items - qDebug() << "there were more than 1 item of the name" << moduleName; - foreach (QTreeWidgetItem* i, doubleNameItems) { - QBrush bg(Qt::red); - i->setBackground(0, bg); - } - m_doubleCheckedModules[moduleName] = true; - } - else if (doubleCheckedItems.count() == 1) { - qDebug() << "there were 1 checked items of the name" << moduleName; - // uncolor the items - foreach (QTreeWidgetItem* i, doubleNameItems) { - i->setBackground(0, i->parent()->background(0)); - } - m_doubleCheckedModules.remove(moduleName); - if (m_doubleCheckedModules.count() == 0) { - enableOk(true); - } - } - } + retranslateUi(); } -QList BtInstallModuleChooserDialog::findModuleItemsByName(QString name) { - qDebug() << "BtInstallModuleChooserDialog::findModuleItemsByName:" << name << treeWidget()->topLevelItemCount(); - QList doubleNamedAllItems = treeWidget()->findItems(name, Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive); - //qDebug() << "doubleNamedAllItems: " << doubleNamedAllItems.count(); - QList doubleNamedModuleItems; - foreach (QTreeWidgetItem* item, doubleNamedAllItems) { - //qDebug() << "item:" << item; - if (item->parent()) { - doubleNamedModuleItems << item; - } - } - //qDebug() << "module items:" << doubleNamedModuleItems.count(); - return doubleNamedModuleItems; +void BtInstallModuleChooserDialog::addModuleItem(CSwordModuleInfo *module, + const QString &sourceName) +{ + module->setProperty("installSourceName", sourceName); + m_bookshelfModel->addModule(module); +} + +void BtInstallModuleChooserDialog::retranslateUi() { + setWindowTitle(tr("Install/Update works?")); + util::tool::initExplanationLabel( + label(), QString::null, + tr("Do you really want to install these works?") + "

" + + tr("Only one version of a work can be installed at the same time. Select only " + "one if there are items marked with red.") + ""); +} + +void BtInstallModuleChooserDialog::showEvent(QShowEvent *event) { + Q_UNUSED(event); + + if (m_shown) return; + bookshelfWidget()->treeView()->expandAll(); + bookshelfWidget()->treeView()->header()->resizeSections(QHeaderView::ResizeToContents); + m_shown = true; } -void BtInstallModuleChooserDialog::enableOk(bool enabled) { - qDebug() << "BtInstallModuleChooserDialog::enableOk" << enabled; - okButton()->setEnabled(enabled); +void BtInstallModuleChooserDialog::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) { + g.saveTo(groupingOrderKey); } diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h index 06144ff..070df6f 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h +++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h @@ -1,51 +1,55 @@ /********* * +* In the name of the Father, and of the Son, and of the Holy Spirit. +* * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. * **********/ #ifndef BTINSTALLMODULECHOOSERDIALOG_H #define BTINSTALLMODULECHOOSERDIALOG_H -#include "frontend/cmodulechooserdialog.h" +#include "frontend/btmodulechooserdialog.h" -#include -#include -#include -#include +#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h" -class BTModuleTreeItem; -class QWidget; -class QTreeWidgetItem; +class BtBookshelfModel; +class BtInstallModuleChooserDialogModel; +class CSwordModuleInfo; /** * Confirmation dialog for installation. Lets the user * uncheck modules from the list. */ -class BtInstallModuleChooserDialog : public CModuleChooserDialog { - Q_OBJECT - +class BtInstallModuleChooserDialog: public BtModuleChooserDialog { + Q_OBJECT public: - BtInstallModuleChooserDialog(QWidget* parent, QString title, QString label, QList* empty); + BtInstallModuleChooserDialog(const BtBookshelfTreeModel::Grouping &g, + QWidget *parent = 0, + Qt::WindowFlags flags = 0); - void initModuleItem(QString name, QTreeWidgetItem* sourceItem); - void enableOk(bool enabled); + inline const QSet &checkedModules() const { + return bookshelfWidget()->treeModel()->checkedModules(); + } - public slots: - void slotItemChecked(QTreeWidgetItem* item, int column); + void addModuleItem(CSwordModuleInfo *module, const QString &sourceName); protected: - virtual void initModuleItem(BTModuleTreeItem*, QTreeWidgetItem*); + void retranslateUi(); + void showEvent(QShowEvent *event); + + protected slots: + void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); - QList findModuleItemsByName(QString name); private: - QStringList m_nameList; - QMap m_doubleCheckedModules; + BtBookshelfModel *m_bookshelfModel; + bool m_shown; }; -#endif +#endif // BTINSTALLMODULECHOOSERDIALOG_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp new file mode 100644 index 0000000..880ea6a --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp @@ -0,0 +1,136 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h" + +#include +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/cswordbackend.h" + + +#define MODULEPOINTERFORINDEX(i) static_cast(\ + BtBookshelfTreeModel::data((i), BtBookshelfModel::ModulePointerRole).value()) + +BtInstallModuleChooserDialogModel::BtInstallModuleChooserDialogModel( + const Grouping &grouping, + QObject *parent) + : BtBookshelfTreeModel(grouping, parent), m_dataChangedFired(false) +{ + setDefaultChecked(BtBookshelfTreeModel::CHECKED); + setCheckable(true); + connect(this, SIGNAL(dataChanged(QModelIndex,QModelIndex)), + this, SLOT(parentDataChanged(QModelIndex,QModelIndex)), + Qt::DirectConnection); +} + +BtInstallModuleChooserDialogModel::~BtInstallModuleChooserDialogModel() { + // Intentionally empty +} + +QVariant BtInstallModuleChooserDialogModel::data(const QModelIndex &i, int role) const { + switch (role) { + case Qt::BackgroundRole: + if (isMulti(i)) return QBrush(Qt::red); + return BtBookshelfTreeModel::data(i, role); + case Qt::ForegroundRole: + if (isMulti(i)) return QBrush(Qt::white); + return BtBookshelfTreeModel::data(i, role); + case Qt::DisplayRole: + switch (i.column()) { + case 0: + return BtBookshelfTreeModel::data(i, role); + case 1: + { + CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); + if (module != 0) return module->property("installSourceName"); + break; + } + case 2: + { + CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); + if (module == 0) break; + CSwordBackend *b = CSwordBackend::instance(); + CSwordModuleInfo *imodule = b->findModuleByName(module->name()); + if (imodule == 0) { + return module->config(CSwordModuleInfo::ModuleVersion); + } else { + return imodule->config(CSwordModuleInfo::ModuleVersion) + + " => " + + module->config(CSwordModuleInfo::ModuleVersion); + } + } + default: break; + } + default: + if (i.column() == 0) return BtBookshelfTreeModel::data(i, role); + } + + return QVariant(); +} + +int BtInstallModuleChooserDialogModel::columnCount(const QModelIndex &parent) const { + Q_UNUSED(parent); + + return 3; +} + +QVariant BtInstallModuleChooserDialogModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case 0: return tr("Work"); + case 1: return tr("Installation source"); + case 2: return tr("Version"); + default: break; + } + } + + return QVariant(); +} + +void BtInstallModuleChooserDialogModel::parentDataChanged(const QModelIndex &topLeft, + const QModelIndex &bottomRight) +{ + Q_UNUSED(topLeft); + Q_UNUSED(bottomRight); + + if (m_dataChangedFired) return; + m_dataChangedFired = true; + resetData(); + m_dataChangedFired = false; +} + +bool BtInstallModuleChooserDialogModel::isMulti(CSwordModuleInfo *m1) const { + if (m1 != 0 && checkedModules().contains(m1)) { + Q_FOREACH(CSwordModuleInfo *m2, m_modules.keys()) { + if (m1 != m2 && checkedModules().contains(m2) && m1->name() == m2->name()) { + return true; + } + } + } + return false; +} + +bool BtInstallModuleChooserDialogModel::isMulti(const QModelIndex &i) const { + if (!i.isValid()) return false; + + if (!hasChildren(i)) { + return isMulti(MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent()))); + } else { + for (int row = 0; row < rowCount(i); row++) { + if (isMulti(i.child(row, 0))) return true; + } + } + return false; +} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h new file mode 100644 index 0000000..6120fa8 --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h @@ -0,0 +1,44 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTINSTALLMODULECHOOSERDIALOGMODEL_H +#define BTINSTALLMODULECHOOSERDIALOGMODEL_H + +#include "backend/bookshelfmodel/btbookshelftreemodel.h" + +#include + + +class BtInstallModuleChooserDialogModel: public BtBookshelfTreeModel { + Q_OBJECT + public: + BtInstallModuleChooserDialogModel(const Grouping &grouping, QObject *parent = 0); + ~BtInstallModuleChooserDialogModel(); + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + private slots: + void parentDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + + private: + bool isMulti(CSwordModuleInfo *module) const; + bool isMulti(const QModelIndex &index) const; + + private: + QMap m_nameCounts; + bool m_dataChangedFired; +}; + +#endif // BTINSTALLMODULECHOOSERDIALOGMODEL_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp index b71599a..d3bac59 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp +++ b/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp @@ -2,63 +2,60 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/bookshelfmanager/installpage/btinstallpage.h" -#include #include -#include #include -#include -#include +#include #include #include #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include -#include -#include #include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" -#include "frontend/bookshelfmanager/btconfigdialog.h" -#include "frontend/bookshelfmanager/btinstallmgr.h" +#include "backend/btinstallbackend.h" #include "frontend/bookshelfmanager/btmodulemanagerdialog.h" #include "frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h" +#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h" +#include "frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h" #include "frontend/bookshelfmanager/installpage/btinstallpathdialog.h" #include "frontend/bookshelfmanager/installpage/btinstallprogressdialog.h" -#include "frontend/bookshelfmanager/installpage/btsourcewidget.h" -#include "frontend/bookshelfmanager/installpage/btsourcearea.h" -#include "frontend/bookshelfmanager/instbackend.h" -#include "frontend/cmodulechooserdialog.h" -#include "util/directory.h" -#include "util/cpointers.h" +#include "frontend/btbookshelfview.h" #include "util/cresmgr.h" +#include "util/dialogutil.h" +#include "util/directory.h" +#include "util/tool.h" + -// Sword includes: -#include +namespace { +const QString groupingOrderKey ("GUI/BookshelfManager/InstallPage/grouping"); +const QString headerStateKey ("GUI/BookshelfManager/InstallPage/headerState"); +const QString selectedModuleKey("GUI/BookshelfManager/InstallPage/selectedModule"); +} // anonymous namespace // ********************************************************* // *********** Config dialog page: Install/Update ********** // ********************************************************* -BtInstallPage::BtInstallPage() - : BtConfigPage() { - qDebug() << "BtInstallPage::BtInstallPage() start"; +BtInstallPage::BtInstallPage(QWidget *parent) + : BtConfigPage(parent) + , m_groupingOrder(groupingOrderKey) + , m_modulesSelected(0) + , m_modulesSelectedSources(0) +{ + // Read settings: + m_headerState = CBTConfig::getConfig()->value(headerStateKey).toByteArray(); + + // Initialize widgets: initView(); initConnections(); } @@ -75,68 +72,105 @@ QString BtInstallPage::selectedInstallPath() { void BtInstallPage::initView() { namespace DU = util::directory; - qDebug() << "void BtInstallPage::initView() start"; - QVBoxLayout *mainLayout = new QVBoxLayout(this); - - // installation path chooser - QHBoxLayout* pathLayout = new QHBoxLayout(); - // beautify the layout - int top; - int bottom; - int left; - int right; - pathLayout->getContentsMargins(&left, &top, &right, &bottom); - pathLayout->setContentsMargins(left, top + 7, right, bottom + 7 ); - QLabel* pathLabel = new QLabel(tr("Install folder:")); - m_pathCombo = new QComboBox(); + // Warning label: + + m_warningLabel = util::tool::explanationLabel(this, tr("WARNING!!!"), + tr("If you live in a persecuted country and don't want to risk " + "detection don't use remote sources.")); + + // Source chooser: + m_sourceGroupBox = new QGroupBox(tr("Select installation &source:"), this); + m_sourceGroupBox->setFlat(true); + + m_sourceComboBox = new QComboBox(this); + m_sourceComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + initSourcesCombo(); + + m_sourceAddButton = new QPushButton(tr("&Add...")); + m_sourceAddButton ->setToolTip(tr("Add new source")); + m_sourceAddButton ->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::add_icon)); + + m_sourceDeleteButton = new QPushButton(tr("&Delete...")); + m_sourceDeleteButton->setToolTip(tr("Delete this source")); + m_sourceDeleteButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::delete_icon)); + + QHBoxLayout *sourceChooserLayout = new QHBoxLayout(); + sourceChooserLayout->setContentsMargins(0, 0, 0, 0); + sourceChooserLayout->addWidget(m_sourceComboBox, 1); + sourceChooserLayout->addWidget(m_sourceAddButton); + sourceChooserLayout->addWidget(m_sourceDeleteButton); + m_sourceGroupBox->setLayout(sourceChooserLayout); + + // Works chooser: + m_worksGroupBox = new QGroupBox(tr("Select &works to install:"), this); + m_worksGroupBox->setFlat(true); + m_worksLayout = new QStackedLayout(); + m_worksGroupBox->setLayout(m_worksLayout); + slotSourceIndexChanged(m_sourceComboBox->currentIndex()); + + // Installation path chooser: + m_installGroupBox = new QGroupBox(this); + m_installGroupBox->setFlat(true); + retranslateInstallGroupBox(); + + m_pathLabel = new QLabel(tr("Install &folder:")); + m_pathCombo = new QComboBox(this); m_pathCombo->setMinimumContentsLength(20); m_pathCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); m_pathCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); m_pathCombo->setToolTip(tr("The folder where the new works will be installed")); m_pathCombo->view()->setTextElideMode(Qt::ElideMiddle); - initPathCombo(); // set the paths and the current path + m_pathLabel->setBuddy(m_pathCombo); + initPathCombo(); + m_configurePathButton = new QToolButton(this); m_configurePathButton->setToolTip(tr("Configure folders where works are installed and found")); m_configurePathButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::path_icon)); - pathLayout->addWidget(pathLabel); - pathLayout->addWidget(m_pathCombo); - pathLayout->addWidget(m_configurePathButton); - mainLayout->addLayout(pathLayout); - - // Source widget - m_sourceWidget = new BtSourceWidget(this); - mainLayout->addWidget(m_sourceWidget); - // Install button - QHBoxLayout *installButtonLayout = new QHBoxLayout(); - installButtonLayout->setContentsMargins(0, 5, 0, 5); - QSpacerItem *installButtonSpacer = new QSpacerItem(371, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - installButtonLayout->addItem(installButtonSpacer); - m_installButton = new QPushButton(tr("Install..."), this); + m_installButton = new QPushButton(tr("&Install..."), this); m_installButton->setToolTip(tr("Install or update selected works")); m_installButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::install_icon)); m_installButton->setEnabled(false); - installButtonLayout->addWidget(m_installButton); - mainLayout->addLayout(installButtonLayout); + QHBoxLayout *pathLayout = new QHBoxLayout(); + pathLayout->setContentsMargins(0, 0, 0, 0); + pathLayout->addWidget(m_pathLabel); + pathLayout->addWidget(m_pathCombo); + pathLayout->addWidget(m_configurePathButton); + pathLayout->addWidget(m_installButton); + m_installGroupBox->setLayout(pathLayout); + + Q_ASSERT(qobject_cast(layout()) != 0); + QVBoxLayout *mainLayout = static_cast(layout()); + mainLayout->addWidget(m_warningLabel); + mainLayout->addWidget(m_sourceGroupBox); + mainLayout->addWidget(m_worksGroupBox, 1); + mainLayout->addWidget(m_installGroupBox); } void BtInstallPage::initConnections() { - qDebug() << "void BtInstallPage::initConnections() start"; - QObject::connect(m_pathCombo, SIGNAL(activated(const QString&)), this , SLOT(slotPathChanged(const QString&))); - QObject::connect(m_configurePathButton, SIGNAL(clicked()), this, SLOT(slotEditPaths())); - QObject::connect(m_installButton, SIGNAL(clicked()), m_sourceWidget, SLOT(slotInstall()) ); - - QObject::connect(CPointers::backend(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), this, SLOT(slotSwordSetupChanged())); - //source widget has its own connections, not here + connect(m_sourceComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(slotSourceIndexChanged(int))); + connect(m_sourceAddButton, SIGNAL(clicked()), + this, SLOT(slotSourceAdd())); + connect(m_sourceDeleteButton, SIGNAL(clicked()), + this, SLOT(slotSourceDelete())); + connect(m_installButton, SIGNAL(clicked()), + this, SLOT(slotInstall())); + connect(m_pathCombo, SIGNAL(activated(const QString&)), + this , SLOT(slotPathChanged(const QString&))); + connect(m_configurePathButton, SIGNAL(clicked()), + this, SLOT(slotEditPaths())); + connect(CSwordBackend::instance(), + SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), + this, SLOT(slotSwordSetupChanged())); } void BtInstallPage::initPathCombo() { - qDebug() << "void BtInstallPage::initPathCombo() start"; //populate the combo list m_pathCombo->clear(); - QStringList targets = instbackend::targetList(); + QStringList targets = BtInstallBackend::targetList(); for (QStringList::iterator it = targets.begin(); it != targets.end(); ++it) { // Add the path only if it's writable if ((*it).isEmpty()) continue; @@ -154,43 +188,252 @@ void BtInstallPage::initPathCombo() { m_pathCombo->setCurrentIndex(index); } +void BtInstallPage::initSourcesCombo() { + /// \todo Implement a proper model for this + + m_sourceComboBox->clear(); + QStringList sourceList = BtInstallBackend::sourceNameList(); + + // Add a default entry, the Crosswire main repository + if (sourceList.empty()) { + /// \todo Open a dialog which asks whether to get list from server and add sources + sword::InstallSource is("FTP"); //default return value + is.caption = "CrossWire Bible Society"; + is.source = "ftp.crosswire.org"; + is.directory = "/pub/sword/raw"; + // passive ftp is not needed here, it's the default + + BtInstallBackend::addSource(is); + + sourceList = BtInstallBackend::sourceNameList(); + Q_ASSERT(!sourceList.empty()); + } + + // Read selected module from config: + QString selected = CBTConfig::getConfig()->value(selectedModuleKey).toString(); + + // Populate combo box + bool selectionOk = false; + for (int i = 0; i < sourceList.size(); i++) { + m_sourceComboBox->addItem(sourceList.at(i)); + + // Select configured item: + if (!selectionOk && sourceList.at(i) == selected) { + m_sourceComboBox->setCurrentIndex(i); + selectionOk = true; + } + } + + // Set selection, if it wasn't properly configured: + if (!selectionOk) { + m_sourceComboBox->setCurrentIndex(0); + CBTConfig::getConfig()->setValue(selectedModuleKey, sourceList.at(0)); + } +} + +void BtInstallPage::activateSource(const sword::InstallSource &src) { + qDebug() << "Selected source" << src.caption; + qApp->setOverrideCursor(Qt::WaitCursor); + BtInstallPageWorksWidget *w = m_sourceMap.value(QString(src.caption), 0); + if (w == 0) { + if (parentDialog() != 0) parentDialog()->setEnabled(false); + qApp->processEvents(); + w = new BtInstallPageWorksWidget(src, m_groupingOrder, this); + m_sourceMap.insert(QString(src.caption), w); + m_worksLayout->addWidget(w); + connect(w->treeModel(), SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); + connect(w->treeModel(), SIGNAL(moduleChecked(CSwordModuleInfo*,bool)), + this, SLOT(slotSelectedModulesChanged())); + if (parentDialog() != 0) parentDialog()->setEnabled(true); + } else { + disconnect(w->treeView()->header(), SIGNAL(geometriesChanged()), + this, SLOT(slotHeaderChanged())); + } + m_worksLayout->setCurrentWidget(w); + w->treeModel()->setGroupingOrder(m_groupingOrder); + w->treeView()->header()->restoreState(m_headerState); + connect(w->treeView()->header(), SIGNAL(geometriesChanged()), + this, SLOT(slotHeaderChanged())); + qApp->restoreOverrideCursor(); +} + +void BtInstallPage::retranslateInstallGroupBox() { + if (m_modulesSelected > 0) { + m_installGroupBox->setTitle(tr("Start installation of %1 works from %2 sources:") + .arg(m_modulesSelected) + .arg(m_modulesSelectedSources)); + } else { + m_installGroupBox->setTitle(tr("Start installation:")); + } +} + +void BtInstallPage::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) { + m_groupingOrder = g; + m_groupingOrder.saveTo(groupingOrderKey); +} + +void BtInstallPage::slotHeaderChanged() { + typedef BtInstallPageWorksWidget IPWW; + Q_ASSERT(qobject_cast(m_worksLayout->currentWidget()) != 0); + IPWW *w = static_cast(m_worksLayout->currentWidget()); + m_headerState = w->treeView()->header()->saveState(); + CBTConfig::getConfig()->setValue(headerStateKey, m_headerState); +} + +void BtInstallPage::slotInstall() { + qDebug() << "BtInstallPage::slotInstall"; + + // check that the destination path is writable, do nothing if not and user doesn't want to continue + QDir dir = selectedInstallPath(); + bool canWrite = true; + if (dir.isReadable()) { + const QFileInfo fi( dir.canonicalPath() ); + if (!fi.exists() || !fi.isWritable()) { + canWrite = false; + } + } + else { + canWrite = false; + } + if (!canWrite) { + const int result = util::showWarning(this, tr("Warning"), tr("The destination directory is not writable or does not exist. Installation will fail unless this has first been fixed."), QMessageBox::Ignore | QMessageBox::Cancel, QMessageBox::Cancel); + if (result != QMessageBox::Ignore) { + return; + } + } + + // create the confirmation dialog + BtInstallModuleChooserDialog *dlg = new BtInstallModuleChooserDialog(m_groupingOrder, this); + + // Add all checked modules from all tabs: + Q_FOREACH (BtInstallPageWorksWidget *w, m_sourceMap.values()) { + Q_FOREACH (CSwordModuleInfo *module, w->treeModel()->checkedModules()) { + dlg->addModuleItem(module, QString(w->installSource().caption)); + } + } + + if (dlg->exec() == QDialog::Accepted) { + QSet cm; + Q_FOREACH(const CSwordModuleInfo *m, dlg->checkedModules()) { + cm.insert(m); + } + + if (cm.empty()) return; + + /// \todo first remove all modules which will be updated from the module list + // but what modules? all with the same real name? (there may be _n modules...) + + BtModuleManagerDialog *parentDlg = dynamic_cast(parentDialog()); + + BtInstallProgressDialog *dlg = new BtInstallProgressDialog(cm, selectedInstallPath(), parentDlg); + + if (!parentDlg) qDebug() << "error, wrong parent!"; + + m_installButton->setEnabled(false); + + // the progress dialog is now modal, it can be made modeless later. + dlg->exec(); + + qDebug() << "BtSourceWidget::slotInstallAccepted end"; + } + delete dlg; +} + void BtInstallPage::slotPathChanged(const QString& /*pathText*/) { CBTConfig::set(CBTConfig::installPathIndex, m_pathCombo->currentIndex( ) ); } void BtInstallPage::slotEditPaths() { - qDebug() << "void BtInstallPage::slotEditPaths() start"; - BtInstallPathDialog* dlg = new BtInstallPathDialog(); int result = dlg->exec(); if (result == QDialog::Accepted) { //dynamic_cast(parentDialog())->slotSwordSetupChanged(); - CPointers::backend()->reloadModules(CSwordBackend::PathChanged); + CSwordBackend::instance()->reloadModules(CSwordBackend::PathChanged); } } -// implement the BtConfigPage methods +void BtInstallPage::slotSourceAdd() { + typedef CSwordSetupInstallSourcesDialog SSISD; -QString BtInstallPage::iconName() { - return CResMgr::bookshelfmgr::installpage::icon; + QSharedPointer dlg(new SSISD()); + if (dlg->exec() == QDialog::Accepted) { + if (!dlg->wasRemoteListAdded()) { + sword::InstallSource newSource = dlg->getSource(); + if ( !((QString)newSource.type.c_str()).isEmpty() ) { // we have a valid source to add + BtInstallBackend::addSource(newSource); + } + initSourcesCombo(); + for (int i = 0; i < m_sourceComboBox->count(); i++) { + if (m_sourceComboBox->itemText(i) == newSource.caption) { + m_sourceComboBox->setCurrentIndex(i); + break; + } + } + } + } } -QString BtInstallPage::label() { - // \todo move the warning to a dialog which is shown when adding a source. - return tr("Install and update works. Add remote or local sources, refresh them, select the works to be installed/updated and click Install.
WARNING: If you live in a persecuted country and don't want to risk detection don't use remote sources."); + +void BtInstallPage::slotSourceDelete() { + typedef BtInstallPageWorksWidget IPWW; + + int ret = util::showWarning(this, tr("Delete Source?"), + tr("Do you really want to delete this source?"), + QMessageBox::Yes | QMessageBox::No); + + if (ret == QMessageBox::Yes) { + Q_ASSERT(qobject_cast(m_worksLayout->currentWidget())); + IPWW *w = static_cast(m_worksLayout->currentWidget()); + w->deleteSource(); + initSourcesCombo(); + slotSourceIndexChanged(m_sourceComboBox->currentIndex()); + delete w; + } } -QString BtInstallPage::header() { - return tr("Install/Update"); + +void BtInstallPage::slotSourceIndexChanged(int index) { + if (index < 0) index = 0; + + /// \todo use pointers instead of text + QString moduleName = m_sourceComboBox->itemText(index); + CBTConfig::getConfig()->setValue(selectedModuleKey, moduleName); + activateSource(BtInstallBackend::source(moduleName)); } -void BtInstallPage::slotSwordSetupChanged() { - qDebug() << "BtInstallPage::slotSwordSetupChanged"; - initPathCombo(); -// for (int i = 0; i < m_sourceWidget->count(); i++ ) { -// BtSourceArea* sourceArea = dynamic_cast(m_sourceWidget->widget(i)); -// Q_ASSERT(sourceArea); -// sourceArea->createModuleTree(); -// } +void BtInstallPage::slotSelectedModulesChanged() { + m_modulesSelected = 0; + m_modulesSelectedSources = 0; + Q_FOREACH (BtInstallPageWorksWidget *w, m_sourceMap.values()) { + int selected = w->treeModel()->checkedModules().size(); + if (selected > 0) { + m_modulesSelectedSources++; + m_modulesSelected += selected; + } + } + + m_installButton->setEnabled(m_modulesSelected > 0); + retranslateInstallGroupBox(); +} + +// implement the BtConfigPage methods + +const QIcon &BtInstallPage::icon() const { + return util::directory::getIcon(CResMgr::bookshelfmgr::installpage::icon); } +QString BtInstallPage::header() const { + return tr("Install/Update"); +} +void BtInstallPage::slotSwordSetupChanged() { + QString moduleName = m_sourceComboBox->currentText(); + initSourcesCombo(); + qDeleteAll(m_sourceMap.values()); + m_sourceMap.clear(); + m_sourceComboBox->setCurrentIndex(m_sourceComboBox->findText(moduleName)); + initPathCombo(); + m_modulesSelected = 0; + m_modulesSelectedSources = 0; + retranslateInstallGroupBox(); +} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpage.h b/src/frontend/bookshelfmanager/installpage/btinstallpage.h index fde9919..88d1f92 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallpage.h +++ b/src/frontend/bookshelfmanager/installpage/btinstallpage.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,29 +12,34 @@ #include "frontend/bookshelfmanager/btconfigdialog.h" -#include +#include "backend/bookshelfmodel/btbookshelftreemodel.h" -// Sword includes: -#include +namespace sword { +class InstallSource; +} -class BtSourceWidget; +class BtInstallPageWorksWidget; class QComboBox; +class QGroupBox; class QPushButton; +class QStackedLayout; class QToolButton; /** * The Install page includes module path chooser, source/module handler and install button. */ -class BtInstallPage : public BtConfigPage { +class BtInstallPage: public BtConfigPage { Q_OBJECT + public: - BtInstallPage(); + BtInstallPage(QWidget *parent = 0); + + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; - // reimplemented from btinstallpage - QString iconName(); - QString label(); - QString header(); + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; void setInstallEnabled(bool b); @@ -47,18 +52,46 @@ class BtInstallPage : public BtConfigPage { void initView(); void initConnections(); void initPathCombo(); + void initSourcesCombo(); + + void activateSource(const sword::InstallSource &src); + void retranslateInstallGroupBox(); private slots: + void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); + void slotHeaderChanged(); + void slotInstall(); void slotPathChanged(const QString& pathText); void slotEditPaths(); + void slotSourceAdd(); + void slotSourceDelete(); + void slotSourceIndexChanged(int index); + void slotSelectedModulesChanged(); private: + BtBookshelfTreeModel::Grouping m_groupingOrder; + QByteArray m_headerState; + + QMap m_sourceMap; + + QLabel *m_warningLabel; + + QGroupBox *m_sourceGroupBox; + QComboBox *m_sourceComboBox; + QPushButton *m_sourceAddButton; + QPushButton *m_sourceDeleteButton; + + QGroupBox *m_worksGroupBox; + QStackedLayout *m_worksLayout; + + QGroupBox *m_installGroupBox; + QLabel *m_pathLabel; + QComboBox *m_pathCombo; + QToolButton *m_configurePathButton; + QPushButton *m_installButton; - QComboBox* m_pathCombo; - //QPushButton* m_configurePathButton; - QToolButton* m_configurePathButton; - BtSourceWidget* m_sourceWidget; - QPushButton* m_installButton; + unsigned m_modulesSelected; + unsigned m_modulesSelectedSources; }; #endif diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp new file mode 100644 index 0000000..9aa6743 --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp @@ -0,0 +1,87 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/bookshelfmanager/installpage/btinstallpagemodel.h" + + +#include "backend/drivers/cswordmoduleinfo.h" +#include "backend/managers/cswordbackend.h" + + +#define MODULEPOINTERFORINDEX(i) static_cast(\ + BtBookshelfTreeModel::data((i), BtBookshelfModel::ModulePointerRole).value()) + +BtInstallPageModel::BtInstallPageModel(const Grouping &grouping, QObject *parent) + : BtBookshelfTreeModel(grouping, parent) +{ + setDefaultChecked(BtBookshelfTreeModel::UNCHECKED); + setCheckable(true); +} + +BtInstallPageModel::~BtInstallPageModel() { + // Intentionally empty +} + +QVariant BtInstallPageModel::data(const QModelIndex &i, int role) const { + switch (role) { + case Qt::DisplayRole: + switch (i.column()) { + case 0: + return BtBookshelfTreeModel::data(i, role); + case 1: + { + CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); + if (module == 0) break; + CSwordBackend *b = CSwordBackend::instance(); + CSwordModuleInfo *imodule = b->findModuleByName(module->name()); + if (imodule == 0) { + return module->config(CSwordModuleInfo::ModuleVersion); + } else { + return imodule->config(CSwordModuleInfo::ModuleVersion) + + " => " + + module->config(CSwordModuleInfo::ModuleVersion); + } + } + case 2: + { + CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())); + if (module != 0) return module->config(CSwordModuleInfo::Description); + } + default: break; + } + default: + if (i.column() == 0) return BtBookshelfTreeModel::data(i, role); + } + + return QVariant(); +} + +int BtInstallPageModel::columnCount(const QModelIndex &parent) const { + Q_UNUSED(parent); + + return 3; +} + +QVariant BtInstallPageModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case 0: return tr("Work"); + case 1: return tr("Version"); + case 2: return tr("Description"); + default: break; + } + } + + return QVariant(); +} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h new file mode 100644 index 0000000..8a02409 --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h @@ -0,0 +1,33 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTINSTALLPAGEMODEL_H +#define BTINSTALLPAGEMODEL_H + +#include "backend/bookshelfmodel/btbookshelftreemodel.h" + +#include + + +class BtInstallPageModel: public BtBookshelfTreeModel { + Q_OBJECT + public: + BtInstallPageModel(const Grouping &grouping, QObject *parent = 0); + ~BtInstallPageModel(); + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; +}; + +#endif // BTINSTALLPAGEMODEL_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp new file mode 100644 index 0000000..6b9fb53 --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp @@ -0,0 +1,140 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h" + +#include +#include +#include +#include +#include +#include "backend/btinstallbackend.h" +#include "backend/managers/cswordbackend.h" +#include "frontend/bookshelfmanager/installpage/btinstallpage.h" +#include "frontend/bookshelfmanager/installpage/btinstallpagemodel.h" +#include "frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h" +#include "frontend/btbookshelfview.h" +#include "util/cresmgr.h" +#include "util/directory.h" + + +namespace { + +/** Filters out already installed modules which can't be updated right now. */ +bool filter(CSwordModuleInfo *mInfo) { + typedef CSwordModuleInfo CSMI; + typedef sword::SWVersion SV; + + const CSMI *installedModule = CSwordBackend::instance()->findModuleByName(mInfo->name()); + if (installedModule) { + // Already installed, check if it's an update: + const SV curVersion(installedModule->config(CSMI::ModuleVersion).toLatin1()); + const SV newVersion(mInfo->config(CSMI::ModuleVersion).toLatin1()); + if (curVersion >= newVersion) { + return false; + } + } + return true; +} + +} + +BtInstallPageWorksWidget::BtInstallPageWorksWidget( + const sword::InstallSource &source, + const BtBookshelfTreeModel::Grouping &g, + BtInstallPage *parent, Qt::WindowFlags flags) + : BtBookshelfWidget(parent, flags) + , m_source(source) + , m_parent(parent) + , m_backend(0) + , m_myModel(0) +{ + namespace DU = util::directory; + + qDebug() << "Creating new BtInstallPageWorksWidget for source" << source.caption; + + setTreeModel(new BtInstallPageModel(g, this)); + + treeView()->setHeaderHidden(false); + showHideButton()->hide(); + showHideAction()->setVisible(false); + + m_sourceRefreshButton = new QToolButton(this); + m_sourceRefreshButton->setAutoRaise(true); + m_sourceRefreshButton ->setToolTip(tr("Refresh the list of works from this source")); + m_sourceRefreshButton ->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::refresh_icon)); + setRightCornerWidget(m_sourceRefreshButton); + + connect(m_sourceRefreshButton, SIGNAL(clicked()), + this, SLOT(slotSourceRefresh())); + + // Delayed init, part 1 - disable parent: + parent->setEnabled(false); +} + +BtInstallPageWorksWidget::~BtInstallPageWorksWidget() { + qDebug() << "Deleting BtInstallPageWorksWidget for source" << m_source.caption; + + delete m_backend; +} + +void BtInstallPageWorksWidget::deleteSource() { + qDebug() << "Deleting source" << m_source.caption; + + setEnabled(false); + m_myModel->clear(); + BtInstallBackend::deleteSource(QString(m_source.caption)); +} + +void BtInstallPageWorksWidget::updateTree() { + qDebug() << "Updating BtInstallPageWorksWidget tree for source" << m_source.caption; + + m_myModel->clear(); + + // Is this necessary? + m_source = BtInstallBackend::source(QString(m_source.caption)); + m_backend = BtInstallBackend::backend(m_source); + + // Repopulate model: + Q_FOREACH(CSwordModuleInfo *module, m_backend->moduleList()) { + if (filter(module)) m_myModel->addModule(module); + } +} + +void BtInstallPageWorksWidget::paintEvent(QPaintEvent *e) { + // Delayed init, part 2 - queue init when painted: + if (m_myModel == 0) { + QTimer::singleShot(0, this, SLOT(slotDelayedInit())); + } + BtBookshelfWidget::paintEvent(e); +} + +void BtInstallPageWorksWidget::slotDelayedInit() { + // Delayed init, part 3 - initialize + reenable parent + qApp->setOverrideCursor(Qt::WaitCursor); + m_backend = BtInstallBackend::backend(m_source); + Q_ASSERT(m_backend != 0); + m_myModel = new BtBookshelfModel(this); + Q_FOREACH(CSwordModuleInfo *module, m_backend->moduleList()) { + if (filter(module)) m_myModel->addModule(module); + } + setSourceModel(m_myModel); + m_parent->setEnabled(true); + qApp->restoreOverrideCursor(); +} + +void BtInstallPageWorksWidget::slotSourceRefresh() { + qDebug() << "Refreshing source" << m_source.caption; + + if (BtInstallBackend::isRemote(m_source)) { + BtRefreshProgressDialog d(m_source, this); + if (!d.runAndDelete()) return; + } + updateTree(); +} diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h new file mode 100644 index 0000000..1a9bd8f --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h @@ -0,0 +1,59 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTINSTALLPAGEWORKSWIDGET_H +#define BTINSTALLPAGEWORKSWIDGET_H + + +#include "frontend/btbookshelfwidget.h" + +// Sword includes +#include + + +class BtInstallPage; + +class BtInstallPageWorksWidget: public BtBookshelfWidget { + Q_OBJECT + + public: /* Methods: */ + + BtInstallPageWorksWidget(const sword::InstallSource &source, + const BtBookshelfTreeModel::Grouping &g, + BtInstallPage *parent, Qt::WindowFlags f = 0); + + ~BtInstallPageWorksWidget(); + + inline const sword::InstallSource &installSource() const { + return m_source; + } + void deleteSource(); + + private: /* Methods: */ + + void updateTree(); + + /** Reimplemented from QWidget. */ + virtual void paintEvent(QPaintEvent *e); + + private slots: + + void slotDelayedInit(); + void slotSourceRefresh(); + + private: /* Fields: */ + + sword::InstallSource m_source; + BtInstallPage *m_parent; + QToolButton *m_sourceRefreshButton; + CSwordBackend *m_backend; + BtBookshelfModel *m_myModel; +}; + +#endif // BTINSTALLPAGEWORKSWIDGET_H diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp index 9efb9f0..a272d89 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp +++ b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,13 +15,12 @@ #include #include #include -#include #include #include #include #include #include -#include "frontend/bookshelfmanager/instbackend.h" +#include "backend/btinstallbackend.h" #include "util/dialogutil.h" #include "util/directory.h" #include "util/cresmgr.h" @@ -47,7 +46,7 @@ BtInstallPathDialog::BtInstallPathDialog() { tr("Configure bookshelf folders"), l1 + QString("

") + l2 + QString("
")); mainLayout->addWidget(mainLabel); - QString swordConfPath = instbackend::swordConfigFilename(); + QString swordConfPath = BtInstallBackend::swordConfigFilename(); /// \todo After releasing 2.4, change the following line to: QLabel *confPathLabel = new QLabel(tr("Configuration file for the folders is: %1").arg(swordConfPath), this); QLabel* confPathLabel = new QLabel(tr("Configuration file for the folders is: ").append("%1").arg(swordConfPath), this); confPathLabel->setWordWrap(true); @@ -55,7 +54,7 @@ BtInstallPathDialog::BtInstallPathDialog() { m_swordPathListBox = new QTreeWidget(this); - m_swordPathListBox->header()->hide(); + m_swordPathListBox->setHeaderHidden(true); QString rwfolderitem(tr("Folders where new works can be installed")); m_writableItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(rwfolderitem));; @@ -65,7 +64,7 @@ BtInstallPathDialog::BtInstallPathDialog() { m_nonexistingItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(tr("Nonexistent folders")));; m_nonexistingItem->setFlags(Qt::ItemIsEnabled); - QStringList targets = instbackend::targetList(); + QStringList targets = BtInstallBackend::targetList(); foreach (QString pathname, targets) { addPathToList(pathname); @@ -76,19 +75,19 @@ BtInstallPathDialog::BtInstallPathDialog() { QVBoxLayout* buttonLayout = new QVBoxLayout(); - m_addButton = new QPushButton(tr("Add..."), this); + m_addButton = new QPushButton(tr("&Add..."), this); m_addButton->setToolTip(tr("Add new folder")); m_addButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::paths::add_icon)); connect(m_addButton, SIGNAL(clicked()), this, SLOT(slotAddClicked())); buttonLayout->addWidget(m_addButton); - m_editButton = new QPushButton(tr("Edit..."), this); + m_editButton = new QPushButton(tr("&Edit..."), this); m_editButton->setToolTip(tr("Edit the selected folder")); m_editButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::paths::edit_icon)); connect(m_editButton, SIGNAL(clicked()), this, SLOT(slotEditClicked())); buttonLayout->addWidget(m_editButton); - m_removeButton = new QPushButton(tr("Remove"), this); + m_removeButton = new QPushButton(tr("&Remove"), this); m_removeButton->setToolTip(tr("Remove the selected folder")); m_removeButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::paths::remove_icon)); connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveClicked())); @@ -162,7 +161,7 @@ void BtInstallPathDialog::addPathToList(QString pathname) { i = new QTreeWidgetItem(m_readableItem, QStringList(pathname) ); } } - if (i && QDir(pathname) == instbackend::swordDir()) { + if (i && QDir(pathname) == BtInstallBackend::swordDir()) { i->setFlags(Qt::NoItemFlags); i->setToolTip(0, tr("This default folder in your home directory can't be removed")); } @@ -231,7 +230,7 @@ void BtInstallPathDialog::writeSwordConfig() { ++it; } qDebug() << "save the target list" << targets; - instbackend::setTargetList(targets); //creates new Sword config + BtInstallBackend::setTargetList(targets); //creates new Sword config } void BtInstallPathDialog::accept() { diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h index e72da3c..9adf6bc 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h +++ b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp index 365d5c8..465ec03 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp +++ b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,11 +22,13 @@ #include #include "backend/managers/cswordbackend.h" #include "frontend/bookshelfmanager/installpage/btinstallthread.h" -#include "util/cpointers.h" -BtInstallProgressDialog::BtInstallProgressDialog(QWidget* parent, QTreeWidget* selectedModulesTreeWidget, QString destination) - : QDialog(parent) { +BtInstallProgressDialog::BtInstallProgressDialog( + const QSet &modules, + const QString &destination, QWidget *parent, Qt::WindowFlags flags) + : QDialog(parent, flags) +{ // we want this dialog to be deleted when user closes it or the downloads are completed setAttribute(Qt::WA_DeleteOnClose, true); setWindowTitle(tr("Install Progress")); @@ -39,39 +41,34 @@ BtInstallProgressDialog::BtInstallProgressDialog(QWidget* parent, QTreeWidget* s m_statusWidget->header()->setMovable(false); //m_statusWidget->setColumnWidth(1, util::tool::mWidth(m_statusWidget, 2)); - foreach (QTreeWidgetItem* sourceItem, selectedModulesTreeWidget->invisibleRootItem()->takeChildren()) { - // create items and threads for modules under this source - foreach (QTreeWidgetItem* moduleItem, sourceItem->takeChildren()) { - if (moduleItem->checkState(0) == Qt::Checked) { - // create a thread for this module - BtInstallThread* thread = new BtInstallThread(this, moduleItem->text(0), sourceItem->text(0), destination); - m_waitingThreads.insert(sourceItem->text(0), thread); - m_threadsByModule.insert(moduleItem->text(0), thread); - // progress widget/item - QPushButton* stopButton = new QPushButton(tr("Stop"), m_statusWidget); - stopButton->setFixedSize(stopButton->sizeHint()); - - // the item - QTreeWidgetItem* progressItem = new QTreeWidgetItem(m_statusWidget); - m_statusWidget->setColumnWidth(2, stopButton->sizeHint().width()); - progressItem->setSizeHint(2, stopButton->sizeHint()); - progressItem->setText(0, moduleItem->text(0)); - progressItem->setFlags(Qt::ItemIsEnabled); - m_statusWidget->setItemWidget(progressItem, 2, stopButton); - progressItem->setText(1, tr("Waiting for turn...")); - - //connect the signals between the dialog, items and threads - QObject::connect(stopButton, SIGNAL(clicked()), thread, SLOT(slotStopInstall()), Qt::QueuedConnection); - QObject::connect(thread, SIGNAL(installStopped(QString, QString)), this, SLOT(slotOneItemStopped(QString, QString)), Qt::QueuedConnection); - //is this needed or is statusUpdated enough? - QObject::connect(thread, SIGNAL(installCompleted(QString, QString, int)), this, SLOT(slotOneItemCompleted(QString, QString, int)), Qt::QueuedConnection); - QObject::connect(thread, SIGNAL(statusUpdated(QString, int)), this, SLOT(slotStatusUpdated(QString, int)), Qt::QueuedConnection); - QObject::connect(thread, SIGNAL(downloadStarted(QString)), this, SLOT(slotDownloadStarted(QString)), Qt::QueuedConnection); - - QObject::connect(thread, SIGNAL(preparingInstall(QString, QString)), this, SLOT(slotInstallStarted(QString, QString)), Qt::QueuedConnection); - - } - } + Q_FOREACH(const CSwordModuleInfo *module, modules) { + const QString sourceName(module->property("installSourceName").toString()); + // create a thread for this module + BtInstallThread* thread = new BtInstallThread(module->name(), sourceName, destination); + m_waitingThreads.insert(sourceName, thread); + m_threadsByModule.insert(module->name(), thread); + // progress widget/item + QPushButton* stopButton = new QPushButton(tr("Stop"), m_statusWidget); + stopButton->setFixedSize(stopButton->sizeHint()); + + // the item + QTreeWidgetItem* progressItem = new QTreeWidgetItem(m_statusWidget); + m_statusWidget->setColumnWidth(2, stopButton->sizeHint().width()); + progressItem->setSizeHint(2, stopButton->sizeHint()); + progressItem->setText(0, module->name()); + progressItem->setFlags(Qt::ItemIsEnabled); + m_statusWidget->setItemWidget(progressItem, 2, stopButton); + progressItem->setText(1, tr("Waiting for turn...")); + + //connect the signals between the dialog, items and threads + QObject::connect(stopButton, SIGNAL(clicked()), thread, SLOT(slotStopInstall()), Qt::QueuedConnection); + QObject::connect(thread, SIGNAL(installStopped(QString, QString)), this, SLOT(slotOneItemStopped(QString, QString)), Qt::QueuedConnection); + //is this needed or is statusUpdated enough? + QObject::connect(thread, SIGNAL(installCompleted(QString, QString, int)), this, SLOT(slotOneItemCompleted(QString, QString, int)), Qt::QueuedConnection); + QObject::connect(thread, SIGNAL(statusUpdated(QString, int)), this, SLOT(slotStatusUpdated(QString, int)), Qt::QueuedConnection); + QObject::connect(thread, SIGNAL(downloadStarted(QString)), this, SLOT(slotDownloadStarted(QString)), Qt::QueuedConnection); + + QObject::connect(thread, SIGNAL(preparingInstall(QString, QString)), this, SLOT(slotInstallStarted(QString, QString)), Qt::QueuedConnection); } m_statusWidget->setMinimumWidth(m_statusWidget->size().width()); @@ -93,22 +90,22 @@ void BtInstallProgressDialog::startThreads() { // remove all the updated modules from the backend module list at once //foreach (QString mName, m_threadsByModule.keys()) { //} - //QList CPointers::backend()->takeModulesFromList(m_threadsByModule.keys()); + //QList CSwordBackend::instance()()->takeModulesFromList(m_threadsByModule.keys()); qDebug() << "start threads..."; //loop through the multimap of the waiting threads, start at most 3 threads for each source QMultiMap::iterator threadIterator = m_waitingThreads.end(); // concurrency is disabled for now -// while (threadIterator != m_waitingThreads.end()) { -// QString sourceName = threadIterator.key(); -// qDebug() << sourceName; -// if (m_runningThreads.values(sourceName).count() < 3) { -// BtInstallThread* t = threadIterator.value(); -// m_runningThreads.insert(sourceName, t); -// threadIterator = m_waitingThreads.erase(threadIterator); -// t->start(); -// } -// else ++threadIterator; -// } +// while (threadIterator != m_waitingThreads.end()) { +// QString sourceName = threadIterator.key(); +// qDebug() << sourceName; +// if (m_runningThreads.values(sourceName).count() < 3) { +// BtInstallThread* t = threadIterator.value(); +// m_runningThreads.insert(sourceName, t); +// threadIterator = m_waitingThreads.erase(threadIterator); +// t->start(); +// } +// else ++threadIterator; +// } //non-concurrent if (threadIterator != m_waitingThreads.begin()) { // go to the last item which is actually the first in the visible list @@ -157,16 +154,16 @@ void BtInstallProgressDialog::oneItemStoppedOrCompleted(QString module, QString m_waitingThreads.remove(source, m_threadsByModule.value(module)); //concurrency is disabled for now -// //start a waiting thread if there are any -// QList threadsForSource = m_waitingThreads.values(source); -// qDebug() << threadsForSource; -// if (!threadsForSource.isEmpty()) { -// qDebug() << "Threads are waiting for turn"; -// BtInstallThread* thread = threadsForSource.at(0); -// m_waitingThreads.remove(source, thread); -// m_runningThreads.insert(source, thread); -// thread->start(); -// } +// //start a waiting thread if there are any +// QList threadsForSource = m_waitingThreads.values(source); +// qDebug() << threadsForSource; +// if (!threadsForSource.isEmpty()) { +// qDebug() << "Threads are waiting for turn"; +// BtInstallThread* thread = threadsForSource.at(0); +// m_waitingThreads.remove(source, thread); +// m_runningThreads.insert(source, thread); +// thread->start(); +// } //non-concurrent QMultiMap::iterator threadIterator = m_waitingThreads.end(); @@ -238,7 +235,7 @@ void BtInstallProgressDialog::closeEvent(QCloseEvent* event) { return; } // other parts of the UI/engine must be updated - CPointers::backend()->reloadModules(CSwordBackend::AddedModules); + CSwordBackend::instance()->reloadModules(CSwordBackend::AddedModules); } bool BtInstallProgressDialog::threadsDone() { diff --git a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h index 1d8113a..8b990ad 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h +++ b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,13 +17,16 @@ class BtInstallThread; +class CSwordModuleInfo; class QTreeWidget; class QTreeWidgetItem; class BtInstallProgressDialog : public QDialog { Q_OBJECT public: - BtInstallProgressDialog(QWidget* parent, QTreeWidget* selectedModulesTreeWidget, QString destination); + BtInstallProgressDialog(const QSet &modules, + const QString &destination, QWidget *parent = 0, + Qt::WindowFlags flags = 0); ~BtInstallProgressDialog(); @@ -43,7 +46,7 @@ class BtInstallProgressDialog : public QDialog { virtual void closeEvent(QCloseEvent* event); //signals: -// void swordSetupChanged(); +// void swordSetupChanged(); private: diff --git a/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp b/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp index 53ae071..2d04a51 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp +++ b/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,14 +16,14 @@ #include #include "backend/managers/cswordbackend.h" #include "frontend/bookshelfmanager/btinstallmgr.h" -#include "frontend/bookshelfmanager/instbackend.h" -#include "util/cpointers.h" +#include "backend/btinstallbackend.h" // Sword includes: #include -BtInstallThread::BtInstallThread(QObject* parent, QString moduleName, QString sourceName, QString destinationName) +BtInstallThread::BtInstallThread(const QString &moduleName, const QString &sourceName, + const QString &destinationName, QObject *parent) : QThread(parent), done(false), m_module(moduleName), @@ -45,8 +45,8 @@ void BtInstallThread::run() { emit preparingInstall(m_module, m_source); //This is 0 before set here - remember when using the value when cancelling // the installation before this has been run - m_installSource.reset(new sword::InstallSource(instbackend::source(m_source))); - m_backendForSource.reset(instbackend::backend(*m_installSource)); + m_installSource = QSharedPointer(new sword::InstallSource(BtInstallBackend::source(m_source))); + m_backendForSource = QSharedPointer(BtInstallBackend::backend(*m_installSource)); //make sure target/mods.d and target/modules exist /// \todo move this to some common precondition @@ -74,9 +74,9 @@ void BtInstallThread::run() { // manager for the destination path sword::SWMgr lMgr( m_destination.toLatin1() ); - if (instbackend::isRemote(*m_installSource)) { + if (BtInstallBackend::isRemote(*m_installSource)) { qDebug() << "calling install"; - int status = m_iMgr->installModule(&lMgr, 0, m_module.toLatin1(), m_installSource.get()); + int status = m_iMgr->installModule(&lMgr, 0, m_module.toLatin1(), m_installSource.data()); if (status != 0) { qWarning() << "Error with install: " << status << "module:" << m_module; } @@ -123,7 +123,7 @@ void BtInstallThread::slotStopInstall() { qDebug() << "BtInstallThread::slotStopInstall 3"; // cleanup: remove the module, remove the temp files // if installation has already started - if (m_installSource.get() != 0) { + if (m_installSource.data() != 0) { qDebug() << "BtInstallThread::slotStopInstall 4"; // remove the installed module, just to be sure because mgr may // have been terminated when copying files @@ -148,9 +148,9 @@ void BtInstallThread::slotDownloadStarted() { void BtInstallThread::removeModule() { qDebug() << "BtInstallThread::removeModule start"; CSwordModuleInfo* m; - m = CPointers::backend()->findModuleByName(m_module); + m = CSwordBackend::instance()->findModuleByName(m_module); if (!m) { - m = instbackend::backend(instbackend::source(m_destination.toLatin1()))->findModuleByName(m_module); + m = BtInstallBackend::backend(BtInstallBackend::source(m_destination.toLatin1()))->findModuleByName(m_module); } if (m) { //module found? qDebug() << "BtInstallThread::removeModule, module" << m_module << "found"; @@ -164,7 +164,7 @@ void BtInstallThread::removeModule() { prefixPath.remove( prefixPath.indexOf(dataPath), dataPath.length() ); } else { - prefixPath = QString::fromLatin1(CPointers::backend()->prefixPath); + prefixPath = QString::fromLatin1(CSwordBackend::instance()->prefixPath); } sword::SWMgr mgr(prefixPath.toLatin1()); @@ -182,8 +182,8 @@ void BtInstallThread::removeTempFiles() { // (take the remote conf file for this module, take DataPath, // take the absolute path of the InstallMgr) - //sword::InstallSource is = instbackend::source(m_source); - if (instbackend::isRemote(*m_installSource)) { + //sword::InstallSource is = BtInstallBackend::source(m_source); + if (BtInstallBackend::isRemote(*m_installSource)) { // get the path for the module temp files CSwordModuleInfo* mInfo = m_backendForSource->findModuleByName(m_module); QString dataPath = mInfo->config(CSwordModuleInfo::AbsoluteDataPath); diff --git a/src/frontend/bookshelfmanager/installpage/btinstallthread.h b/src/frontend/bookshelfmanager/installpage/btinstallthread.h index a50910f..8bb660d 100644 --- a/src/frontend/bookshelfmanager/installpage/btinstallthread.h +++ b/src/frontend/bookshelfmanager/installpage/btinstallthread.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,11 +12,12 @@ #include -#include +#include #include "frontend/bookshelfmanager/btinstallmgr.h" class BtInstallProgressDialog; +class CSwordBackend; /** * Thread for installing a module. @@ -54,7 +55,8 @@ temporary files manually. class BtInstallThread : public QThread { Q_OBJECT public: - BtInstallThread(QObject* parent, QString moduleName, QString sourceName, QString destinationName); + BtInstallThread(const QString &moduleName, const QString &sourceName, + const QString &destinationName, QObject *parent = 0); ~BtInstallThread(); @@ -77,10 +79,10 @@ class BtInstallThread : public QThread { bool m_cancelled; BtInstallMgr* m_iMgr; //BtInstallMgr m_iMgr; - boost::scoped_ptr m_installSource; + QSharedPointer m_installSource; /// \todo it would be best to get the backend from the bookshelf manager install page // where it has already been created. Could fasten the progress dialog startup. - boost::scoped_ptr m_backendForSource; + QSharedPointer m_backendForSource; signals: /** Emitted when the install progress status is updated. */ diff --git a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp new file mode 100644 index 0000000..3666888 --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp @@ -0,0 +1,62 @@ +#include "frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h" + +#include +#include +#include "backend/btinstallbackend.h" +#include "util/dialogutil.h" + + +BtRefreshProgressDialog::BtRefreshProgressDialog(sword::InstallSource &source, + QWidget *parent, + Qt::WindowFlags flags) + : QProgressDialog(parent, flags) + , m_source(source) +{ + qDebug() << "Creating BtRefreshProgressDialog for source" << source.caption; + + Q_ASSERT(BtInstallBackend::isRemote(source)); + setWindowTitle(tr("Refreshing source %1").arg(QString(source.caption))); + setCancelButtonText(tr("&Cancel")); + setLabelText(tr("Connecting...")); + Q_ASSERT(minimum() == 0); + setMaximum(100); + setValue(0); + setWindowModality(Qt::ApplicationModal); + setMinimumDuration(1000); + + connect(this, SIGNAL(canceled()), + this, SLOT(slotCanceled())); + connect(&m_installMgr, SIGNAL(percentCompleted(int,int)), + this, SLOT(slotPercentCompleted(int,int))); +} + +void BtRefreshProgressDialog::slotPercentCompleted(int, int current) { + qDebug() << "BtRefreshProgressDialog progress:" << current; + + setValue(current); + qApp->processEvents(); +} + +void BtRefreshProgressDialog::slotCanceled() { + qDebug() << "BtRefreshProgressDialog cancel clicked."; + + m_installMgr.terminate(); +} + +bool BtRefreshProgressDialog::runAndDelete() { + qDebug() << "BtRefreshProgressDialog runAndDelete()"; + + show(); + qApp->processEvents(); + bool r = (m_installMgr.refreshRemoteSource(&m_source) == 0); + if (r) { + setValue(100); + qApp->processEvents(); + } else { + util::showWarning(this, tr("Warning"), + tr("Failed to refresh source %1") + .arg(QString(m_source.caption))); + } + deleteLater(); + return r; +} diff --git a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h new file mode 100644 index 0000000..dfabcf6 --- /dev/null +++ b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h @@ -0,0 +1,38 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTREFRESHPROGRESSDIALOG_H +#define BTREFRESHPROGRESSDIALOG_H + +#include + +#include "frontend/bookshelfmanager/btinstallmgr.h" + + +class BtRefreshProgressDialog: public QProgressDialog { + Q_OBJECT + + public: /* Methods: */ + BtRefreshProgressDialog(sword::InstallSource &source, + QWidget *parent = 0, Qt::WindowFlags f = 0); + + bool runAndDelete(); + + private slots: + + void slotPercentCompleted(int, int); + void slotCanceled(); + + private: /* Fields: */ + + sword::InstallSource m_source; + BtInstallMgr m_installMgr; +}; + +#endif // BTREFRESHPROGRESSDIALOG_H diff --git a/src/frontend/bookshelfmanager/installpage/btsourcearea.cpp b/src/frontend/bookshelfmanager/installpage/btsourcearea.cpp deleted file mode 100644 index ca85822..0000000 --- a/src/frontend/bookshelfmanager/installpage/btsourcearea.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/bookshelfmanager/installpage/btsourcearea.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend/managers/cswordbackend.h" -#include "frontend/bookshelfmanager/instbackend.h" -#include "frontend/btaboutmoduledialog.h" -#include "util/directory.h" -#include "util/cpointers.h" -#include "util/cresmgr.h" -#include "util/tool.h" - -// Sword includes: -#include - - -// **************************************************************** -// ******** Installation source and module list widget ************ -// **************************************************************** - -BtSourceArea::BtSourceArea(const QString& sourceName) - : QWidget(), - m_sourceName(sourceName), - m_treeAlreadyInitialized(false), - m_remoteBackend(0) { //important! - setObjectName(sourceName); - m_checkedModules = QMap(); - qDebug() << "BtSourceArea::BtSourceArea, " << m_sourceName; - initView(); -} - -BtSourceArea::~BtSourceArea() { - qDebug() << "BtSourceArea::~BtSourceArea" << m_sourceName; - delete m_remoteBackend; -} - -void BtSourceArea::initView() { - namespace DU = util::directory; - - qDebug() << "BtSourceArea::initView"; - QVBoxLayout *mainLayout = new QVBoxLayout(this); - - // source related button row - QHBoxLayout *sourceLayout = new QHBoxLayout(); - m_refreshButton = new QPushButton(tr("Refresh...")); - m_refreshButton->setToolTip(tr("Refresh the list of works from this source")); - m_refreshButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::refresh_icon)); - //m_refreshButton->setEnabled(false); - QSpacerItem *sourceSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - //m_editButton = new QPushButton(tr("Edit...")); - /// \todo after writing the edit widget: - //m_editButton->setEnabled(false); - m_deleteButton = new QPushButton(tr("Delete...")); - m_deleteButton->setToolTip(tr("Delete this source")); - m_deleteButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::delete_icon)); - //m_deleteButton->setEnabled(false); - m_addButton = new QPushButton(tr("Add...")); - m_addButton->setToolTip(tr("Add new source")); - m_addButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::add_icon)); - - sourceLayout->addWidget(m_refreshButton); - sourceLayout->addItem(sourceSpacer); - //sourceLayout->addWidget(m_editButton); - sourceLayout->addWidget(m_deleteButton); - sourceLayout->addWidget(m_addButton); - - mainLayout->addLayout(sourceLayout); - // There are no views for the stack yet, see initSources - m_view = new QTreeWidget(this); - m_view->setHeaderLabels(QStringList() << tr("Work") << tr("Description")); - m_view->setColumnWidth(0, util::tool::mWidth(m_view, 20)); - mainLayout->addWidget(m_view); - - connect(m_view, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), SLOT(slotItemDoubleClicked(QTreeWidgetItem*, int))); - connect(CPointers::backend(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), SLOT(slotSwordSetupChanged())); - connect(this, SIGNAL(signalCreateTree()), SLOT(slotCreateTree()), Qt::QueuedConnection); -} - -void BtSourceArea::prepareRemove() { - // don't create tree anymore, this will be removed - disconnect(this, SIGNAL(signalCreateTree()), this, SLOT(slotCreateTree())); -} - -QSize BtSourceArea::sizeHint() const { - return QSize(100, m_refreshButton->height() + (m_view->header()->height() * 5)); -} - -void BtSourceArea::initTreeFirstTime() { - if (!m_treeAlreadyInitialized) { - createModuleTree(); - m_treeAlreadyInitialized = true; - } -} - -void BtSourceArea::createModuleTree() { - qDebug() << "BtSourceArea::createModuleTree start"; - // Start creating tree with a queued connection. - // This makes showing the dialog possible even before the tree is initialized. - emit signalCreateTree(); -} -void BtSourceArea::slotCreateTree() { - qDebug() << "BtSourceArea::slotCreateTree" << QTime::currentTime (); - //let the dialog become visible - QCoreApplication::processEvents(); - // Creating the view and populating list may take time - QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); - - // disconnect the signal so that we don't have to run functions for every module - // (note: what to do if we want to restore the item selection when rebuilding? - disconnect(m_view, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotSelectionChanged(QTreeWidgetItem*, int)) ); - m_view->clear(); - - /// \todo if the tree already exists for this source, maybe the selections should be preserved - m_checkedModules.clear(); - - sword::InstallSource is = instbackend::source(m_sourceName); - delete m_remoteBackend; // the old one can be deleted - m_remoteBackend = instbackend::backend(is); - Q_ASSERT(m_remoteBackend); - m_moduleList = m_remoteBackend->moduleList(); - - // give the list to BTModuleTreeItem, create filter to remove - // those modules which are installed already - InstalledFilter alreadyInstalledFilter(m_sourceName); - QList filterList; - filterList.append(&alreadyInstalledFilter); - BTModuleTreeItem rootItem(filterList, BTModuleTreeItem::CatLangMod, &m_moduleList); - - addToTree(&rootItem, m_view->invisibleRootItem()); - QCoreApplication::processEvents(); - // receive signal when user checks modules - connect(m_view, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotSelectionChanged(QTreeWidgetItem*, int)) ); - QApplication::restoreOverrideCursor(); - qDebug() << "BtSourceArea::createModuleTree end" << QTime::currentTime (); -} - -void BtSourceArea::addToTree(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem) { - //qDebug()<<"BtSourceArea::addToTree "<text(); - //qDebug() << "BTMTItem type: " << item->type(); - - foreach (BTModuleTreeItem* i, item->children()) { - addToTree(i, new QTreeWidgetItem(widgetItem)); - } - if (item->type() != BTModuleTreeItem::Root) { - CSwordModuleInfo* mInfo = item->moduleInfo(); - widgetItem->setText(0, item->text()); - if (item->type() == BTModuleTreeItem::Category || item->type() == BTModuleTreeItem::Language) { - //qDebug() << "item"<text()<< "was cat or lang"; - widgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate); - } - if (item->type() == BTModuleTreeItem::Module) { - //qDebug() << "item"<text()<< "was a module"; - widgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - widgetItem->setCheckState(0, Qt::Unchecked); - - CSwordModuleInfo* const installedModule = CPointers::backend()->findModuleByName(mInfo->name()); - QString installedV; - - if (!installedModule) { - /** - \todo maybe? save the module list of a source before refreshing, - compare after refreshing, mark the newly added modules if - not newly added: - state: installable (no indicator) - else: status: newly added, color yellow - */ - } else { // the module is already installed - QBrush bg(QColor(255, 153, 153)); /// \bug Possible color conflict - widgetItem->setBackground(0, bg); - widgetItem->setBackground(1, bg); - installedV = QString(installedModule->config(CSwordModuleInfo::ModuleVersion).toLatin1()); - // set the color for the parent items - QTreeWidgetItem* parent1 = widgetItem->parent(); - if (parent1) { - parent1->setBackground(0, bg); - parent1->setBackground(1, bg); - QTreeWidgetItem* parent2 = parent1->parent(); - if (parent2) { - parent2->setBackground(0, bg); - parent2->setBackground(1, bg); - } - } - } - - - QString descr(mInfo->config(CSwordModuleInfo::Description)); - QString toolTipText = util::tool::remoteModuleToolTip(mInfo, installedV); - - widgetItem->setText(1, descr); - widgetItem->setToolTip(0, toolTipText); - widgetItem->setToolTip(1, toolTipText); - } - } -} - -QTreeWidget* BtSourceArea::treeWidget() { - return m_view; -} - -// return the selected modules -QMap* BtSourceArea::selectedModules() { - return &m_checkedModules; -} - -// when a module is checked/unchecked -void BtSourceArea::slotSelectionChanged(QTreeWidgetItem* item, int column) { - //qDebug() << "BtSourceArea::slotSelectionChanged"; - // modify the internal list of selected (actually checked) modules - // if() leaves groups away - if (!item->childCount() && column == 0) { - foreach (CSwordModuleInfo* module, m_moduleList) { - if (module->name() == item->text(0)) { - if (item->checkState(0) == Qt::Checked) { - qDebug() << module->name() << "was checked"; - m_checkedModules.insert(module->name(), true); - } - else { - qDebug() << module->name() << "was unchecked"; - m_checkedModules.remove(module->name()); - } - emit signalSelectionChanged(m_sourceName, m_checkedModules.count()); - break; - } - } - } -} - -void BtSourceArea::slotItemDoubleClicked(QTreeWidgetItem* item, int /*column*/) { - CSwordModuleInfo* mInfo = m_remoteBackend->findModuleByName(item->text(0)); - if (mInfo) { - BTAboutModuleDialog* dialog = new BTAboutModuleDialog(this, mInfo); - dialog->show(); - dialog->raise(); - } -} - -BtSourceArea::InstalledFilter::InstalledFilter(QString sourceName) - : BTModuleTreeItem::Filter(), - m_source(instbackend::source(sourceName)), - m_swordBackend(instbackend::backend(m_source)) { - // these are set once to optimize away repeated calls - // m_source, m_swordBackend - -} -//filter out already installed, not updateable modules -bool BtSourceArea::InstalledFilter::filter(CSwordModuleInfo* mInfo) { - //qDebug() << "BtSourceArea::InstalledFilter::filter, module " << mInfo->name(); - CSwordModuleInfo* const installedModule = CPointers::backend()->findModuleByName(mInfo->name()); - if (installedModule) { - //qDebug() << "already installed, check if it's an update..."; - const sword::SWVersion installedVersion(installedModule->config(CSwordModuleInfo::ModuleVersion).toLatin1()); - const sword::SWVersion newVersion(mInfo->config(CSwordModuleInfo::ModuleVersion).toLatin1()); - if (installedVersion >= newVersion) { - return false; - } - } - return true; -} - -void BtSourceArea::slotSwordSetupChanged() { - createModuleTree(); -} diff --git a/src/frontend/bookshelfmanager/installpage/btsourcearea.h b/src/frontend/bookshelfmanager/installpage/btsourcearea.h deleted file mode 100644 index ece20ed..0000000 --- a/src/frontend/bookshelfmanager/installpage/btsourcearea.h +++ /dev/null @@ -1,96 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BTSOURCEAREA_H -#define BTSOURCEAREA_H - -#include - -#include -#include -#include -#include "backend/btmoduletreeitem.h" - -// Sword includes: -#include - - -class QTreeWidget; -class QTreeWidgetItem; -class QLabel; -class QPushButton; - -/** -* Area for one install source. -* -* - Tree widget for modules -* - Buttons for handling the source(s): refresh, edit, remove, add -* -* Each source has -* QTreeWidget, populated with the module tree if the source -* module list is in a local cache. Refreshing the source refreshes -* the cache and rebuilds the module tree. Sources are not refreshed -* automatically, only by the user action, one source at a time. -*/ -class BtSourceArea : public QWidget { - Q_OBJECT - - friend class BtSourceWidget; - public: - - struct InstalledFilter : BTModuleTreeItem::Filter { - InstalledFilter(QString sourceName); - bool filter(CSwordModuleInfo*); - sword::InstallSource m_source; - boost::scoped_ptr m_swordBackend; - }; - - BtSourceArea(const QString& sourceName); - ~BtSourceArea(); - - void initView(); - void prepareRemove(); - /** Reimplemented from QWidget. */ - virtual QSize sizeHint() const; - void initTreeFirstTime(); - QTreeWidget* treeWidget(); - - QMap* selectedModules(); - - public slots: - void slotSwordSetupChanged(); - /** Create a module tree for a tree widget */ - void createModuleTree(); - - signals: - void signalSelectionChanged(QString sourceName, int selectedCount); - void signalCreateTree(); - - private slots: - void slotCreateTree(); - void slotSelectionChanged(QTreeWidgetItem* item, int column); - void slotItemDoubleClicked(QTreeWidgetItem* item, int column); - private: - void addToTree(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem); - - QString m_sourceName; - bool m_treeAlreadyInitialized; - QMap m_checkedModules; - CSwordBackend* m_remoteBackend; // needed for the module list - QList m_moduleList; - - QTreeWidget* m_view; - QLabel* m_refreshTimeLabel; - QPushButton* m_refreshButton; - QPushButton* m_editButton; - QPushButton* m_deleteButton; - QPushButton* m_addButton; -}; - -#endif diff --git a/src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp b/src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp deleted file mode 100644 index 81e84fb..0000000 --- a/src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/bookshelfmanager/installpage/btsourcewidget.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "frontend/bookshelfmanager/btinstallmgr.h" -#include "frontend/bookshelfmanager/btmodulemanagerdialog.h" -#include "frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h" -#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h" -#include "frontend/bookshelfmanager/installpage/btinstallpage.h" -#include "frontend/bookshelfmanager/installpage/btinstallprogressdialog.h" -#include "frontend/bookshelfmanager/installpage/btsourcearea.h" -#include "frontend/bookshelfmanager/instbackend.h" -#include "util/dialogutil.h" - - -/** -* Tab Widget that holds source widgets -*/ -BtSourceWidget::BtSourceWidget(BtInstallPage* parent) - : QTabWidget(parent), - m_page(parent) { - qDebug() << "BtSourceWidget::BtSourceWidget start"; - initSources(); - // send queued event because "Delete" is initiated from tab which should be deleted - connect(this, SIGNAL(sigInitSources()), SLOT(initSources()), Qt::QueuedConnection); - /// \todo choose the page from config - -} - -BtSourceArea* BtSourceWidget::area() { - return dynamic_cast(currentWidget()); -} - -QString BtSourceWidget::currentSourceName() { - qDebug() << "BtSourceWidget::currentSourceName: " << m_sourceNameList.at(currentIndex()); - return m_sourceNameList.at(currentIndex()); -} - -void BtSourceWidget::initSourceConnections() { - qDebug() << "void BtSourceWidget::initSourceConnections() start"; - if (area()) { - connect(area()->m_refreshButton, SIGNAL(clicked()), SLOT(slotRefresh())); - //connect(area()->m_editButton, SIGNAL(clicked()), SLOT(slotEdit())); - connect(area()->m_deleteButton, SIGNAL(clicked()), SLOT(slotDelete()), Qt::QueuedConnection); - connect(area()->m_addButton, SIGNAL(clicked()), SLOT(slotAdd())); - connect(area(), SIGNAL(signalSelectionChanged(QString, int)), SLOT(slotModuleSelectionChanged(QString, int)) ); - } - qDebug() << "void BtSourceWidget::initSourceConnections() end"; -} - -void BtSourceWidget::slotEdit() { - qDebug() << "BtSourceWidget::slotEdit"; - /// \todo open the source editor dialog - - // if the source was changed, init the sources - -} - -void BtSourceWidget::slotDelete() { - qDebug() << "void BtSourceWidget::slotDelete() start"; - // ask for confirmation - int ret = util::showWarning(this, tr("Delete Source?"), - tr("Do you really want to delete this source?"), - QMessageBox::Yes | QMessageBox::No); - - if (ret == QMessageBox::Yes) { - instbackend::deleteSource(currentSourceName()); - initSources(); - } -} - -void BtSourceWidget::slotAdd() { - - boost::scoped_ptr dlg( new CSwordSetupInstallSourcesDialog() ); - sword::InstallSource newSource(""); //empty, invalid Source - - if (dlg->exec() == QDialog::Accepted) { - if (!dlg->wasRemoteListAdded()) { - newSource = dlg->getSource(); - if ( !((QString)newSource.type.c_str()).isEmpty() ) { // we have a valid source to add - instbackend::addSource(newSource); - } - } - initSources(); - } -} - - -void BtSourceWidget::slotRefresh() { - qDebug() << "void BtSourceWidget::slotRefresh() start"; - // (re)build the module cache for the source - - QString sourceName = currentSourceName(); - - // quick enough, make it modal so that we don't need to take care of anything else - m_progressDialog = new QProgressDialog("", tr("Cancel"), 0 , 100, this); - m_progressDialog->setWindowTitle(tr("Refreshing Source")); - m_progressDialog->setMinimumDuration(0); - - /// \todo get rid of the backend code, BtInstallMgr and progressdialog could handle this - //write method BtInstallMgr::slotRefreshCanceled() - connect(m_progressDialog, SIGNAL(canceled()), SLOT(slotRefreshCanceled())); - - // BACKEND CODE ********************************************************** - // would this be possible: instbackend::refreshSource( arguments ); - qDebug() << "void BtSourceWidget::slotRefresh 1"; - BtInstallMgr iMgr; - m_currentInstallMgr = &iMgr; //for the progress dialog - sword::InstallSource is = instbackend::source(sourceName); - bool success = false; - qDebug() << "void BtSourceWidget::slotRefresh 2"; - // connect this directly to the dialog setValue(int) if possible - connect(&iMgr, SIGNAL(percentCompleted(const int, const int)), SLOT(slotRefreshCompleted(const int, const int))); - - if (instbackend::isRemote(is)) { - m_progressDialog->show(); - qApp->processEvents(); - this->slotRefreshCompleted(0, 0); - m_progressDialog->setLabelText(tr("Connecting...")); - m_progressDialog->setValue(0); - qApp->processEvents(); - qDebug() << "void BtSourceWidget::slotRefresh 3"; - bool successful = iMgr.refreshRemoteSource( &is ); - if (!successful ) { //make sure the sources were updated sucessfully - success = true; - m_progressDialog->setValue(100); //make sure the dialog closes - } - else { - qWarning("InstallMgr: refreshRemoteSources returned an error."); - success = false; - } - } - else { - // Local source, update the list - success = true; - } - - delete m_progressDialog; - m_progressDialog = 0; - - // rebuild the view tree and refresh the view - if (success) { - qDebug() << "void BtSourceWidget::slotRefresh 4"; - area()->createModuleTree(); - } -} - -/// \todo try to move this to BtInstallMgr -void BtSourceWidget::slotRefreshCanceled() { - qDebug() << "BtSourceWidget::slotRefreshCanceled"; - Q_ASSERT(m_currentInstallMgr); - if (m_currentInstallMgr) { - m_currentInstallMgr->terminate(); - } - qApp->processEvents(); -} - -/// \todo try to move this to progress dialog -void BtSourceWidget::slotRefreshCompleted(const int, const int current) { - qDebug() << "BtSourceWidget::slotRefreshCompleted"; - if (m_progressDialog) { - if (m_progressDialog->labelText() != tr("Refreshing...")) { - m_progressDialog->setLabelText(tr("Refreshing...")); - } - m_progressDialog->setValue(current); - } - qApp->processEvents(); -} - -// init the tabbar, setup the module tree for the current source -void BtSourceWidget::initSources() { - qDebug() << "void BtSourceWidget::initSources() start"; - - //first clear all sources - //int i = count(); - for (int i = count() - 1; i >= 0; i--) { - BtSourceArea* a = dynamic_cast(widget(i)); - a->prepareRemove(); - } - for (int i = count() - 1; i >= 0; i--) { - qDebug() << "remove tab" << tabText(i); - QWidget* w = widget(i); - removeTab(i); - delete w; - qDebug() << "deleted"; - } - m_sourceNameList.clear(); - - // ***** Use the backend to get the list of sources ***** - instbackend::initPassiveFtpMode(); - QStringList sourceList = instbackend::sourceList(); - qDebug() << "got the source list from backend:" << sourceList; - // Add a default entry, the Crosswire main repository - if (!sourceList.count()) { - /// \todo Open a dialog which asks whether to get list from server and add sources - sword::InstallSource is("FTP"); //default return value - is.caption = "CrossWire Bible Society"; - is.source = "ftp.crosswire.org"; - is.directory = "/pub/sword/raw"; - // passive ftp is not needed here, it's the default - - instbackend::addSource(is); - - sourceList = instbackend::sourceList(); - //Q_ASSERT( sourceList.count() > 0 ); - } - qDebug() << "void BtSourceWidget::initSources 1"; - // Add the sources to the widget - foreach (QString sourceName, sourceList) { - addSource(sourceName); - } - // connect this after the tabs have been created, - // otherwise the signal is caught too early. - QObject::connect(this, SIGNAL(currentChanged(int)), this, SLOT(slotTabSelected(int))); - qDebug() << "void BtSourceWidget::initSources end"; - /// \todo select the current source from the config - // It's important to choose something because the tree is not initialized until now - setCurrentIndex(0); - slotTabSelected(0); // setting the index wasn't enough if there were only 1 tab - - if (sourceList.count() == 0) { - QHBoxLayout* l = new QHBoxLayout(this); - QLabel* message = new QLabel(QString("") + tr("No sources were found in the SWORD configuration and BibleTime couldn't create a default source. Check your SWORD configuration and that the configuration path is writable. Then restart the Bookshelf Manager.") + QString(""), this); - message->setWordWrap(true); - l->addWidget(message); - } -} - -void BtSourceWidget::addSource(const QString& sourceName) { - qDebug() << "void BtSourceWidget::addSource(const QString& sourceName) start, with name" << sourceName; - // The source has already been added to the backend. - - QString type; - QString server; - QString path; - sword::InstallSource is = instbackend::source(sourceName); - if (instbackend::isRemote(is)) { - type = tr("Remote:"); - server = is.source.c_str(); - path = is.directory.c_str(); - } - else { // local source - type = tr("Local:"); - QFileInfo fi( is.directory.c_str() ); - path = is.directory.c_str(); - if (!(fi.isDir() )) { - path = path + QString(" ") + tr("Not a directory!"); /// \todo change this - } - if (!fi.isReadable()) { - path = path + QString(" ") + tr("Not readable!"); /// \todo change this - } - } - - // Here the tab UI is created and added to the tab widget - BtSourceArea* area = new BtSourceArea(sourceName); - int tabNumber = this->addTab(area, sourceName); - - /// \todo add "remote/local", server, path etc. - QString toolTip(QString("

") + sourceName + QString("
") + type + QString(" ") + server + path + QString("

")); - tabBar()->setTabToolTip(tabNumber, toolTip); - - //select the new tab - setCurrentIndex(tabNumber); - m_sourceNameList.append(sourceName); - initSourceConnections(); - qDebug() << "BtSourceWidget::addSource end"; -} - -// -void BtSourceWidget::slotModuleSelectionChanged(QString sourceName, int selectedCount) { - /// \todo editing sources should update the map also - qDebug() << "BtSourceWidget::slotModuleSelectionChanged start"; - - int overallCount = 0; - m_selectedModulesCountMap.insert(sourceName, selectedCount); - foreach (int count, m_selectedModulesCountMap) { - qDebug() << "add" << count << "to overall count of selected modules"; - overallCount += count; - } - - if (overallCount > 0) { - m_page->setInstallEnabled(true); - } - else { - m_page->setInstallEnabled(false); - } -} - -void BtSourceWidget::slotTabSelected(int /*index*/) { - BtSourceArea* area = dynamic_cast(currentWidget()); - if (area) area->initTreeFirstTime(); -} - -void BtSourceWidget::slotInstall() { - qDebug() << "void BtInstallPage::slotInstall start"; - - // check that the destination path is writable, do nothing if not and user doesn't want to continue - QDir dir = QDir(dynamic_cast(parent())->selectedInstallPath()); - bool canWrite = true; - if (dir.isReadable()) { - const QFileInfo fi( dir.canonicalPath() ); - if (!fi.exists() || !fi.isWritable()) { - canWrite = false; - } - } - else { - canWrite = false; - } - if (!canWrite) { - const int result = util::showWarning(this, tr("Warning"), tr("The destination directory is not writable or does not exist. Installation will fail unless this has first been fixed."), QMessageBox::Ignore | QMessageBox::Cancel, QMessageBox::Cancel); - if (result != QMessageBox::Ignore) { - return; - } - } - - // create the confirmation dialog - // (module tree dialog, modules taken from all sources) - QString dlgTitle(tr("Install/Update works?")); - QString dlgLabel(tr("Do you really want to install these works?") + - QString("

") + - tr("Only one version of a work can be installed at the same time. Select only one if there are items marked with red.") + - QString("")); - - // with empty list we avoid creating the module tree inside the dialog code - QList emptyList; - BtInstallModuleChooserDialog* dlg = new BtInstallModuleChooserDialog(this, dlgTitle, dlgLabel, &emptyList); - //dlg->setGrouping(BTModuleTreeItem::Mod); - QTreeWidget* treeWidget = dlg->treeWidget(); - QTreeWidgetItem* rootItem = treeWidget->invisibleRootItem(); - - QStringList nameList; - - // loop through each tab - for (int tab = 0; tab < count(); ++tab) { - BtSourceArea* sArea = dynamic_cast(widget(tab)); - if (sArea && sArea->selectedModules()->count() > 0) { - // there are selected modules in the source, create items for these - /// \todo Use new bookshelf model instead - /// \bug Valgrind reports memory leak: - QTreeWidgetItem* sourceItem = new QTreeWidgetItem(rootItem); - sourceItem->setText(0, m_sourceNameList.at(tab)); - sourceItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsTristate | Qt::ItemIsEnabled); - foreach (QString mName, sArea->selectedModules()->keys()) { - dlg->initModuleItem(mName, sourceItem); - } - sourceItem->setExpanded(true); - } - } - - //user accepts the dialog - connect(dlg, SIGNAL(modulesChanged(QList, QTreeWidget*)), SLOT(slotInstallAccepted(QList, QTreeWidget*)) ); - // user checks/unchecks an item, needed for preventing double items - QObject::connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), dlg, SLOT(slotItemChecked(QTreeWidgetItem*, int))); - dlg->exec(); - // The OK signal sent by the dialog is catched with slotInstallAccepted. -} - -void BtSourceWidget::slotStopInstall(QTreeWidget* /*treeWidget*/) { - qDebug() << "BtSourceWidget::slotStopInstall"; - // not needed? -} - -void BtSourceWidget::slotInstallAccepted(QList /*modules*/, QTreeWidget* treeWidget) { - qDebug() << "BtSourceWidget::slotInstallAccepted"; - - /// \todo first remove all modules which will be updated from the module list - // but what modules? all with the same real name? (there may be _n modules...) - - BtModuleManagerDialog* parentDialog = dynamic_cast(dynamic_cast(parent())->parentDialog()); - - BtInstallProgressDialog* dlg = new BtInstallProgressDialog(parentDialog, treeWidget, dynamic_cast(parent())->selectedInstallPath()); - - if (!parentDialog) qDebug() << "error, wrong parent!"; - - m_page->setInstallEnabled(false); - // the progress dialog is now modal, it can be made modeless later. - dlg->exec(); - - qDebug() << "BtSourceWidget::slotInstallAccepted end"; -} diff --git a/src/frontend/bookshelfmanager/installpage/btsourcewidget.h b/src/frontend/bookshelfmanager/installpage/btsourcewidget.h deleted file mode 100644 index fbe8426..0000000 --- a/src/frontend/bookshelfmanager/installpage/btsourcewidget.h +++ /dev/null @@ -1,86 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ -#ifndef BTSOURCEWIDGET_H -#define BTSOURCEWIDGET_H - -#include - -#include -#include - - -class BtInstallMgr; -class BtInstallPage; -class BtSourceArea; -class CSwordModuleInfo; -class QProgressDialog; -class QTreeWidget; - -/** -* Tabwidget which holds the source widgets. -* This widget implements the slots for the source action buttons and -* applies the actions to the proper source(s). -*/ -class BtSourceWidget : public QTabWidget { - Q_OBJECT - public: - friend class BtInstallPage; - - BtSourceWidget(BtInstallPage* parent); - virtual ~BtSourceWidget() {} - - BtSourceArea* area(); - QString currentSourceName(); - - public slots: - /** Install button has been clicked. */ - void slotInstall(); - /** "Stop All" button clicked */ - void slotStopInstall(QTreeWidget* treeWidget); - - private: - void initSourceConnections(); - - /** Add one source to tabs/stack. */ - void addSource(const QString& sourceName); - - private slots: - /** Add tabs/views for each source. */ - void initSources(); - - void slotRefresh(); - - void slotRefreshCanceled(); - - void slotRefreshCompleted(int, int); - - /** Edit button clicked. */ - void slotEdit(); - /** Delete button clicked. */ - void slotDelete(); - /** Add button clicked. */ - void slotAdd(); - /** Modules have been checked/unchecked in the view. */ - void slotModuleSelectionChanged(QString sourceName, int selectedCount); - - void slotTabSelected(int index); - void slotInstallAccepted(QList mi, QTreeWidget* treeWidget); - - signals: - void sigInitSources(); - - private: - QStringList m_sourceNameList; - BtInstallPage* m_page; - QProgressDialog* m_progressDialog; // for refreshing - BtInstallMgr* m_currentInstallMgr; // for refreshing - QMap m_selectedModulesCountMap; -}; - -#endif diff --git a/src/frontend/bookshelfmanager/instbackend.cpp b/src/frontend/bookshelfmanager/instbackend.cpp deleted file mode 100644 index 463a6e5..0000000 --- a/src/frontend/bookshelfmanager/instbackend.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/bookshelfmanager/instbackend.h" - -#include -#include -#include -#include -#include -#include -#include -#include "backend/managers/cswordbackend.h" -#include "frontend/bookshelfmanager/btinstallmgr.h" -#include "util/cpointers.h" -#include "util/directory.h" -#include "util/dialogutil.h" - -// Sword includes: -#include -#include -#include - - -using namespace sword; - -namespace instbackend { - -/** Adds the source described by Source to the backend. */ -bool addSource(sword::InstallSource& source) { - qDebug() << "backend::addSource"; - SWConfig config(configFilename().toLatin1()); - if (!strcmp(source.type, "FTP")) { - //make sure the path doesn't have a trailing slash, sword doesn't like it - if (source.directory[ source.directory.length()-1 ] == '/') { - source.directory--; //make one char shorter - } - - config["Sources"].insert( std::make_pair(SWBuf("FTPSource"), source.getConfEnt()) ); - } - else if (!strcmp(source.type, "DIR")) { - config["Sources"].insert( std::make_pair(SWBuf("DIRSource"), source.getConfEnt()) ); - } - config.Save(); - return true; -} - -/** Returns the Source struct. */ -sword::InstallSource source(QString name) { - qDebug() << "backend::source"; - BtInstallMgr mgr; - InstallSourceMap::iterator source = mgr.sources.find(name.toLatin1().data()); - if (source != mgr.sources.end()) { - return *(source->second); - } - else { //not found in Sword, may be a local DIR source - SWConfig config(configFilename().toLatin1()); - SectionMap::iterator sourcesSection = config.Sections.find("Sources"); - if (sourcesSection != config.Sections.end()) { - ConfigEntMap::iterator sourceBegin = - sourcesSection->second.lower_bound("DIRSource"); - ConfigEntMap::iterator sourceEnd = - sourcesSection->second.upper_bound("DIRSource"); - - while (sourceBegin != sourceEnd) { - InstallSource is("DIR", sourceBegin->second.c_str()); - if (!strcmp(is.caption, name.toLatin1()) ) { //found local dir source - return is; - } - - sourceBegin++;//next source - } - } - } - - InstallSource is("EMPTY"); //default return value - is.caption = "unknown caption"; - is.source = "unknown source"; - is.directory = "unknown dir"; - return is; -} - -/** Deletes the source. */ -bool deleteSource(QString name) { - qDebug() << "backend::deleteSource"; - sword::InstallSource is = source(name ); - - SWConfig config(configFilename().toLatin1()); - - //this code can probably be shortened by using the stl remove_if functionality - std::pair< ConfigEntMap::iterator, ConfigEntMap::iterator > range = - isRemote(is) - ? config["Sources"].equal_range("FTPSource") - : config["Sources"].equal_range("DIRSource"); - - ConfigEntMap::iterator it = range.first; - SWBuf sourceConfigEntry = is.getConfEnt(); - bool notFound = true; - while (it != range.second) { - //SWORD lib gave us a "nice" surprise: getConfEnt() adds uid, so old sources added by BT are not recognized here - if (it->second == sourceConfigEntry) { - config["Sources"].erase(it); - notFound = false; - break; - } - ++it; - } - if (notFound) { - qDebug() << "source was not found, try without uid"; - //try again without uid - QString sce(sourceConfigEntry.c_str()); - QStringList l = sce.split('|'); - l.removeLast(); - sce = l.join("|").append("|"); - it = range.first; - while (it != range.second) { - qDebug() << it->second; - if (it->second == sce) { - config["Sources"].erase(it); - break; - } - ++it; - } - } - - config.Save(); - return true; /// \todo dummy -} - -/** Refreshes the remote source module list. */ -bool refreshSource(QString /*name*/) { - // not possible until manager and progressdialog work together - return true; /// \todo dummy -} - -/** Returns the moduleinfo list for the source. Delete the pointer after using. IS THIS POSSIBLE?*/ -QList moduleList(QString /*name*/) { - QList list; /// \todo dummy - return list; -} - -bool isRemote(const sword::InstallSource& source) { - return !strcmp(source.type, "FTP"); -} - -const QString configPath() { - QString confPath = util::directory::getUserHomeSwordDir().absolutePath(); - confPath.append("/InstallMgr"); - return confPath; -} - -const QString configFilename() { - return (configPath() + "/InstallMgr.conf"); -} - -QStringList targetList() { - qDebug() << "backend::targetList"; - QStringList names = CPointers::backend()->swordDirList(); - return names; -} - -bool setTargetList( const QStringList& targets ) { - namespace DU = util::directory; - - qDebug() << "backend::setTargetList"; - //saves a new Sword config using the provided target list - //QString filename = KGlobal::dirs()->saveLocation("data", "bibletime/") + "sword.conf"; //default is to assume the real location isn't writable - //QString filename = util::DirectoryUtil::getUserBaseDir().canonicalPath().append("/.sword/sword.conf"); - //bool directAccess = false; - QString filename = swordConfigFilename(); - QFileInfo i(filename); - QFileInfo dirInfo(i.absolutePath()); - - - if ( !i.exists() && dirInfo.isWritable() ) { - // if the file doesn't exist but the parent is writable, create it - qWarning() << "The Sword config file does not exist, it has to be created"; - QFile f(filename); - f.open(QIODevice::WriteOnly); - f.close(); - i.refresh(); - } - if ( i.exists() && i.isWritable() ) { //we can write to the file ourself - qDebug() << "The Sword config file is writable"; - } - else { - // There is no way to save to the file - qWarning() << "The Sword config file is not writable!"; - util::showWarning(0, QObject::tr("Can't write file"), QObject::tr("The Sword config file can't be written!")); - return false; - } - - filename = util::directory::convertDirSeparators(filename); - SWConfig conf(filename.toLocal8Bit()); - conf.Sections.clear(); - -#ifdef Q_WS_WIN - // On Windows, add the sword directory to the config file. - QString swordPath = DU::convertDirSeparators( DU::getApplicationSwordDir().absolutePath()); - conf["Install"].insert( - std::make_pair( SWBuf("LocalePath"), swordPath.toLocal8Bit().data() ) - ); -#endif - - bool setDataPath = false; - for (QStringList::const_iterator it = targets.begin(); it != targets.end(); ++it) { - QString t = DU::convertDirSeparators(*it); -#ifdef Q_WS_WIN - if (t.contains(DU::convertDirSeparators(DU::getUserHomeDir().canonicalPath().append("\\Sword")))) { -#else - if (t.contains(DU::getUserHomeDir().canonicalPath().append("/.sword"))) { -#endif - //we don't want $HOME/.sword in the config - continue; - } - else { - qDebug() << "Add path to the conf file" << filename << ":" << t; - conf["Install"].insert( std::make_pair(!setDataPath ? SWBuf("DataPath") : SWBuf("AugmentPath"), t.toLocal8Bit().data()) ); - setDataPath = true; - } - } - qDebug() << "save the sword conf..."; - conf.Save(); - CPointers::backend()->reloadModules(CSwordBackend::PathChanged); - return true; -} - -QStringList sourceList() { - qDebug() << "backend::sourceList"; - BtInstallMgr mgr; - Q_ASSERT(mgr.installConf); - - QStringList names; - - //add Sword remote sources - for (InstallSourceMap::iterator it = mgr.sources.begin(); it != mgr.sources.end(); it++) { - names << QString::fromLocal8Bit(it->second->caption); - } - - // Add local directory sources - SWConfig config(configFilename().toLatin1()); - sword::SectionMap::iterator sourcesSection = config.Sections.find("Sources"); - if (sourcesSection != config.Sections.end()) { - sword::ConfigEntMap::iterator sourceBegin = sourcesSection->second.lower_bound("DIRSource"); - sword::ConfigEntMap::iterator sourceEnd = sourcesSection->second.upper_bound("DIRSource"); - - while (sourceBegin != sourceEnd) { - InstallSource is("DIR", sourceBegin->second.c_str()); - names << QString::fromLatin1(is.caption.c_str()); - - sourceBegin++; - } - } - - return names; -} - - -void initPassiveFtpMode() { - qDebug() << "backend::initPassiveFtpMode"; - SWConfig config(configFilename().toLatin1()); - config["General"]["PassiveFTP"] = "true"; - config.Save(); -} -const QString swordConfigFilename() { - namespace DU = util::directory; - - qDebug() << "backend::swordConfigFilename"; -#ifdef Q_WS_WIN - qDebug() << DU::getUserHomeDir().absolutePath().append("/Sword/sword.conf"); - return DU::getUserHomeDir().absolutePath().append("/Sword/sword.conf"); -// return DU::getApplicationDir().absolutePath().append("/sword.conf"); -#else - qDebug() << DU::getUserHomeDir().absolutePath().append("/.sword/sword.conf"); - return DU::getUserHomeDir().absolutePath().append("/.sword/sword.conf"); -#endif -} - -const QDir swordDir() { - namespace DU = util::directory; - -#ifdef Q_WS_WIN - return QDir(DU::getUserHomeDir().absolutePath().append("/Sword/")); -#else - return QDir(DU::getUserHomeDir().absolutePath().append("/.sword/")); -#endif -} - -CSwordBackend* backend( const sword::InstallSource& is) { - qDebug() << "backend::backend"; - CSwordBackend* ret = 0; - if (isRemote(is)) { - ret = new CSwordBackend( QString(is.localShadow.c_str()), false ); - } - else { - ret = new CSwordBackend( QString(is.directory.c_str()), false); - } - - Q_ASSERT(ret); - if (ret) { - ret->initModules(CSwordBackend::OtherChange); - } - return ret; -} - -} diff --git a/src/frontend/bookshelfmanager/instbackend.h b/src/frontend/bookshelfmanager/instbackend.h deleted file mode 100644 index 3a98e5a..0000000 --- a/src/frontend/bookshelfmanager/instbackend.h +++ /dev/null @@ -1,74 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef INSTBACKEND_H -#define INSTBACKEND_H - -#include -#include -#include "backend/managers/cswordbackend.h" - -// Sword includes: -#include - - -class CSwordModuleInfo; - -namespace instbackend { - -/** Adds the source to the backend. */ -bool addSource(sword::InstallSource& source); - -/** Returns the source struct. */ -sword::InstallSource source(QString name); - -/** Deletes the source. */ -bool deleteSource(QString name); - -/** Refreshes the remote source module list. */ -bool refreshSource(QString name); - -/** Returns the moduleinfo list for the source. */ -QList moduleList(QString name); - -/** Tells if the source is remote or local. */ -bool isRemote(const sword::InstallSource& source); - -/** Returns the list of available install target paths. */ -QStringList targetList(); - -/** Saves the list of available install target paths to the sword config. Return success indicator.*/ -bool setTargetList( const QStringList& targets ); - -QStringList sourceList(); - -/** Returns the path of the sword installer configuration file. */ -const QString configPath(); - -/** Returns the name of the sword installer configuration file. */ -const QString configFilename(); - -/** Sets the passive mode for as default. -* \todo see if we can en/disable this per source. -*/ -void initPassiveFtpMode(); - -/** Returns the file name for the Sword config file. */ -const QString swordConfigFilename(); - -/** Returns the Sword directory ($HOME/.sword/) as a QDir, created with absolute path (not canonical). -*/ -const QDir swordDir(); - -/** Returns backend Sword manager for the source. */ -CSwordBackend* backend( const sword::InstallSource& is); - -} - -#endif diff --git a/src/frontend/bookshelfmanager/removepage/btremovepage.cpp b/src/frontend/bookshelfmanager/removepage/btremovepage.cpp index 3f602e0..a19ab89 100644 --- a/src/frontend/bookshelfmanager/removepage/btremovepage.cpp +++ b/src/frontend/bookshelfmanager/removepage/btremovepage.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -12,90 +12,137 @@ #include "frontend/bookshelfmanager/removepage/btremovepage.h" -#include +#include +#include +#include #include -#include +#include #include -#include -#include "backend/drivers/cswordmoduleinfo.h" +#include +#include +#include "backend/bookshelfmodel/btbookshelffiltermodel.h" #include "backend/managers/cswordbackend.h" -#include "util/directory.h" -#include "util/dialogutil.h" -#include "util/cpointers.h" +#include "frontend/btbookshelfview.h" +#include "frontend/btbookshelfwidget.h" #include "util/cresmgr.h" +#include "util/dialogutil.h" +#include "util/directory.h" // Sword includes: #include #include -BtRemovePage::BtRemovePage() - : BtConfigPage() { - namespace DU = util::directory; - - QGridLayout* layout = new QGridLayout(this); - layout->setMargin(5); - - layout->setSpacing(10); - layout->setColumnStretch(1, 1); - layout->setRowStretch(2, 1); - - m_model = new BtRemovePageTreeModel(this); - m_model->setSourceModel(CPointers::backend()->model()); - - m_view = new QTreeView(this); - m_view->header()->setResizeMode(QHeaderView::ResizeToContents); - m_view->setModel(m_model); +namespace { +const QString groupingOrderKey("GUI/BookshelfManager/RemovePage/grouping"); +} - layout->addWidget(m_view, 2, 0, 1, 2); +BtRemovePage::BtRemovePage(QWidget *parent) + : BtConfigPage(parent) +{ + namespace DU = util::directory; - m_removeButton = new QPushButton(tr("Remove..."), this); + m_worksGroupBox = new QGroupBox(tr("Select &works to uninstall:"), this); + m_worksGroupBox->setFlat(true); + QVBoxLayout *wLayout = new QVBoxLayout; + wLayout->setContentsMargins(0, 0, 0, 0); + m_worksGroupBox->setLayout(wLayout); + + BtRemovePageTreeModel *treeModel = new BtRemovePageTreeModel(groupingOrderKey, + this); + connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); + + m_bookshelfWidget = new BtBookshelfWidget(this); + m_bookshelfWidget->postFilterModel()->setShowHidden(true); + m_bookshelfWidget->setTreeModel(treeModel); + m_bookshelfWidget->setSourceModel(CSwordBackend::instance()->model()); + m_bookshelfWidget->showHideAction()->setVisible(false); + m_bookshelfWidget->showHideButton()->hide(); + m_bookshelfWidget->treeView()->header()->show(); + m_bookshelfWidget->treeView()->header()->setResizeMode(QHeaderView::ResizeToContents); + wLayout->addWidget(m_bookshelfWidget); + + m_uninstallGroupBox = new QGroupBox(this); + m_uninstallGroupBox->setFlat(true); + retranslateUninstallGroupBox(); + QHBoxLayout *uLayout = new QHBoxLayout; + uLayout->setContentsMargins(0, 0, 0, 0); + m_uninstallGroupBox->setLayout(uLayout); + uLayout->addStretch(1); + + m_removeButton = new QPushButton(tr("&Remove..."), this); m_removeButton->setToolTip(tr("Remove the selected works")); m_removeButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::removepage::remove_icon)); m_removeButton->setEnabled(false); - layout->addWidget(m_removeButton, 3, 1, Qt::AlignRight); + uLayout->addWidget(m_removeButton, 0, Qt::AlignRight); + + Q_ASSERT(qobject_cast(layout()) != 0); + QVBoxLayout *mainLayout = static_cast(layout()); + mainLayout->addWidget(m_worksGroupBox, 1); + mainLayout->addWidget(m_uninstallGroupBox); connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveModules())); - connect(m_model, SIGNAL(moduleChecked(CSwordModuleInfo*, bool)), - this, SLOT(resetRemoveButton())); - connect(m_model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(resetRemoveButton())); + connect(m_bookshelfWidget->treeModel(), SIGNAL(moduleChecked(CSwordModuleInfo*,bool)), + this, SLOT(slotResetRemoveButton())); + connect(m_bookshelfWidget->treeModel(), SIGNAL(rowsRemoved(const QModelIndex&,int,int)), + this, SLOT(slotResetRemoveButton())); } -QString BtRemovePage::label() { - return tr("Remove installed works. Select the works and click Remove button."); +const QIcon &BtRemovePage::icon() const { + return util::directory::getIcon(CResMgr::bookshelfmgr::removepage::icon); } -QString BtRemovePage::iconName() { - return CResMgr::bookshelfmgr::removepage::icon; +QString BtRemovePage::header() const { + return tr("Remove"); } -QString BtRemovePage::header() { - return tr("Remove"); +void BtRemovePage::retranslateUninstallGroupBox() { + int count = m_bookshelfWidget->treeModel()->checkedModules().count(); + if (count > 0) { + m_uninstallGroupBox->setTitle(tr("Start removal of %1 works:") + .arg(count)); + } else { + m_uninstallGroupBox->setTitle(tr("Start removal:")); + } } -void BtRemovePage::resetRemoveButton() { - m_removeButton->setEnabled(!m_model->checkedModules().empty()); +void BtRemovePage::slotResetRemoveButton() { + retranslateUninstallGroupBox(); + m_removeButton->setEnabled(!m_bookshelfWidget->treeModel()->checkedModules().empty()); } void BtRemovePage::slotRemoveModules() { // Do nothing when this signal fires without anything selected to remove: - if (m_model->checkedModules().empty()) return; + if (m_bookshelfWidget->treeModel()->checkedModules().empty()) return; QStringList moduleNames; - foreach (CSwordModuleInfo *m, m_model->checkedModules()) { - moduleNames.append(m->name()); + const int textHeight = fontMetrics().height(); + /// \bug is not working, Qt bug + const QString moduleString(" %4"); + const QString iconDir = util::directory::getIconDir().canonicalPath() + '/'; + Q_FOREACH(const CSwordModuleInfo *m, + m_bookshelfWidget->treeModel()->checkedModules()) + { + const QIcon icon = CSwordModuleInfo::moduleIcon(m); + const QSize iconSize = icon.actualSize(QSize(textHeight, textHeight)); + moduleNames.append(moduleString + .arg(iconDir + CSwordModuleInfo::moduleIconFilename(m)) + .arg(iconSize.width()) + .arg(iconSize.height()) + .arg(m->name())); } const QString message = tr("You selected the following work(s): ") - .append(moduleNames.join(", ")) - .append("\n\n") + .append("

    ") + .append(moduleNames.join(",  ")) + .append("

") .append(tr("Do you really want to remove them from your system?")); if ((util::showQuestion(this, tr("Remove Works?"), message, QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)) { //Yes was pressed. // Update the module list before really removing. Remember deleting the pointers later. - QList toBeDeleted = CPointers::backend()->takeModulesFromList(moduleNames); + QList toBeDeleted = CSwordBackend::instance()->takeModulesFromList(moduleNames); sword::InstallMgr installMgr; QMap mgrDict; //maps config paths to SWMgr objects @@ -131,3 +178,7 @@ void BtRemovePage::slotRemoveModules() { mgrDict.clear(); } } + +void BtRemovePage::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) { + g.saveTo(groupingOrderKey); +} diff --git a/src/frontend/bookshelfmanager/removepage/btremovepage.h b/src/frontend/bookshelfmanager/removepage/btremovepage.h index 2950619..11017d0 100644 --- a/src/frontend/bookshelfmanager/removepage/btremovepage.h +++ b/src/frontend/bookshelfmanager/removepage/btremovepage.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -21,29 +21,36 @@ #include "frontend/bookshelfmanager/removepage/btremovepagetreemodel.h" +class BtBookshelfWidget; +class QGroupBox; class QPushButton; -class QTreeView; class BtRemovePage: public BtConfigPage { Q_OBJECT public: - BtRemovePage(); + BtRemovePage(QWidget *parent = 0); - // BtConfigPage methods: - QString header(); - QString iconName(); - QString label(); + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; - protected slots: + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; + + private: + void retranslateUninstallGroupBox(); + + private slots: void slotRemoveModules(); - void resetRemoveButton(); + void slotResetRemoveButton(); + void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); - protected: - BtRemovePageTreeModel *m_model; + private: + QGroupBox *m_worksGroupBox; + BtBookshelfWidget *m_bookshelfWidget; - QTreeView *m_view; - QPushButton *m_removeButton; + QGroupBox *m_uninstallGroupBox; + QPushButton *m_removeButton; }; #endif diff --git a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.cpp b/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.cpp index fe566d1..a0955b2 100644 --- a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.cpp +++ b/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -13,8 +13,9 @@ #include "frontend/bookshelfmanager/removepage/btremovepagetreemodel.h" -BtRemovePageTreeModel::BtRemovePageTreeModel(QObject *parent) - : BtBookshelfTreeModel(parent) { +BtRemovePageTreeModel::BtRemovePageTreeModel(const QString &configKey, QObject *parent) + : BtBookshelfTreeModel(configKey, parent) +{ setCheckable(true); setDefaultChecked(BtBookshelfTreeModel::UNCHECKED); } diff --git a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.h b/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.h index 619a1ff..14e0a67 100644 --- a/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.h +++ b/src/frontend/bookshelfmanager/removepage/btremovepagetreemodel.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -19,7 +19,7 @@ class BtRemovePageTreeModel: public BtBookshelfTreeModel { Q_OBJECT public: - BtRemovePageTreeModel(QObject *parent = 0); + BtRemovePageTreeModel(const QString &configKey, QObject *parent = 0); int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; diff --git a/src/frontend/btaboutdialog.cpp b/src/frontend/btaboutdialog.cpp new file mode 100644 index 0000000..5b62cf3 --- /dev/null +++ b/src/frontend/btaboutdialog.cpp @@ -0,0 +1,274 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/btaboutdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "util/dialogutil.h" +#include "util/directory.h" + +// Sword includes: +#include + + +#define MAKE_STYLE(t) "" +#define MAKE_HTML(t,x) "" MAKE_STYLE(t) "" + (x) + "" +#define MAKE_LINK(c,u,t) ""; (c) += (t); (c) += "" +#define MAKE_LINK_STATIC(u,t) "" t "" +#define MAKE_CONTR(c,n,r) "
  • " n " (";\ + (c) += (r);\ + (c) += ")
  • " +#define MAKE_CONTR2(c,n,r,r2) "
  • " n " (";\ + (c) += (r);\ + (c) += ", ";\ + (c) += (r2);\ + (c) += ")
  • " + +BtAboutDialog::BtAboutDialog(QWidget *parent, Qt::WindowFlags wflags) + : QDialog(parent, wflags) +{ + setAttribute(Qt::WA_DeleteOnClose); + resize(550, 340); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + QWidget *top = new QWidget(this); + QHBoxLayout *topLayout = new QHBoxLayout; + QLabel *iconLabel = new QLabel(this); + iconLabel->setPixmap(QIcon(util::directory::getIconDir().path() + "/bibletime.svg").pixmap(48)); + topLayout->addWidget(iconLabel); + topLayout->addWidget(new QLabel("

    BibleTime " BT_VERSION "

    "), 1); + top->setLayout(topLayout); + mainLayout->addWidget(top, 0, Qt::AlignCenter); + + m_tabWidget = new QTabWidget(this); + mainLayout->addWidget(m_tabWidget); + + initTab(m_bibletimeTab); + initTab(m_contributorsTab); + initTab(m_swordTab); + initTab(m_qtTab); + initTab(m_licenceTab); + + m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this); + mainLayout->addWidget(m_buttonBox); + setLayout(mainLayout); + + connect(m_buttonBox, SIGNAL(rejected()), + this, SLOT(reject())); + + retranslateUi(); +} + +BtAboutDialog::~BtAboutDialog() { + // Intentionally empty +} + +void BtAboutDialog::initTab(QWebView *&tab) { + tab = new QWebView(this); + m_tabWidget->addTab(tab, ""); + tab->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); + connect(tab, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl))); +} + +void BtAboutDialog::retranslateUi() { + setWindowTitle(tr("About BibleTime")); + + retranslateBtTab(); + retranslateContributorsTab(); + retranslateSwordTab(); + retranslateQtTab(); + retranslateLicenceTab(); + + util::prepareDialogBox(m_buttonBox); +} + +void BtAboutDialog::retranslateBtTab() { + m_tabWidget->setTabText(0, tr("&BibleTime")); + + QString content("

    "); + content += tr("BibleTime is an easy to use but powerful Bible study tool."); + content += "

    "; + content += tr("We are looking for developers and translators. If you would like to join " + "our team, please send an email to %1.") + .arg(MAKE_LINK_STATIC("mailto:info@bibletime.info", "info@bibletime.info")); + content += "

    "; + content += tr("(c)1999-2011, The BibleTime Team"); + content += "

    " MAKE_LINK_STATIC("http://www.bibletime.info", "www.bibletime.info") + "

    "; + m_bibletimeTab->setHtml(MAKE_HTML(m_bibletimeTab, content)); +} + +void BtAboutDialog::retranslateContributorsTab() { + m_tabWidget->setTabText(1, tr("&Contributors")); + + const QString developer(tr("developer")); + const QString designer(tr("designer")); + + /**************************************************************************************** + *** NB!!! Credits are sorted alphabetically by last name! *** + ****************************************************************************************/ + + QString content("

    "); + content += tr("The following people contributed to BibleTime:"); + content += "

      " + MAKE_CONTR(content, "Thomas Abthorpe", tr("documentation and translation manager")) + MAKE_CONTR2(content, "Joachim Ansorg", tr("project founder"), developer) + MAKE_CONTR(content, "David Blue", designer) + MAKE_CONTR(content, "Tim Brodie", developer) + MAKE_CONTR(content, "Timothy R. Butler", designer) + MAKE_CONTR(content, "Jim Campbell", developer) + MAKE_CONTR(content, "Lee Carpenter", developer) + MAKE_CONTR(content, "Jeremy Erickson", tr("packager")) + MAKE_CONTR(content, "Troy A. Griffitts", tr("creator of The Sword Project")) + MAKE_CONTR2(content, "Martin Gruner", tr("project manager"), developer) + MAKE_CONTR(content, "Thomas Hagedorn", tr("domain sponsor")) + MAKE_CONTR(content, "Bob Harman", tr("howto")) + MAKE_CONTR(content, "Gary Holmlund", developer) + MAKE_CONTR(content, "Nikolay Igotti", developer) + MAKE_CONTR(content, "Eeli Kaikkonnen", developer) + MAKE_CONTR(content, "Chris Kujawa", developer) + MAKE_CONTR(content, "Mark Lybarger", developer) + MAKE_CONTR(content, "Luke Mauldin", developer) + MAKE_CONTR(content, "James Ots", designer) + MAKE_CONTR(content, "Andrus Raag", tr("artist")) + MAKE_CONTR(content, "Jaak Ristioja", developer) + MAKE_CONTR(content, "Fred Saalbach", tr("documentation")) + MAKE_CONTR(content, "Gary Sims", developer) + MAKE_CONTR2(content, "Wolfgang Stradner", tr("tester"), tr("usability expert")) + MAKE_CONTR(content, "Kang Sun", developer) + MAKE_CONTR(content, "Thorsten Uhlmann", developer) + MAKE_CONTR(content, "David White", developer) + MAKE_CONTR(content, "Mark Zealey", developer) + "

    "; + + + /**************************************************************************************** + *** NB!!! Credits are sorted alphabetically by last name! *** + ****************************************************************************************/ + content += tr("The following people translated BibleTime into their language:"); + content += "

      " + "
    • Horatiu Alexe
    • " + "
    • Roy Alvear Aguirre
    • " + "
    • Luis Barron
    • " + "
    • Jan Bělohoubek
    • " + "
    • Chun-shek Chan
    • " + "
    • Nouhoun Y. Diarra
    • " + "
    • Rafael Fagundes
    • " + "
    • Eeli Kaikkonen
    • " + "
    • Ilpo Kantonen
    • " + "
    • Pavel Laukko
    • " + "
    • Piotr Markiewicz
    • " + "
    • Géza Novák
    • " + "
    • Gabriel Pérez
    • " + "
    • Igor Plisco
    • " + "
    • Zdenko Podobný
    • " + "
    • Jaak Ristioja
    • " + "
    • Igor Rykhlin
    • " + "
    • Vlad Savitsky
    • " + "
    • Henrik Sonesson
    • " + "
    • Johan van der Lingen
    • " + "
    • Jean Van Schaftingen
    • " + "
    • Roland Teschner
    • " + "
    • Giovanni Tedaldi
    • " + "
    • Dmitry Yurevich
    • " + "
    • Esteban Zeller
    • " + "

    "; + content += tr("Some names may be missing, please email %1 if you notice errors or " + "omissions.").arg(MAKE_LINK_STATIC( + "mailto:bibletime-translations@lists.sourceforge.net", + "bibletime-translations@lists.sourceforge.net")); + content += "

    "; + + m_contributorsTab->setHtml(MAKE_HTML(m_contributorsTab, content)); +} + + +void BtAboutDialog::retranslateSwordTab() { + m_tabWidget->setTabText(2, tr("&SWORD")); + + QString version(sword::SWVersion::currentVersion.getText()); + QString content("

    "); + content += tr("SWORD library version %1").arg(version); + content += "

    "; + content += tr("BibleTime makes use of the SWORD Project. The SWORD Project is the " + "CrossWire Bible Society's free Bible software project. Its purpose is to " + "create cross-platform open-source tools — covered by the GNU " + "General Public License — that allow programmers and Bible " + "societies to write new Bible software more quickly and easily."); + content += "

    "; + content += tr("The SWORD Project: "); + content += MAKE_LINK_STATIC("http://www.crosswire.org/sword/", + "www.crosswire.org/sword") "

    "; + + m_swordTab->setHtml(MAKE_HTML(m_swordTab, content)); +} + +void BtAboutDialog::retranslateQtTab() { + m_tabWidget->setTabText(3, tr("&Qt")); + + QString content("

    "); + content += tr("Qt toolkit version %1").arg(qVersion()); + content += "

    "; + content += tr("This program uses Qt version %1.").arg(qVersion()); + content += "

    "; + content += tr("Qt is a cross-platform application and UI framework, created with C++ " + "language. It has been released under the LGPL license."); + content += " " MAKE_LINK(content, "about:qt", tr("More info...")) "

    "; + m_qtTab->setHtml(MAKE_HTML(m_qtTab, content)); +} + +void BtAboutDialog::retranslateLicenceTab() { + m_tabWidget->setTabText(4, tr("&License")); + + QFile licFile(util::directory::getLicenseDir().path() + "/license.html"); + if (licFile.open(QFile::ReadOnly)) { + + QString text("

    "); + text += tr("BibleTime is released under the GPL license. You can download and use " + "the program for personal, private, public or " + "commercial purposes without restrictions, but can give away or " + "distribute the program only if you also distribute the corresponding source " + "code."); + text += "

    "; + text += tr("The complete legally binding license is below."); + text += "


    "; + + QString content(QTextStream(&licFile).readAll().replace("", text)); + content.replace("", MAKE_STYLE(m_licenceTab), Qt::CaseInsensitive); + m_licenceTab->setHtml(content); + licFile.close(); + } +} + +void BtAboutDialog::linkClicked(const QUrl &url) { + if (url.scheme() == "about") { + if (url.path() == "qt") { + qApp->aboutQt(); + } + } else { + QDesktopServices::openUrl(url); + } +} diff --git a/src/frontend/btaboutdialog.h b/src/frontend/btaboutdialog.h new file mode 100644 index 0000000..34c7bcf --- /dev/null +++ b/src/frontend/btaboutdialog.h @@ -0,0 +1,49 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTABOUTDIALOG_H +#define BTABOUTDIALOG_H + +#include + +class QDialogButtonBox; +class QTabWidget; +class QUrl; +class QWebView; + +class BtAboutDialog: public QDialog { + Q_OBJECT + public: + BtAboutDialog(QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); + ~BtAboutDialog(); + + private: + void initTab(QWebView *&tab); + + void retranslateUi(); + void retranslateBtTab(); + void retranslateContributorsTab(); + void retranslateSwordTab(); + void retranslateQtTab(); + void retranslateLicenceTab(); + + private slots: + void linkClicked(const QUrl &url); + + private: + QTabWidget *m_tabWidget; + QWebView *m_bibletimeTab; + QWebView *m_contributorsTab; + QWebView *m_swordTab; + QWebView *m_qtTab; + QWebView *m_licenceTab; + QDialogButtonBox *m_buttonBox; +}; + +#endif diff --git a/src/frontend/btaboutmoduledialog.cpp b/src/frontend/btaboutmoduledialog.cpp index 9241b71..e4847a6 100644 --- a/src/frontend/btaboutmoduledialog.cpp +++ b/src/frontend/btaboutmoduledialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,28 +17,30 @@ #include "util/dialogutil.h" -BTAboutModuleDialog::BTAboutModuleDialog(QWidget* parent, CSwordModuleInfo* info) - : QDialog(parent) { - //Set the flag to destroy when closed - otherwise eats memory - setAttribute(Qt::WA_DeleteOnClose); - setWindowTitle(tr("Information About %1").arg(info->name())); +BTAboutModuleDialog::BTAboutModuleDialog(CSwordModuleInfo *moduleInfo, QWidget *parent, + Qt::WindowFlags flags) + : QDialog(parent, flags), m_moduleInfo(moduleInfo) +{ resize(650, 400); QVBoxLayout* vboxLayout = new QVBoxLayout(this); - QTextEdit* textEdit = new QTextEdit(this); - textEdit->setReadOnly(true); - textEdit->setTextInteractionFlags(Qt::TextSelectableByMouse); - vboxLayout->addWidget(textEdit); - textEdit->setHtml(info->aboutText()); + m_textEdit = new QTextEdit(this); + m_textEdit->setReadOnly(true); + m_textEdit->setTextInteractionFlags(Qt::TextSelectableByMouse); + vboxLayout->addWidget(m_textEdit); - QDialogButtonBox* buttonBox = new QDialogButtonBox(this); - buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Close); - util::prepareDialogBox(buttonBox); - vboxLayout->addWidget(buttonBox); + m_buttons = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this); + QObject::connect(m_buttons, SIGNAL(rejected()), this, SLOT(reject())); + vboxLayout->addWidget(m_buttons); + retranslateUi(); - QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(moduleInfo, SIGNAL(destroyed()), + this, SLOT(close())); +} +void BTAboutModuleDialog::retranslateUi() { + setWindowTitle(tr("Information About %1").arg(m_moduleInfo->name())); + m_textEdit->setHtml(m_moduleInfo->aboutText()); + util::prepareDialogBox(m_buttons); } diff --git a/src/frontend/btaboutmoduledialog.h b/src/frontend/btaboutmoduledialog.h index 65c0696..eb4b15c 100644 --- a/src/frontend/btaboutmoduledialog.h +++ b/src/frontend/btaboutmoduledialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,17 +14,27 @@ class CSwordModuleInfo; -class QWidget; +class QDialogButtonBox; +class QTextEdit; /** Dialog to show the information about a module. @author The BibleTime team */ -class BTAboutModuleDialog : public QDialog { +class BTAboutModuleDialog: public QDialog { Q_OBJECT public: - BTAboutModuleDialog(QWidget* parent, CSwordModuleInfo* info); + BTAboutModuleDialog(CSwordModuleInfo *moduleInfo, QWidget *parent = 0, + Qt::WindowFlags flags = 0); + + protected: + void retranslateUi(); + + private: + CSwordModuleInfo *m_moduleInfo; + QTextEdit *m_textEdit; + QDialogButtonBox *m_buttons; }; #endif diff --git a/src/frontend/btbookshelfdockwidget.cpp b/src/frontend/btbookshelfdockwidget.cpp index 880c939..9159210 100644 --- a/src/frontend/btbookshelfdockwidget.cpp +++ b/src/frontend/btbookshelfdockwidget.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -14,172 +14,100 @@ #include #include -#include -#include -#include #include -#include #include +#include +#include #include -#include -#include +#include #include -#include "backend/bookshelfmodel/btbookshelfmodel.h" -#include "backend/bookshelfmodel/btbookshelftreemodel.h" -#include "backend/bookshelfmodel/btbookshelffiltermodel.h" #include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" #include "backend/managers/cswordbackend.h" -#include "frontend/btaboutmoduledialog.h" -#include "frontend/mainindex/btbookshelfview.h" -#include "util/cpointers.h" +#include "bibletime.h" +#include "frontend/btbookshelfview.h" +#include "frontend/btbookshelfwidget.h" #include "util/cresmgr.h" #include "util/directory.h" +namespace { +const QString groupingOrderKey("GUI/MainWindow/Docks/Bookshelf/grouping"); +} + +BtBookshelfDockWidget *BtBookshelfDockWidget::m_instance = 0; + BtBookshelfDockWidget::BtBookshelfDockWidget(QWidget *parent, Qt::WindowFlags f) - : QDockWidget(parent, f) { - QSettings *settings(CBTConfig::getConfig()); + : QDockWidget(parent, f) +{ + Q_ASSERT(m_instance == 0); + m_instance = this; setObjectName("BookshelfDock"); - // Setup models: - settings->beginGroup("GUI/MainWindow/Docks/Bookshelf"); - { - QVariant v(settings->value("grouping")); - if (v.canConvert()) { - m_bookshelfTreeModel = new BtBookshelfTreeModel(v.value(), this); - } - else { - m_bookshelfTreeModel = new BtBookshelfTreeModel(this); - } - } - settings->endGroup(); - m_bookshelfTreeModel->setDefaultChecked(BtBookshelfTreeModel::MODULE_HIDDEN); - m_bookshelfTreeModel->setSourceModel(CPointers::backend()->model()); - - m_filterProxyModel = new BtBookshelfFilterModel(this); - m_filterProxyModel->setSourceModel(m_bookshelfTreeModel); // Setup actions and menus: initMenus(); - // Setup widgets: - m_widget = new QWidget(this); - QVBoxLayout *layout(new QVBoxLayout); - layout->setContentsMargins(0, 0, 0, 0); - QHBoxLayout *toolBar(new QHBoxLayout); - // Add a small margin between the edge of the window and the label (looks better) - toolBar->setContentsMargins(3, 0, 0, 0); - m_nameFilterLabel = new QLabel(this); - toolBar->addWidget(m_nameFilterLabel); - - m_nameFilterEdit = new QLineEdit(this); - m_nameFilterEdit->installEventFilter(this); - m_nameFilterLabel->setBuddy(m_nameFilterEdit); - toolBar->addWidget(m_nameFilterEdit); - - m_groupingButton = new QToolButton(this); - m_groupingButton->setPopupMode(QToolButton::InstantPopup); - m_groupingButton->setMenu(m_groupingMenu); - m_groupingButton->setIcon(m_groupingMenu->icon()); - m_groupingButton->setAutoRaise(true); - toolBar->addWidget(m_groupingButton); - - m_showHideButton = new QToolButton(this); - m_showHideButton->setDefaultAction(m_showHideAction); - m_showHideButton->setAutoRaise(true); - toolBar->addWidget(m_showHideButton); - layout->addLayout(toolBar); - - m_view = new BtBookshelfView(this); - m_view->setModel(m_filterProxyModel); - layout->addWidget(m_view); - m_widget->setLayout(layout); - setWidget(m_widget); - - connect(m_nameFilterEdit, SIGNAL(textEdited(QString)), - m_filterProxyModel, SLOT(setNameFilterFixedString(QString))); - connect(m_view, SIGNAL(contextMenuActivated(QPoint)), - this, SLOT(showContextMenu(QPoint))); - connect(m_view, - SIGNAL(moduleContextMenuActivated(CSwordModuleInfo*, QPoint)), - this, SLOT(showItemContextMenu(CSwordModuleInfo*, QPoint))); - connect(m_view, SIGNAL(moduleActivated(CSwordModuleInfo*)), - this, SIGNAL(moduleOpenTriggered(CSwordModuleInfo*))); - connect(m_bookshelfTreeModel, SIGNAL(moduleChecked(CSwordModuleInfo*, bool)), - this, SLOT(moduleChecked(CSwordModuleInfo*, bool))); + // Setup tree model: + m_treeModel = new BtBookshelfTreeModel(groupingOrderKey, this); + + // Get backend model: + BtBookshelfModel *bookshelfModel = CSwordBackend::instance()->model(); + + // Setup bookshelf widgets: + m_bookshelfWidget = new BtBookshelfWidget(this); + m_bookshelfWidget->setTreeModel(m_treeModel); + m_bookshelfWidget->setSourceModel(bookshelfModel); + m_bookshelfWidget->setItemContextMenu(m_itemContextMenu); + /// \bug The correct grouping action is not selected on startup. + + // Setup welcome widgets: + m_welcomeWidget = new QWidget(this); + QVBoxLayout *welcomeLayout = new QVBoxLayout; + m_installLabel = new QLabel(this); + m_installLabel->setWordWrap(true); + m_installLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); + welcomeLayout->addWidget(m_installLabel, 0, Qt::AlignHCenter | Qt::AlignBottom); + m_installButton = new QPushButton(this); + welcomeLayout->addWidget(m_installButton, 0, Qt::AlignHCenter | Qt::AlignTop); + m_welcomeWidget->setLayout(welcomeLayout); + + // Setup stacked widget: + m_stackedWidget = new QStackedWidget(this); + m_stackedWidget->addWidget(m_bookshelfWidget); + m_stackedWidget->addWidget(m_welcomeWidget); + m_stackedWidget->setCurrentWidget(bookshelfModel->moduleList().empty() + ? m_welcomeWidget + : m_bookshelfWidget); + setWidget(m_stackedWidget); + + // Connect signals: + connect(m_bookshelfWidget->treeView(), SIGNAL(moduleActivated(CSwordModuleInfo*)), + this, SLOT(slotModuleActivated(CSwordModuleInfo*))); + connect(m_treeModel, SIGNAL(moduleChecked(CSwordModuleInfo*, bool)), + this, SLOT(slotModuleChecked(CSwordModuleInfo*, bool))); + connect(m_treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); + connect(m_bookshelfWidget->showHideAction(), SIGNAL(toggled(bool)), + m_treeModel, SLOT(setCheckable(bool))); + connect(bookshelfModel, SIGNAL(rowsInserted(const QModelIndex&,int,int)), + this, SLOT(slotModulesChanged())); + connect(bookshelfModel, SIGNAL(rowsRemoved(const QModelIndex&,int,int)), + this, SLOT(slotModulesChanged())); + connect(m_installButton, SIGNAL(clicked()), + BibleTime::instance(), SLOT(slotSwordSetupDialog())); retranslateUi(); } -bool BtBookshelfDockWidget::eventFilter(QObject *object, QEvent *event) { - Q_ASSERT(object == m_nameFilterEdit); - if (event->type() == QEvent::KeyPress) { - QKeyEvent *e = static_cast(event); - switch (e->key()) { - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Enter: - case Qt::Key_Return: - QApplication::sendEvent(m_view, event); - return true; - default: - break; - } - } - return false; -} - void BtBookshelfDockWidget::initMenus() { namespace DU = util::directory; namespace RM = CResMgr::mainIndex; - m_contextMenu = new QMenu(this); - m_groupingMenu = new QMenu(this); - m_contextMenu->addMenu(m_groupingMenu); - m_groupingMenu->setIcon(DU::getIcon(RM::grouping::icon)); - m_groupingActionGroup = new QActionGroup(this); - connect(m_groupingActionGroup, SIGNAL(triggered(QAction*)), - this, SLOT(groupingActionTriggered(QAction*))); - - m_groupingCatLangAction = new QAction(this); - m_groupingCatLangAction->setIcon(DU::getIcon(RM::grouping::icon)); - m_groupingCatLangAction->setChecked(true); - m_groupingActionGroup->addAction(m_groupingCatLangAction); - m_groupingMenu->addAction(m_groupingCatLangAction); - - m_groupingCatAction = new QAction(this); - m_groupingCatAction->setIcon(DU::getIcon(RM::grouping::icon)); - m_groupingActionGroup->addAction(m_groupingCatAction); - m_groupingMenu->addAction(m_groupingCatAction); - - m_groupingLangCatAction = new QAction(this); - m_groupingLangCatAction->setIcon(DU::getIcon(RM::grouping::icon)); - m_groupingActionGroup->addAction(m_groupingLangCatAction); - m_groupingMenu->addAction(m_groupingLangCatAction); - - m_groupingLangAction = new QAction(this); - m_groupingLangAction->setIcon(DU::getIcon(RM::grouping::icon)); - m_groupingActionGroup->addAction(m_groupingLangAction); - m_groupingMenu->addAction(m_groupingLangAction); - - m_groupingNoneAction = new QAction(this); - m_groupingNoneAction->setIcon(DU::getIcon(RM::grouping::icon)); - m_groupingActionGroup->addAction(m_groupingNoneAction); - m_groupingMenu->addAction(m_groupingNoneAction); - - m_showHideAction = new QAction(this); - m_showHideAction->setIcon(DU::getIcon("layer-visible-on.svg")); - m_showHideAction->setCheckable(true); - connect(m_showHideAction, SIGNAL(toggled(bool)), - this, SLOT(showHideEnabled(bool))); - m_contextMenu->addAction(m_showHideAction); - m_itemContextMenu = new QMenu(this); m_itemActionGroup = new QActionGroup(this); connect(m_itemActionGroup, SIGNAL(triggered(QAction*)), - this, SLOT(itemActionTriggered(QAction*))); + this, SLOT(slotItemActionTriggered(QAction*))); m_itemOpenAction = new QAction(this); m_itemActionGroup->addAction(m_itemOpenAction); @@ -212,87 +140,58 @@ void BtBookshelfDockWidget::initMenus() { m_itemAboutAction->setIcon(DU::getIcon(RM::aboutModule::icon)); m_itemActionGroup->addAction(m_itemAboutAction); m_itemContextMenu->addAction(m_itemAboutAction); + + connect(m_itemContextMenu, SIGNAL(aboutToShow()), + this, SLOT(slotPrepareItemContextMenu())); } void BtBookshelfDockWidget::retranslateUi() { setWindowTitle(tr("Bookshelf")); - m_nameFilterLabel->setText(tr("Fi<er:")); - m_groupingButton->setText(tr("Grouping")); - m_groupingButton->setToolTip(tr("Change the grouping of items in the bookshelf.")); - - m_groupingMenu->setTitle(tr("Grouping")); - m_groupingCatLangAction->setText(tr("Category/Language")); - m_groupingCatAction->setText(tr("Category")); - m_groupingLangCatAction->setText(tr("Language/Category")); - m_groupingLangAction->setText(tr("Language")); - m_groupingNoneAction->setText(tr("No grouping")); - m_showHideAction->setText(tr("Show/hide works")); - m_itemOpenAction->setText(tr("&Open")); m_itemEditMenu->setTitle(tr("&Edit")); m_itemEditPlainAction->setText(tr("&Plain text")); m_itemEditHtmlAction->setText(tr("&HTML")); m_itemUnlockAction->setText(tr("&Unlock...")); m_itemAboutAction->setText(tr("&About...")); -} -void BtBookshelfDockWidget::moduleChecked(CSwordModuleInfo *module, bool c) { - module->setHidden(!c); + m_installLabel->setText(tr("There are currently no works installed. Please " + "click the button below to install new works.")); + m_installButton->setText(tr("&Install works...")); } -void BtBookshelfDockWidget::showContextMenu(QPoint pos) { - m_contextMenu->popup(pos); -} - -void BtBookshelfDockWidget::groupingActionTriggered(QAction *action) { - BtBookshelfTreeModel::Grouping g; - if (action == m_groupingCatAction) { - g.append(BtBookshelfTreeModel::GROUP_CATEGORY); - } - else if (action == m_groupingCatLangAction) { - g.append(BtBookshelfTreeModel::GROUP_CATEGORY); - g.append(BtBookshelfTreeModel::GROUP_LANGUAGE); - } - else if (action == m_groupingLangAction) { - g.append(BtBookshelfTreeModel::GROUP_LANGUAGE); - } - else if (action == m_groupingLangCatAction) { - g.append(BtBookshelfTreeModel::GROUP_LANGUAGE); - g.append(BtBookshelfTreeModel::GROUP_CATEGORY); - } - m_bookshelfTreeModel->setGroupingOrder(g); - m_view->setRootIsDecorated(!g.isEmpty()); - - QSettings *settings(CBTConfig::getConfig()); - settings->beginGroup("GUI/MainWindow/Docks/Bookshelf"); - settings->setValue("grouping", QVariant::fromValue(g)); - settings->endGroup(); -} - -void BtBookshelfDockWidget::showHideEnabled(bool enable) { - if (enable) { - m_bookshelfTreeModel->setCheckable(true); - m_filterProxyModel->setShowHidden(true); - } - else { - m_filterProxyModel->setShowHidden(false); - m_bookshelfTreeModel->setCheckable(false); +void BtBookshelfDockWidget::slotModuleActivated(CSwordModuleInfo *module) { + if (!module->isLocked()) { + emit moduleOpenTriggered(module); + } else { + /** + \todo Implement a better unlock dialog, which could incorporate the following + warning message. Actually the whole case when the user tries to open a locked + module needs to be rethought and refactored. + */ + QMessageBox::warning(this, tr("Warning: Module locked!"), + tr("You are trying to access an encrypted module. Please " + "provide an unlock key in the following dialog to open the " + "module.")); + + /// \todo We need to keep the module name because unlocking currently reloads sword. + const QString moduleName(module->name()); + + if (BibleTime::moduleUnlock(module)) { + // Re-initialize module pointer: + module = CSwordBackend::instance()->findModuleByName(moduleName); + Q_ASSERT(module != 0); + + emit moduleOpenTriggered(module); + } } } -void BtBookshelfDockWidget::showItemContextMenu(CSwordModuleInfo *module, - QPoint pos) { - m_itemContextMenu->setProperty("BtModule", qVariantFromValue((void*) module)); - m_itemSearchAction->setText(tr("&Search in %1...").arg(module->name())); - m_itemOpenAction->setEnabled(!module->isLocked()); - m_itemEditMenu->setEnabled(module->isWritable()); - m_itemUnlockAction->setEnabled(module->isLocked()); - - m_itemContextMenu->popup(pos); +void BtBookshelfDockWidget::slotModuleChecked(CSwordModuleInfo *module, bool c) { + module->setHidden(!c); } -void BtBookshelfDockWidget::itemActionTriggered(QAction *action) { +void BtBookshelfDockWidget::slotItemActionTriggered(QAction *action) { CSwordModuleInfo *module((CSwordModuleInfo*) m_itemContextMenu->property("BtModule").value()); if (module == 0) return; @@ -315,3 +214,27 @@ void BtBookshelfDockWidget::itemActionTriggered(QAction *action) { emit moduleAboutTriggered(module); } } + +void BtBookshelfDockWidget::slotPrepareItemContextMenu() { + void *v = m_itemContextMenu->property("BtModule").value(); + CSwordModuleInfo *module = static_cast(v); + m_itemOpenAction->setEnabled(!module->isLocked()); + m_itemSearchAction->setText(tr("&Search in %1...").arg(module->name())); + m_itemSearchAction->setEnabled(!module->isLocked()); + m_itemEditMenu->setEnabled(module->isWritable()); + m_itemUnlockAction->setEnabled(module->isLocked()); +} + +void BtBookshelfDockWidget::slotModulesChanged() { + const BtBookshelfModel *bookshelfModel = CSwordBackend::instance()->model(); + m_stackedWidget->setCurrentWidget(bookshelfModel->moduleList().empty() + ? m_welcomeWidget + : m_bookshelfWidget); +} + +void BtBookshelfDockWidget::slotGroupingOrderChanged( + const BtBookshelfTreeModel::Grouping &g) +{ + g.saveTo(groupingOrderKey); + emit groupingOrderChanged(g); +} diff --git a/src/frontend/btbookshelfdockwidget.h b/src/frontend/btbookshelfdockwidget.h index cfa20e6..58a014b 100644 --- a/src/frontend/btbookshelfdockwidget.h +++ b/src/frontend/btbookshelfdockwidget.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -15,24 +15,28 @@ #include +#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "frontend/btbookshelfwidget.h" + -class CSwordModuleInfo; -class BtBookshelfView; -class BtBookshelfTreeModel; -class BtBookshelfFilterModel; class QAction; class QActionGroup; class QLabel; -class QLineEdit; class QMenu; -class QToolBar; -class QToolButton; +class QPushButton; +class QStackedWidget; class BtBookshelfDockWidget: public QDockWidget { Q_OBJECT public: BtBookshelfDockWidget(QWidget *parent = 0, Qt::WindowFlags f = 0); + static inline BtBookshelfDockWidget *getInstance() { return m_instance; } + + inline const BtBookshelfTreeModel::Grouping &groupingOrder() const { + return m_treeModel->groupingOrder(); + } + signals: void moduleOpenTriggered(CSwordModuleInfo *module); void moduleSearchTriggered(CSwordModuleInfo *module); @@ -40,43 +44,30 @@ class BtBookshelfDockWidget: public QDockWidget { void moduleEditHtmlTriggered(CSwordModuleInfo *module); void moduleUnlockTriggered(CSwordModuleInfo *module); void moduleAboutTriggered(CSwordModuleInfo *module); + void groupingOrderChanged(BtBookshelfTreeModel::Grouping newGrouping); protected: - bool eventFilter(QObject *object, QEvent *event); void initMenus(); void retranslateUi(); protected slots: - void moduleChecked(CSwordModuleInfo *module, bool checked); - void showContextMenu(QPoint pos); - void groupingActionTriggered(QAction *action); - void showHideEnabled(bool enable); - void showItemContextMenu(CSwordModuleInfo *module, QPoint pos); - void itemActionTriggered(QAction *action); + void slotModuleActivated(CSwordModuleInfo *module); + void slotModuleChecked(CSwordModuleInfo *module, bool checked); + void slotItemActionTriggered(QAction *action); + void slotPrepareItemContextMenu(); + void slotModulesChanged(); + void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); protected: - // Models: - BtBookshelfTreeModel *m_bookshelfTreeModel; - BtBookshelfFilterModel *m_filterProxyModel; - - // Widgets: - QWidget *m_widget; - BtBookshelfView *m_view; - QLabel *m_nameFilterLabel; - QLineEdit *m_nameFilterEdit; - QToolButton *m_groupingButton; - QToolButton *m_showHideButton; - - // Popup menus: - QMenu *m_contextMenu; - QMenu *m_groupingMenu; - QActionGroup *m_groupingActionGroup; - QAction *m_groupingCatLangAction; - QAction *m_groupingCatAction; - QAction *m_groupingLangCatAction; - QAction *m_groupingLangAction; - QAction *m_groupingNoneAction; - QAction *m_showHideAction; + BtBookshelfTreeModel *m_treeModel; + + QStackedWidget *m_stackedWidget; + BtBookshelfWidget *m_bookshelfWidget; + QWidget *m_welcomeWidget; + QLabel *m_installLabel; + QPushButton *m_installButton; + + // Item context menu: QMenu *m_itemContextMenu; QActionGroup *m_itemActionGroup; QAction *m_itemOpenAction; @@ -86,6 +77,8 @@ class BtBookshelfDockWidget: public QDockWidget { QAction *m_itemEditHtmlAction; QAction *m_itemUnlockAction; QAction *m_itemAboutAction; + + static BtBookshelfDockWidget *m_instance; }; #endif // BTBOOKSHELFDOCKWIDGET_H diff --git a/src/frontend/btbookshelfgroupingmenu.cpp b/src/frontend/btbookshelfgroupingmenu.cpp new file mode 100644 index 0000000..de2bcf6 --- /dev/null +++ b/src/frontend/btbookshelfgroupingmenu.cpp @@ -0,0 +1,113 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/btbookshelfgroupingmenu.h" + +#include "util/cresmgr.h" +#include "util/directory.h" + + +namespace { +bool groupsInitialized = false; +BtBookshelfTreeModel::Grouping groupingNone(true); +BtBookshelfTreeModel::Grouping groupingCat(true); +BtBookshelfTreeModel::Grouping groupingCatLang; +BtBookshelfTreeModel::Grouping groupingLang(true); +BtBookshelfTreeModel::Grouping groupingLangCat(true); + +inline void initializeGroups() { + Q_ASSERT(groupingNone.empty()); + groupingCat.append(BtBookshelfTreeModel::GROUP_CATEGORY); + Q_ASSERT(groupingCatLang.size() == 2); + Q_ASSERT(groupingCatLang.at(0) == BtBookshelfTreeModel::GROUP_CATEGORY); + Q_ASSERT(groupingCatLang.at(1) == BtBookshelfTreeModel::GROUP_LANGUAGE); + groupingLang.append(BtBookshelfTreeModel::GROUP_LANGUAGE); + groupingLangCat.append(BtBookshelfTreeModel::GROUP_LANGUAGE); + groupingLangCat.append(BtBookshelfTreeModel::GROUP_CATEGORY); + groupsInitialized = true; +} + +inline void setActionRef(QAction *a, const BtBookshelfTreeModel::Grouping &g) { + a->setProperty("groupingPointer", QVariant::fromValue((void*) &g)); +} + +inline const BtBookshelfTreeModel::Grouping &getActionRef(const QAction *a) { + return *((const BtBookshelfTreeModel::Grouping*) a->property("groupingPointer").value()); +} + +} // anonymous namespace + + +void BtBookshelfGroupingMenu::initMenu(bool showNoGrouping) { + namespace DU = util::directory; + namespace RM = CResMgr::mainIndex; + + if (!groupsInitialized) initializeGroups(); + + setIcon(DU::getIcon(RM::grouping::icon)); + + m_groupingActionGroup = new QActionGroup(this); + m_groupingActionGroup->setExclusive(true); + connect(m_groupingActionGroup, SIGNAL(triggered(QAction*)), + this, SLOT(slotGroupingActionTriggered(QAction*))); + + m_groupingCatLangAction = new QAction(this); + m_groupingCatLangAction->setCheckable(true); + setActionRef(m_groupingCatLangAction, groupingCatLang); + m_groupingActionGroup->addAction(m_groupingCatLangAction); + addAction(m_groupingCatLangAction); + + m_groupingCatAction = new QAction(this); + m_groupingCatAction->setCheckable(true); + setActionRef(m_groupingCatAction, groupingCat); + m_groupingActionGroup->addAction(m_groupingCatAction); + addAction(m_groupingCatAction); + + m_groupingLangCatAction = new QAction(this); + m_groupingLangCatAction->setCheckable(true); + setActionRef(m_groupingLangCatAction, groupingLangCat); + m_groupingActionGroup->addAction(m_groupingLangCatAction); + addAction(m_groupingLangCatAction); + + m_groupingLangAction = new QAction(this); + m_groupingLangAction->setCheckable(true); + setActionRef(m_groupingLangAction, groupingLang); + m_groupingActionGroup->addAction(m_groupingLangAction); + addAction(m_groupingLangAction); + + if (showNoGrouping) { + m_groupingNoneAction = new QAction(this); + m_groupingNoneAction->setCheckable(true); + setActionRef(m_groupingNoneAction, groupingNone); + m_groupingActionGroup->addAction(m_groupingNoneAction); + addAction(m_groupingNoneAction); + } else { + m_groupingNoneAction = 0; + } + + retranslateUi(); +} + +void BtBookshelfGroupingMenu::retranslateUi() { + m_groupingCatLangAction->setText(tr("Category/Language")); + m_groupingCatAction->setText(tr("Category")); + m_groupingLangCatAction->setText(tr("Language/Category")); + m_groupingLangAction->setText(tr("Language")); + + if (m_groupingNoneAction != 0) { + m_groupingNoneAction->setText(tr("No grouping")); + } +} + +void BtBookshelfGroupingMenu::slotGroupingActionTriggered(QAction *action) { + emit signalGroupingOrderChanged(getActionRef(action)); +} diff --git a/src/frontend/btbookshelfgroupingmenu.h b/src/frontend/btbookshelfgroupingmenu.h new file mode 100644 index 0000000..83605a7 --- /dev/null +++ b/src/frontend/btbookshelfgroupingmenu.h @@ -0,0 +1,53 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFGROUPINGMENU_H +#define BTBOOKSHELFGROUPINGMENU_H + +#include + +#include + + +class QAction; +class QActionGroup; + +class BtBookshelfGroupingMenu: public QMenu { + Q_OBJECT + public: + explicit inline BtBookshelfGroupingMenu(QWidget *parent = 0) + : QMenu(parent) { initMenu(true); } + + explicit inline BtBookshelfGroupingMenu(bool showNoGrouping, + QWidget *parent = 0) + : QMenu(parent) { initMenu(showNoGrouping); } + + signals: + void signalGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &); + + private: + void initMenu(bool showNoGrouping); + void retranslateUi(); + + private slots: + void slotGroupingActionTriggered(QAction *action); + + private: + QActionGroup *m_groupingActionGroup; + QAction *m_groupingCatLangAction; + QAction *m_groupingCatAction; + QAction *m_groupingLangCatAction; + QAction *m_groupingLangAction; + QAction *m_groupingNoneAction; +}; + +#endif // BTBOOKSHELFGROUPINGMENU_H diff --git a/src/frontend/btbookshelfview.cpp b/src/frontend/btbookshelfview.cpp new file mode 100644 index 0000000..2dfa745 --- /dev/null +++ b/src/frontend/btbookshelfview.cpp @@ -0,0 +1,108 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/btbookshelfview.h" + +#include +#include +#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "backend/drivers/cswordmoduleinfo.h" + + +BtBookshelfView::BtBookshelfView(QWidget *parent) + : QTreeView(parent) +{ + setHeaderHidden(true); + + /* + Uncommenting the following statement will hide the [+]expand/[-]collapse + controls in front of first-level items, which might not be desirable since + hiding them also means that one has to do a total of 2 clicks (double- + click)to expand or collapse top-level items: + */ + // setRootIsDecorated(false); + + connect(this, SIGNAL(activated(QModelIndex)), + this, SLOT(slotItemActivated(QModelIndex))); +} + +BtBookshelfView::~BtBookshelfView() { + // Intentionally empty +} + +CSwordModuleInfo *BtBookshelfView::getModule(const QModelIndex &index) const { + return (CSwordModuleInfo *) model() + ->data(index, BtBookshelfModel::ModulePointerRole).value(); +} + +void BtBookshelfView::keyPressEvent(QKeyEvent *event) { + switch (event->key()) { + case Qt::Key_Menu: + scrollTo(currentIndex()); + { + CSwordModuleInfo *i(getModule(currentIndex())); + QRect itemRect(visualRect(currentIndex())); + QPoint p(viewport()->mapToGlobal(itemRect.bottomLeft())); + if (i == 0) { + emit contextMenuActivated(p); + } + else { + emit moduleContextMenuActivated(i, p); + } + } + event->accept(); + break; + case Qt::Key_Return: + case Qt::Key_Enter: { + QModelIndex i(currentIndex()); + CSwordModuleInfo *m(getModule(i)); + if (m != 0) { + emit moduleActivated(m); + } + else { + setExpanded(i, !isExpanded(i)); + } + } + event->accept(); + break; + default: + QTreeView::keyPressEvent(event); + break; + } +} + +void BtBookshelfView::mousePressEvent(QMouseEvent *event) { + if (event->buttons() == Qt::RightButton) { + QModelIndex clickedItemIndex(indexAt(event->pos())); + if (clickedItemIndex.isValid()) { + setCurrentIndex(clickedItemIndex); + } + CSwordModuleInfo *i(getModule(clickedItemIndex)); + if (i == 0) { + emit contextMenuActivated(mapToGlobal(event->pos())); + } + else { + emit moduleContextMenuActivated(i, mapToGlobal(event->pos())); + } + event->accept(); + } + else { + QTreeView::mousePressEvent(event); + } +} + +void BtBookshelfView::slotItemActivated(const QModelIndex &index) { + CSwordModuleInfo *i(getModule(index)); + if (i != 0) { + emit moduleActivated(i); + } +} diff --git a/src/frontend/btbookshelfview.h b/src/frontend/btbookshelfview.h new file mode 100644 index 0000000..916559a --- /dev/null +++ b/src/frontend/btbookshelfview.h @@ -0,0 +1,43 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFVIEW_H +#define BTBOOKSHELFVIEW_H + +#include + + +class CSwordModuleInfo; + +class BtBookshelfView: public QTreeView { + Q_OBJECT + public: + BtBookshelfView(QWidget *parent = 0); + virtual ~BtBookshelfView(); + + CSwordModuleInfo *getModule(const QModelIndex &index) const; + + signals: + void contextMenuActivated(QPoint pos); + void moduleContextMenuActivated(CSwordModuleInfo *item, + QPoint pos); + void moduleActivated(CSwordModuleInfo *item); + + protected: + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); + + protected slots: + void slotItemActivated(const QModelIndex &index); +}; + +#endif // BTBOOKSHELFVIEW_H diff --git a/src/frontend/btbookshelfwidget.cpp b/src/frontend/btbookshelfwidget.cpp new file mode 100644 index 0000000..d4f162e --- /dev/null +++ b/src/frontend/btbookshelfwidget.cpp @@ -0,0 +1,203 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/btbookshelfwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "backend/bookshelfmodel/btbookshelffiltermodel.h" +#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h" +#include "frontend/bookshelfmanager/removepage/btremovepagetreemodel.h" +#include "frontend/btbookshelfdockwidget.h" +#include "frontend/btbookshelfgroupingmenu.h" +#include "frontend/btbookshelfview.h" +#include "util/cresmgr.h" +#include "util/directory.h" + + +BtBookshelfWidget::BtBookshelfWidget(QWidget *parent, Qt::WindowFlags flags) + : QWidget(parent, flags) + , m_sourceModel(0) + , m_treeModel(0) + , m_leftCornerWidget(0) + , m_rightCornerWidget(0) +{ + // Setup post-filter: + m_postFilterModel = new BtBookshelfFilterModel(this); + + // Init widgets and such: + initActions(); + initMenus(); + initWidgets(); + + // Connect treeview to model: + m_treeView->setModel(m_postFilterModel); + + retranslateUi(); + + connect(m_nameFilterEdit, SIGNAL(textEdited(QString)), + m_postFilterModel, SLOT(setNameFilterFixedString(QString))); + connect(m_treeView, SIGNAL(contextMenuActivated(QPoint)), + this, SLOT(slotShowContextMenu(QPoint))); + connect(m_treeView, SIGNAL(moduleContextMenuActivated(CSwordModuleInfo*, QPoint)), + this, SLOT(slotShowItemContextMenu(CSwordModuleInfo*, QPoint))); +} + +BtBookshelfWidget::~BtBookshelfWidget() { + // Intentionally empty +} + +void BtBookshelfWidget::setSourceModel(QAbstractItemModel *model) { + Q_ASSERT(model != 0); + m_sourceModel = model; + if (m_treeModel != 0) { + m_treeModel->setSourceModel(model); + } +} + +void BtBookshelfWidget::setTreeModel(BtBookshelfTreeModel *model) { + Q_ASSERT(model != 0); + Q_ASSERT(m_treeModel == 0); + m_treeModel = model; + if (m_sourceModel != 0) { + model->setSourceModel(m_sourceModel); + } + m_postFilterModel->setSourceModel(model); +} + +void BtBookshelfWidget::setLeftCornerWidget(QWidget *w) { + delete m_leftCornerWidget; + w->setParent(this); + m_toolBar->insertWidget(0, w, 0); +} + +void BtBookshelfWidget::setRightCornerWidget(QWidget *w) { + delete m_rightCornerWidget; + w->setParent(this); + m_toolBar->insertWidget(m_toolBar->count(), w, 0); +} + +void BtBookshelfWidget::initActions() { + namespace DU = util::directory; + namespace RM = CResMgr::mainIndex; + + m_showHideAction = new QAction(this); + m_showHideAction->setIcon(DU::getIcon("layer-visible-on.svg")); + m_showHideAction->setCheckable(true); + connect(m_showHideAction, SIGNAL(toggled(bool)), + m_postFilterModel, SLOT(setShowHidden(bool))); +} + +void BtBookshelfWidget::initMenus() { + namespace DU = util::directory; + namespace RM = CResMgr::mainIndex; + + // Grouping menu: + m_groupingMenu = new BtBookshelfGroupingMenu(this); + connect(m_groupingMenu, SIGNAL(signalGroupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, SLOT(slotGroupingActionTriggered(BtBookshelfTreeModel::Grouping))); + + // Context menu + m_contextMenu = new QMenu(this); + m_contextMenu->addMenu(m_groupingMenu); + m_contextMenu->addAction(m_showHideAction); + + // Item context menu + m_itemContextMenu = m_contextMenu; +} + +void BtBookshelfWidget::initWidgets() { + QVBoxLayout *layout(new QVBoxLayout); + layout->setContentsMargins(0, 0, 0, 0); + m_toolBar = new QHBoxLayout; + // Add a small margin between the edge of the window and the label (looks better) + m_toolBar->setContentsMargins(3, 0, 0, 0); + m_nameFilterLabel = new QLabel(this); + m_toolBar->addWidget(m_nameFilterLabel); + + m_nameFilterEdit = new QLineEdit(this); + m_nameFilterEdit->installEventFilter(this); + m_nameFilterLabel->setBuddy(m_nameFilterEdit); + m_toolBar->addWidget(m_nameFilterEdit); + + m_groupingButton = new QToolButton(this); + m_groupingButton->setPopupMode(QToolButton::InstantPopup); + m_groupingButton->setMenu(m_groupingMenu); + m_groupingButton->setIcon(m_groupingMenu->icon()); + m_groupingButton->setAutoRaise(true); + m_toolBar->addWidget(m_groupingButton); + + m_showHideButton = new QToolButton(this); + m_showHideButton->setDefaultAction(m_showHideAction); + m_showHideButton->setAutoRaise(true); + m_toolBar->addWidget(m_showHideButton); + layout->addLayout(m_toolBar); + + m_treeView = new BtBookshelfView(this); + layout->addWidget(m_treeView); + setLayout(layout); +} + +void BtBookshelfWidget::retranslateUi() { + m_nameFilterLabel->setText(tr("Fi<er:")); + m_groupingButton->setText(tr("Grouping")); + m_groupingButton->setToolTip(tr("Change the grouping of items in the bookshelf.")); + m_groupingMenu->setTitle(tr("Grouping")); + m_showHideAction->setText(tr("Show/hide works")); +} + +bool BtBookshelfWidget::eventFilter(QObject *object, QEvent *event) { + Q_ASSERT(object == m_nameFilterEdit); + if (event->type() == QEvent::KeyPress) { + QKeyEvent *e = static_cast(event); + switch (e->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Enter: + case Qt::Key_Return: + QApplication::sendEvent(m_treeView, event); + return true; + default: + break; + } + } + return false; +} + +void BtBookshelfWidget::slotGroupingActionTriggered(const BtBookshelfTreeModel::Grouping &grouping) { + m_treeModel->setGroupingOrder(grouping); + m_treeView->setRootIsDecorated(!grouping.isEmpty()); +} + +void BtBookshelfWidget::slotShowContextMenu(const QPoint &pos) { + m_contextMenu->popup(pos); +} + +void BtBookshelfWidget::slotShowItemContextMenu(CSwordModuleInfo *module, const QPoint &pos) +{ + if (m_itemContextMenu != 0) { + m_itemContextMenu->setProperty("BtModule", qVariantFromValue((void*) module)); + m_itemContextMenu->popup(pos); + } else { + m_itemContextMenu = m_contextMenu; + slotShowItemContextMenu(module, pos); + } +} diff --git a/src/frontend/btbookshelfwidget.h b/src/frontend/btbookshelfwidget.h new file mode 100644 index 0000000..3f1e605 --- /dev/null +++ b/src/frontend/btbookshelfwidget.h @@ -0,0 +1,116 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTBOOKSHELFWIDGET_H +#define BTBOOKSHELFWIDGET_H + +#include + +#include + + +class BtBookshelfFilterModel; +class BtBookshelfGroupingMenu; +class BtBookshelfTreeModel; +class BtBookshelfView; +class QAbstractItemModel; +class QAction; +class QActionGroup; +class QHBoxLayout; +class QLabel; +class QLineEdit; +class QMenu; +class QToolButton; + +class BtBookshelfWidget: public QWidget { + Q_OBJECT + public: + explicit BtBookshelfWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~BtBookshelfWidget(); + + void setSourceModel(QAbstractItemModel *model); + + // Getters for models: + inline BtBookshelfTreeModel *treeModel() const { return m_treeModel; } + inline BtBookshelfFilterModel *postFilterModel() const { return m_postFilterModel; } + + // Setters for models: + void setTreeModel(BtBookshelfTreeModel *model); + + // Getters for widgets: + inline QWidget *leftCornerWidget() const { return m_leftCornerWidget; } + inline QLabel *nameFilterLabel() const { return m_nameFilterLabel; } + inline QLineEdit *nameFilterEdit() const { return m_nameFilterEdit; } + inline QToolButton *groupingButton() const { return m_groupingButton; } + inline QToolButton *showHideButton() const { return m_showHideButton; } + inline QWidget *rightCornerWidget() const { return m_rightCornerWidget; } + inline BtBookshelfView *treeView() const { return m_treeView; } + inline BtBookshelfGroupingMenu *groupingMenu() const { return m_groupingMenu; } + inline QMenu *contextMenu() const { return m_contextMenu; } + inline QMenu *itemContextMenu() const { return m_itemContextMenu; } + + // Setters for widgets: + void setLeftCornerWidget(QWidget *w); + void setRightCornerWidget(QWidget *w); + + // Getters for actions: + inline QAction *showHideAction() const { return m_showHideAction; } + + // Setters for context menus: + inline void setContextMenu(QMenu *newMenu) { m_contextMenu = newMenu; } + inline void setItemContextMenu(QMenu *newMenu) { m_itemContextMenu = newMenu; } + + bool eventFilter(QObject *object, QEvent *event); + + protected: + void initActions(); + void initMenus(); + void initWidgets(); + void retranslateUi(); + + protected slots: + void slotGroupingActionTriggered(const BtBookshelfTreeModel::Grouping &grouping); + void slotShowContextMenu(const QPoint &pos); + void slotShowItemContextMenu(CSwordModuleInfo *module, const QPoint &pos); + + private: + // Models: + QAbstractItemModel *m_sourceModel; + BtBookshelfTreeModel *m_treeModel; + BtBookshelfFilterModel *m_postFilterModel; + + // Widgets: + QHBoxLayout *m_toolBar; + QWidget *m_leftCornerWidget; + QWidget *m_rightCornerWidget; + QLabel *m_nameFilterLabel; + QLineEdit *m_nameFilterEdit; + QToolButton *m_groupingButton; + QToolButton *m_showHideButton; + BtBookshelfView *m_treeView; + + // Popup menus: + QMenu *m_contextMenu; + BtBookshelfGroupingMenu *m_groupingMenu; + QAction *m_showHideAction; + QMenu *m_itemContextMenu; + QActionGroup *m_itemActionGroup; + QAction *m_itemOpenAction; + QAction *m_itemSearchAction; + QMenu *m_itemEditMenu; + QAction *m_itemEditPlainAction; + QAction *m_itemEditHtmlAction; + QAction *m_itemUnlockAction; + QAction *m_itemAboutAction; +}; + +#endif // BTBOOKSHELFWIDGET_H diff --git a/src/frontend/btmenuview.cpp b/src/frontend/btmenuview.cpp index ab9fdd1..b7ce9b4 100644 --- a/src/frontend/btmenuview.cpp +++ b/src/frontend/btmenuview.cpp @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -16,135 +16,179 @@ BtMenuView::BtMenuView(QWidget *parent) - : QMenu(parent), m_model(0), m_actions(0) + : QMenu(parent), m_model(0), m_parentIndex(QModelIndex()), m_actions(0) { connect(this, SIGNAL(aboutToShow()), this, SLOT(slotAboutToShow())); connect(this, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHide())); + connect(this, SIGNAL(triggered(QAction*)), + this, SLOT(slotActionTriggered(QAction*))); } BtMenuView::~BtMenuView() { - if (m_actions != 0) { - delete m_actions; - } + delete m_actions; } void BtMenuView::setModel(QAbstractItemModel *model) { m_model = model; + delete m_actions; + m_actions = 0; + m_indexMap.clear(); + m_parentIndex = QModelIndex(); } -void BtMenuView::buildMenu(QMenu *parentMenu, const QModelIndex &parent) { - Q_ASSERT(m_model != 0); +void BtMenuView::setParentIndex(const QModelIndex &parentIndex) { + if (parentIndex.isValid() && parentIndex.model() != m_model) return; + m_parentIndex = parentIndex; +} - int children = m_model->rowCount(parent); - for (int i = 0; i < children; i++) { - QModelIndex child(m_model->index(i, 0, parent)); - QVariant displayData(m_model->data(child, Qt::DisplayRole)); - QVariant iconData(m_model->data(child, Qt::DecorationRole)); - QVariant toolTipData(m_model->data(child, Qt::ToolTipRole)); - QVariant statusTipData(m_model->data(child, Qt::StatusTipRole)); - QVariant whatsThisData(m_model->data(child, Qt::WhatsThisRole)); - - if (m_model->rowCount(child) > 0) { - QMenu *childMenu = new QMenu(parentMenu); - - // Set text: - if (qVariantCanConvert(displayData)) { - childMenu->setTitle(displayData.toString()); - } +void BtMenuView::preBuildMenu() { + // Intentionally empty. Reimplement in subclass if needed. +} - // Set icon: - if (qVariantCanConvert(iconData)) { - childMenu->setIcon(iconData.value()); - } +void BtMenuView::postBuildMenu() { + // Intentionally empty. Reimplement in subclass if needed. +} - // Set tooltip: - if (qVariantCanConvert(toolTipData)) { - childMenu->setToolTip(toolTipData.toString()); - } +QAction *BtMenuView::newAction(QMenu *parentMenu, const QModelIndex &itemIndex) { + QVariant displayData(m_model->data(itemIndex, Qt::DisplayRole)); + QVariant iconData(m_model->data(itemIndex, Qt::DecorationRole)); + QVariant toolTipData(m_model->data(itemIndex, Qt::ToolTipRole)); + QVariant statusTipData(m_model->data(itemIndex, Qt::StatusTipRole)); + QVariant whatsThisData(m_model->data(itemIndex, Qt::WhatsThisRole)); - // Set status tip: - if (qVariantCanConvert(statusTipData)) { - childMenu->setStatusTip(statusTipData.toString()); - } + QAction *childAction = new QAction(parentMenu); - // Set whatsthis: - if (qVariantCanConvert(whatsThisData)) { - childMenu->setWhatsThis(whatsThisData.toString()); - } + // Set text: + if (qVariantCanConvert(displayData)) { + childAction->setText(displayData.toString()); + } - parentMenu->addMenu(childMenu); - buildMenu(childMenu, child); - } else { - QAction *childAction = new QAction(m_actions); + // Set icon: + if (qVariantCanConvert(iconData)) { + childAction->setIcon(iconData.value()); + } - // Set text: - if (qVariantCanConvert(displayData)) { - childAction->setText(displayData.toString()); - } + // Set tooltip: + if (qVariantCanConvert(toolTipData)) { + childAction->setToolTip(toolTipData.toString()); + } - // Set icon: - if (qVariantCanConvert(iconData)) { - childAction->setIcon(iconData.value()); - } + // Set status tip: + if (qVariantCanConvert(statusTipData)) { + childAction->setStatusTip(statusTipData.toString()); + } - // Set tooltip: - if (qVariantCanConvert(toolTipData)) { - childAction->setToolTip(toolTipData.toString()); - } + // Set whatsthis: + if (qVariantCanConvert(whatsThisData)) { + childAction->setWhatsThis(whatsThisData.toString()); + } - // Set status tip: - if (qVariantCanConvert(statusTipData)) { - childAction->setStatusTip(statusTipData.toString()); - } + // Set checkable: + if (m_model->flags(itemIndex).testFlag(Qt::ItemIsUserCheckable)) { + childAction->setCheckable(true); + } - // Set whatsthis: - if (qVariantCanConvert(whatsThisData)) { - childAction->setWhatsThis(whatsThisData.toString()); - } + // Set checked: + QVariant checkData(m_model->data(itemIndex, Qt::CheckStateRole)); + bool ok; + Qt::CheckState state = (Qt::CheckState) checkData.toInt(&ok); + if (ok) { + childAction->setChecked(state == Qt::Checked); + } - // Set checkable: - if (m_model->flags(child).testFlag(Qt::ItemIsUserCheckable)) { - childAction->setCheckable(true); - } + return childAction; +} - // Set checked: - QVariant checkData(m_model->data(child, Qt::CheckStateRole)); - bool ok; - Qt::CheckState state = (Qt::CheckState) checkData.toInt(&ok); - if (ok) { - childAction->setChecked(state == Qt::Checked); - } +QMenu *BtMenuView::newMenu(QMenu *parentMenu, const QModelIndex &itemIndex) { + QVariant displayData(m_model->data(itemIndex, Qt::DisplayRole)); + QVariant iconData(m_model->data(itemIndex, Qt::DecorationRole)); + QVariant toolTipData(m_model->data(itemIndex, Qt::ToolTipRole)); + QVariant statusTipData(m_model->data(itemIndex, Qt::StatusTipRole)); + QVariant whatsThisData(m_model->data(itemIndex, Qt::WhatsThisRole)); + + QMenu *childMenu = new QMenu(parentMenu); + + // Set text: + if (qVariantCanConvert(displayData)) { + childMenu->setTitle(displayData.toString()); + } + + // Set icon: + if (qVariantCanConvert(iconData)) { + childMenu->setIcon(iconData.value()); + } + + // Set tooltip: + if (qVariantCanConvert(toolTipData)) { + childMenu->setToolTip(toolTipData.toString()); + } + // Set status tip: + if (qVariantCanConvert(statusTipData)) { + childMenu->setStatusTip(statusTipData.toString()); + } - // Map index - m_indexMap[childAction] = QPersistentModelIndex(child); + // Set whatsthis: + if (qVariantCanConvert(whatsThisData)) { + childMenu->setWhatsThis(whatsThisData.toString()); + } - // Add action to action group: - m_actions->addAction(childAction); + return childMenu; +} - // Add action to menu: - parentMenu->addAction(childAction); +void BtMenuView::buildMenu(QMenu *parentMenu, const QModelIndex &parentIndex) { + Q_ASSERT(m_model != 0); + Q_ASSERT(m_actions != 0); + + int children = m_model->rowCount(parentIndex); + for (int i = 0; i < children; i++) { + QModelIndex childIndex(m_model->index(i, 0, parentIndex)); + + if (m_model->rowCount(childIndex) > 0) { + QMenu *childMenu = newMenu(parentMenu, childIndex); + + if (childMenu != 0) { + // Add to menu: + parentMenu->addMenu(childMenu); + + // Populate the menu if not prohibited: + QVariant populate(childMenu->property("BtMenuView_NoPopulate")); + if (!populate.isValid() || populate.toBool()) { + buildMenu(childMenu, childIndex); + } + } + } else { + QAction *childAction = newAction(parentMenu, childIndex); + + if (childAction != 0) { + // Map index + m_indexMap.insert(childAction, childIndex); + + // Add action to action group: + childAction->setActionGroup(m_actions); + + // Add action to menu: + parentMenu->addAction(childAction); + } } } } void BtMenuView::slotAboutToShow() { - if (m_actions != 0) { - delete m_actions; - m_actions = 0; - } + delete m_actions; + m_actions = 0; m_indexMap.clear(); - if (m_model == 0) return; + preBuildMenu(); - m_actions = new QActionGroup(this); - connect(m_actions, SIGNAL(triggered(QAction*)), - this, SLOT(slotActionTriggered(QAction*))); + if (m_model != 0) { + m_actions = new QActionGroup(this); - QModelIndex parentIndex; - buildMenu(this, parentIndex); + buildMenu(this, m_parentIndex); + } + postBuildMenu(); } void BtMenuView::slotAboutToHide() { @@ -152,10 +196,9 @@ void BtMenuView::slotAboutToHide() { } void BtMenuView::slotActionTriggered(QAction *action) { - Q_ASSERT(m_indexMap.contains(action)); + if (!m_indexMap.contains(action)) return; QPersistentModelIndex itemIndex(m_indexMap.value(action)); if (itemIndex.isValid()) { emit triggered(itemIndex); } } - diff --git a/src/frontend/btmenuview.h b/src/frontend/btmenuview.h index dc913e4..87c0d90 100644 --- a/src/frontend/btmenuview.h +++ b/src/frontend/btmenuview.h @@ -4,7 +4,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License * version 2.0. * @@ -18,36 +18,127 @@ #include #include + class QAbstractItemModel; class QActionGroup; /** - \warning This menu does not properly handle changes in the source model while - being shown, so beware to check whether the index emitted by - triggered() is valid. + This is a special menu, which shows the contents of an item model. The menu is repopulated + with data from the item model each time before its shown, and it does not in any other way + react to changes in the model. + + The menu is built from items in the model which are below the given parent index. By + default this parent index is invalid. When the menu is about to show, all items directly + below the parent index are inserted. If a child item has children of its own it is inserted + as a QMenu which will be built recursively. Otherwise the child item is inserted as a + QAction which may be triggered by the user. + + When subclassing this menu, reimplement preBuildMenu() and postBuildMenu() to add new menu + items before or after the menu is populated with data from the associated item model. You + can also reimplement newAction() and newMenu() if you further want to tune the appearance + or behaviour of this menu. + + \warning This menu might not properly handle changes in the source model while being shown, + so beware to check whether the index emitted by triggered() is valid. */ class BtMenuView: public QMenu { Q_OBJECT public: BtMenuView(QWidget *parent = 0); - ~BtMenuView(); + virtual ~BtMenuView(); + /** + Sets or resets the data model for this menu and resets the parent index to an + invalid index. + \param[in] model Pointer to the data model to represent. + \warning Do not (re)set the model when the menu is being shown! + */ void setModel(QAbstractItemModel *model); + + /** + Returns a pointer to the data model associated with this menu. + \retval 0 If this menu is not associated to any model. + */ inline QAbstractItemModel *model() const { return m_model; } + /** + Sets or resets the parent index for the items of the associated model, which to + represent. The menu will only show data items below the given index. This function + has no effect if the given index is valid, but does not belong to the model + associated with this menu. + \param[in] parentIndex the new parent index. + \warning (Re)setting the parent index will only take effect the next time the menu + is to be shown. + \warning Changing the model using setModel() will automatically reset this index. + */ + void setParentIndex(const QModelIndex &parentIndex); + + /** + Returns the parent index of the items of the assiciated model, which are to be + represented by this menu. By default this is an invalid index. + */ + QModelIndex parentIndex() const { return m_parentIndex; } + signals: + /** + This signal is emitted when the user activates a menu item corresponding to an + index in the associated model. + \param index The index of the model which was activated. + */ void triggered(QModelIndex index); protected: - void buildMenu(QMenu *parentMenu, const QModelIndex &parent); + /** + This method is called by BtMenuView before populating itself with data from the + model. Reimplement this method to add any menus/actions to this menu before the + items of the menu. The default implementation does nothing. - protected slots: - void slotActionTriggered(QAction *action); + The model might be unset before this method is called. When the menu is about to be + shown, this allows for this method to initialize the model on request. If the model + is unset after this method returns, the menu is not populated with data from the + item model. + */ + virtual void preBuildMenu(); + + /** + This method is called by BtMenuView after populating itself with data from the + model. If there was no model set, this method is still called after preBuildMenu(). + Reimplement this method to add any menus/actions to this menu after the items of + the menu. The default implementation does nothing. + */ + virtual void postBuildMenu(); + + /** + This method is called by BtMenuView to initialize an action to add to this menu. If + the action corresponding to the given index is not to be added to this menu, please + return 0. + \param[in] parentMenu the parent menu under which the new action is to be added. + \param[in] itemIndex the index of the item corresponding to the action. + */ + virtual QAction *newAction(QMenu *parentMenu, const QModelIndex &itemIndex); + + /** + This method is called by BtMenuView to initialize a menu to add to this menu. If + the menu corresponding to the given index is not to be added to this menu, please + return 0. If the menu should not be populated by BtMenuView itself, please use + setProperty("BtMenuView_NoPopulate", true) on the menu to be returned by this + method. + \param[in] parentMenu the parent menu under which the new menu is to be added. + \param[in] itemIndex the index of the item corresponding to the menu. + */ + virtual QMenu *newMenu(QMenu *parentMenu, const QModelIndex &itemIndex); + + private: + void buildMenu(QMenu *parentMenu, const QModelIndex &parentIndex); + + private slots: void slotAboutToShow(); void slotAboutToHide(); + void slotActionTriggered(QAction *action); protected: QAbstractItemModel *m_model; + QPersistentModelIndex m_parentIndex; QActionGroup *m_actions; QMap m_indexMap; }; diff --git a/src/frontend/btmodulechooserdialog.cpp b/src/frontend/btmodulechooserdialog.cpp new file mode 100644 index 0000000..e8f3dd0 --- /dev/null +++ b/src/frontend/btmodulechooserdialog.cpp @@ -0,0 +1,65 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/btmodulechooserdialog.h" + +#include +#include +#include +#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "frontend/btaboutmoduledialog.h" +#include "frontend/btbookshelfview.h" +#include "frontend/btbookshelfwidget.h" +#include "util/dialogutil.h" +#include "util/tool.h" + + +BtModuleChooserDialog::BtModuleChooserDialog(QWidget *parent, Qt::WindowFlags flags) + : QDialog(parent, flags) +{ + QVBoxLayout *mainLayout = new QVBoxLayout; + + m_captionLabel = new QLabel(this); + mainLayout->addWidget(m_captionLabel); + + m_bookshelfWidget = new BtBookshelfWidget(this); + connect(m_bookshelfWidget->treeView(), SIGNAL(moduleActivated(CSwordModuleInfo*)), + this, SLOT(slotModuleAbout(CSwordModuleInfo*))); + mainLayout->addWidget(m_bookshelfWidget); + + m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, + Qt::Horizontal, this); + connect(m_buttonBox, SIGNAL(accepted()), + this, SLOT(accept())); + connect(m_buttonBox, SIGNAL(rejected()), + this, SLOT(reject())); + mainLayout->addWidget(m_buttonBox); + + setLayout(mainLayout); + + retranslateUi(); +} + +BtModuleChooserDialog::~BtModuleChooserDialog() { + // Intentionally empty +} + +void BtModuleChooserDialog::retranslateUi() { + util::prepareDialogBox(m_buttonBox); +} + +void BtModuleChooserDialog::slotModuleAbout(CSwordModuleInfo *module) { + BTAboutModuleDialog *dialog = new BTAboutModuleDialog(module, this); + dialog->setAttribute(Qt::WA_DeleteOnClose); // Destroy dialog when closed + dialog->show(); + dialog->raise(); +} diff --git a/src/frontend/btmodulechooserdialog.h b/src/frontend/btmodulechooserdialog.h new file mode 100644 index 0000000..706088c --- /dev/null +++ b/src/frontend/btmodulechooserdialog.h @@ -0,0 +1,48 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTMODULECHOOSERDIALOG_H +#define BTMODULECHOOSERDIALOG_H + +#include + +#include "frontend/btbookshelfwidget.h" + + +class CSwordModuleInfo; +class QDialogButtonBox; +class QLabel; + +class BtModuleChooserDialog : public QDialog { + Q_OBJECT + public: + virtual ~BtModuleChooserDialog(); + + protected: + explicit BtModuleChooserDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + + void retranslateUi(); + + inline QLabel *label() const { return m_captionLabel; } + inline BtBookshelfWidget *bookshelfWidget() const { return m_bookshelfWidget; } + inline QDialogButtonBox *buttonBox() const { return m_buttonBox; } + + protected slots: + void slotModuleAbout(CSwordModuleInfo *module); + + private: + QLabel *m_captionLabel; + BtBookshelfWidget *m_bookshelfWidget; + QDialogButtonBox *m_buttonBox; +}; + +#endif // BTMODULECHOOSERDIALOG_H diff --git a/src/frontend/btmoduleindexdialog.cpp b/src/frontend/btmoduleindexdialog.cpp new file mode 100644 index 0000000..0fa879e --- /dev/null +++ b/src/frontend/btmoduleindexdialog.cpp @@ -0,0 +1,103 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/btmoduleindexdialog.h" + +#include +#include +#include "backend/managers/cswordbackend.h" + + +QMutex BtModuleIndexDialog::m_singleInstanceMutex; + +bool BtModuleIndexDialog::indexAllModules( + const QList &modules) +{ + QMutexLocker lock(&m_singleInstanceMutex); + + if (modules.empty()) return true; + + BtModuleIndexDialog d(modules.size()); + d.show(); + d.raise(); + return d.indexAllModules2(modules); +} + +BtModuleIndexDialog::BtModuleIndexDialog(int numModules) + : QProgressDialog(tr("Preparing to index modules..."), tr("Cancel"), 0, + numModules * 100, 0), + m_currentModuleIndex(0) +{ + setWindowTitle(tr("Creating indices")); + setModal(true); +} + +bool BtModuleIndexDialog::indexAllModules2( + const QList &modules) +{ + bool success = true; + + QList indexedModules; + Q_FOREACH(const CSwordModuleInfo *cm, modules) { + Q_ASSERT(!cm->hasIndex()); + + /// \warning const_cast + CSwordModuleInfo *m = const_cast(cm); + + /* + Keep track of created indices to delete them on failure or + cancellation: + */ + indexedModules.append(m); + + connect(this, SIGNAL(canceled()), + m, SLOT(cancelIndexing())); + connect(m, SIGNAL(indexingFinished()), + this, SLOT(slotFinished())); + connect(m, SIGNAL(indexingProgress(int)), + this, SLOT(slotModuleProgress(int))); + + // Single module indexing blocks until finished: + setLabelText(tr("Creating index for work: %1").arg(m->name())); + m->buildIndex(); + m_currentModuleIndex++; + + disconnect(this, SIGNAL(canceled()), + m, SLOT(cancelIndexing())); + disconnect(m, SIGNAL(indexingFinished()), + this, SLOT(slotFinished())); + disconnect(m, SIGNAL(indexingProgress(int)), + this, SLOT(slotModuleProgress(int))); + + if (wasCanceled()) { + success = false; + break; + } + } + + if (!success) { + // Delete already created indices: + Q_FOREACH(CSwordModuleInfo *m, indexedModules) { + if (m->hasIndex()) { + m->deleteIndex(); + } + } + } + return success; +} + +void BtModuleIndexDialog::slotModuleProgress(int percentage) { + setValue(m_currentModuleIndex * 100 + percentage); + qApp->processEvents(); +} + +void BtModuleIndexDialog::slotFinished() { + setValue(m_currentModuleIndex * 100 + 100); + qApp->processEvents(); +} diff --git a/src/frontend/btmoduleindexdialog.h b/src/frontend/btmoduleindexdialog.h new file mode 100644 index 0000000..29a13c4 --- /dev/null +++ b/src/frontend/btmoduleindexdialog.h @@ -0,0 +1,65 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTMODULEINDEXDIALOG_H +#define BTMODULEINDEXDIALOG_H + +#include + +#include + + +class CSwordModuleInfo; + +/** + This dialog is used to index a list of modules and to show progress for that. + While the indexing is in progress it creates a blocking, top level dialog which shows the progress + * while the indexing is done. +*/ +class BtModuleIndexDialog: public QProgressDialog { + Q_OBJECT + Q_DISABLE_COPY(BtModuleIndexDialog) + + public: /* Methods: */ + /** + Creates and shows the indexing progress dialog and starts the actual + indexing. It shows the dialog with progress information. In case + indexing some module is unsuccessful or cancelled, any indices that + were created for other given modules are deleted. After indexing, the + dialog is closed. + \param[in] modules The list of modules to index. + \pre all given modules are unindexed + \returns whether the indexing was finished successfully. + */ + static bool indexAllModules(const QList &modules); + + private: /* Methods: */ + BtModuleIndexDialog(int numModules); + + /** + Shows the indexing progress dialog and starts the actual indexing. It + shows the dialog with progress information. In case indexing some + module is unsuccessful or cancelled, any indices that were created for + other given modules are deleted. After indexing, the dialog is closed. + \param[in] modules The list of modules to index. + \pre all given modules are unindexed + \returns whether the indexing was finished successfully. + */ + bool indexAllModules2(const QList &modules); + + private slots: + void slotModuleProgress(int percentage); + void slotFinished(); + + private: /* Fields: */ + static QMutex m_singleInstanceMutex; + int m_currentModuleIndex; +}; + +#endif diff --git a/src/frontend/btopenworkaction.cpp b/src/frontend/btopenworkaction.cpp new file mode 100644 index 0000000..9f33fc5 --- /dev/null +++ b/src/frontend/btopenworkaction.cpp @@ -0,0 +1,111 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/btopenworkaction.h" + +#include "backend/bookshelfmodel/btbookshelffiltermodel.h" +#include "backend/managers/cswordbackend.h" +#include "frontend/btbookshelfgroupingmenu.h" +#include "util/directory.h" + + +BtOpenWorkActionMenu::BtOpenWorkActionMenu(const QString &groupingConfigKey, + QWidget *parent) + : BtMenuView(parent), m_treeModel(0), m_postFilterModel(0), + m_groupingConfigKey(groupingConfigKey) +{ + // Setup models: + m_treeModel = new BtBookshelfTreeModel(groupingConfigKey, this); + m_postFilterModel = new BtBookshelfFilterModel(this); + m_postFilterModel->setSourceModel(m_treeModel); + setModel(m_postFilterModel); + + m_groupingMenu = new BtBookshelfGroupingMenu(false, this); + + connect(this, SIGNAL(triggered(QModelIndex)), + this, SLOT(slotIndexTriggered(QModelIndex))); + connect(m_groupingMenu, SIGNAL(signalGroupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, SLOT(slotGroupingActionTriggered(BtBookshelfTreeModel::Grouping))); + + retranslateUi(); +} + +BtOpenWorkActionMenu::~BtOpenWorkActionMenu() { + // Intentionally empty +} + +void BtOpenWorkActionMenu::setSourceModel(QAbstractItemModel *model) { + m_treeModel->setSourceModel(model); +} + +void BtOpenWorkActionMenu::retranslateUi() { + m_groupingMenu->setTitle(tr("&Grouping order")); + m_groupingMenu->setStatusTip(tr("Sets the grouping order for the items in " + "this menu.")); +} + +void BtOpenWorkActionMenu::postBuildMenu() { + addSeparator(); + addMenu(m_groupingMenu); +} + +void BtOpenWorkActionMenu::slotIndexTriggered(const QModelIndex &index) { + static const int MPR = BtBookshelfModel::ModulePointerRole; + + CSwordModuleInfo *i; + i = static_cast(model()->data(index, MPR).value()); + if (i != 0) { + emit triggered(i); + } +} + +void BtOpenWorkActionMenu::slotGroupingActionTriggered(const BtBookshelfTreeModel::Grouping &grouping) { + m_treeModel->setGroupingOrder(grouping); + grouping.saveTo(m_groupingConfigKey); +} + +BtOpenWorkAction::BtOpenWorkAction(const QString &groupingConfigKey, + QObject *parent) + : QAction(parent) +{ + m_menu = new BtOpenWorkActionMenu(groupingConfigKey); + m_menu->setSourceModel(CSwordBackend::instance()->model()); + + setMenu(m_menu); + setIcon(util::directory::getIcon("folder-open.svg")); + retranslateUi(); + slotModelChanged(); + + BtBookshelfFilterModel *filterModel = m_menu->postFilterModel(); + connect(m_menu, SIGNAL(triggered(CSwordModuleInfo*)), + this, SIGNAL(triggered(CSwordModuleInfo*))); + connect(filterModel, SIGNAL(layoutChanged()), + this, SLOT(slotModelChanged())); + connect(filterModel, SIGNAL(modelReset()), + this, SLOT(slotModelChanged())); + connect(filterModel, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(slotModelChanged())); + connect(filterModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(slotModelChanged())); +} + +BtOpenWorkAction::~BtOpenWorkAction() { + delete m_menu; +} + +void BtOpenWorkAction::retranslateUi() { + setText(tr("&Open work")); +} + +void BtOpenWorkAction::slotModelChanged() { + setEnabled(m_menu->postFilterModel()->rowCount() > 0); +} diff --git a/src/frontend/btopenworkaction.h b/src/frontend/btopenworkaction.h new file mode 100644 index 0000000..6b28908 --- /dev/null +++ b/src/frontend/btopenworkaction.h @@ -0,0 +1,82 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTOPENWORKACTION_H +#define BTOPENWORKACTION_H + +#include +#include "frontend/btmenuview.h" + +#include "backend/bookshelfmodel/btbookshelftreemodel.h" + + +class BtBookshelfGroupingMenu; +class BtBookshelfTreeModel; +class BtBookshelfFilterModel; +class CSwordModuleInfo; + +class BtOpenWorkActionMenu: public BtMenuView { + Q_OBJECT + public: + BtOpenWorkActionMenu(const QString &groupingConfigKey, + QWidget *parent = 0); + ~BtOpenWorkActionMenu(); + + void setSourceModel(QAbstractItemModel *model); + inline QAbstractItemModel *sourceModel() const { return m_treeModel->sourceModel(); } + inline BtBookshelfTreeModel *treeModel() const { return m_treeModel; } + inline BtBookshelfFilterModel *postFilterModel() const { return m_postFilterModel; } + + signals: + void triggered(CSwordModuleInfo *module); + + private: + void retranslateUi(); + + /* Reimplemented from BtMenuView. */ + virtual void postBuildMenu(); + + private slots: + void slotIndexTriggered(const QModelIndex &index); + void slotGroupingActionTriggered(const BtBookshelfTreeModel::Grouping &grouping); + + private: + // Models: + BtBookshelfTreeModel *m_treeModel; + BtBookshelfFilterModel *m_postFilterModel; + + // Grouping menu: + BtBookshelfGroupingMenu *m_groupingMenu; + const QString m_groupingConfigKey; +}; + +class BtOpenWorkAction: public QAction { + Q_OBJECT + public: + explicit BtOpenWorkAction(const QString &groupingConfigKey, + QObject *parent = 0); + ~BtOpenWorkAction(); + + signals: + void triggered(CSwordModuleInfo *module); + + protected: + void retranslateUi(); + + private slots: + void slotModelChanged(); + + private: + BtOpenWorkActionMenu *m_menu; +}; + +#endif // BTOPENWORKACTION_H diff --git a/src/frontend/cdragdrop.cpp b/src/frontend/cdragdrop.cpp index d595162..657c83e 100644 --- a/src/frontend/cdragdrop.cpp +++ b/src/frontend/cdragdrop.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 2007 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -44,6 +44,9 @@ const BookmarkItem& BTMimeData::bookmark() const { return m_bookmarkList.first(); } -/** Creates a new bookmark item. */ -BookmarkItem::BookmarkItem(QString module, QString key, QString description) - : m_moduleName(module), m_key(key), m_description(description) {} +BookmarkItem::BookmarkItem(const QString &module, const QString &key, + const QString &description) + : m_moduleName(module), m_key(key), m_description(description) +{ + // Intentionally empty +} diff --git a/src/frontend/cdragdrop.h b/src/frontend/cdragdrop.h index 3c4481f..37b2052 100644 --- a/src/frontend/cdragdrop.h +++ b/src/frontend/cdragdrop.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 2007 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,30 +15,36 @@ #include -/** Class which represents a bookmark. -* Includes key, module name and description, all QStrings which have getter methods. -* Can be created only through BTMimeData object. +/** + Class which represents a bookmark. Includes key, module name and description, + all QStrings which have getter methods. Can be created only through + BTMimeData object. */ class BookmarkItem { + friend class BTMimeData; public: /** Returns the key */ - const QString& key() const { + inline const QString &key() const { return m_key; } /** Returns the module name */ - const QString& module() const { + inline const QString &module() const { return m_moduleName; - } ; + } /** Returns the bookmark description */ - const QString& description() const { + inline const QString &description() const { return m_description; - }; + } + + protected: + /** Creates a new bookmark item. */ + BookmarkItem(const QString &module, const QString &key, + const QString &description); + protected: - friend class BTMimeData; - BookmarkItem(QString, QString, QString); - QString m_moduleName; //the module which is used by this item - QString m_key; //the key of a bookmark - QString m_description; //the description of a bookmark + QString m_moduleName; /**< The module which is used by this item. */ + QString m_key; /**< The key of a bookmark. */ + QString m_description; /**< The description of a bookmark. */ }; diff --git a/src/frontend/cexportmanager.cpp b/src/frontend/cexportmanager.cpp index 008963a..eaa0894 100644 --- a/src/frontend/cexportmanager.cpp +++ b/src/frontend/cexportmanager.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/cexportmanager.h" -#include +#include #include #include #include @@ -35,7 +35,12 @@ using namespace Rendering; using namespace Printing; -CExportManager::CExportManager(const QString& caption, const bool showProgress, const QString& progressLabel, const CSwordBackend::FilterOptions filterOptions, const CSwordBackend::DisplayOptions displayOptions) { +CExportManager::CExportManager(const QString &caption, + const bool showProgress, + const QString &progressLabel, + const FilterOptions &filterOptions, + const DisplayOptions &displayOptions) +{ m_caption = !caption.isEmpty() ? caption : QString::fromLatin1("BibleTime"); m_progressLabel = progressLabel; m_filterOptions = filterOptions; @@ -56,7 +61,7 @@ bool CExportManager::saveKey(CSwordKey* key, const Format format, const bool add return false; } - CSwordBackend::FilterOptions filterOptions = m_filterOptions; + FilterOptions filterOptions = m_filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -65,7 +70,7 @@ bool CExportManager::saveKey(CSwordKey* key, const Format format, const bool add filterOptions.textualVariants = false; CHTMLExportRendering::Settings settings(addText); - boost::scoped_ptr render ( + QSharedPointer render ( (format == HTML) ? new CHTMLExportRendering(settings, m_displayOptions, filterOptions) : new CPlainTextExportRendering(settings, m_displayOptions, filterOptions) @@ -75,7 +80,7 @@ bool CExportManager::saveKey(CSwordKey* key, const Format format, const bool add QString startKey; QString stopKey; - QList modules; + QList modules; modules.append(key->module()); CSwordVerseKey *vk = dynamic_cast(key); @@ -94,8 +99,14 @@ bool CExportManager::saveKey(CSwordKey* key, const Format format, const bool add return false; } -bool CExportManager::saveKeyList(sword::ListKey* list, CSwordModuleInfo* module, const Format format, const bool addText) { - if (!list->Count()) +bool CExportManager::saveKeyList(const sword::ListKey &l, + const CSwordModuleInfo *module, + Format format, + bool addText) +{ + /// \warning This is a workaround for Sword constness + sword::ListKey list = l; + if (!list.Count()) return false; const QString filename = getSaveFileName(format); @@ -103,7 +114,7 @@ bool CExportManager::saveKeyList(sword::ListKey* list, CSwordModuleInfo* module, return false; } - CSwordBackend::FilterOptions filterOptions = m_filterOptions; + FilterOptions filterOptions = m_filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -112,7 +123,7 @@ bool CExportManager::saveKeyList(sword::ListKey* list, CSwordModuleInfo* module, filterOptions.textualVariants = false; CHTMLExportRendering::Settings settings(addText); - boost::scoped_ptr render ( + QSharedPointer render ( (format == HTML) ? new CHTMLExportRendering(settings, m_displayOptions, filterOptions) : new CPlainTextExportRendering(settings, m_displayOptions, filterOptions) @@ -120,16 +131,16 @@ bool CExportManager::saveKeyList(sword::ListKey* list, CSwordModuleInfo* module, CTextRendering::KeyTree tree; - setProgressRange(list->Count()); + setProgressRange(list.Count()); CTextRendering::KeyTreeItem::Settings itemSettings; itemSettings.highlight = false; - *list = sword::TOP; - while (!list->Error() && !progressWasCancelled()) { - tree.append( new CTextRendering::KeyTreeItem(QString::fromLocal8Bit((const char*)(*list)) , module, itemSettings) ); + list.setPosition(sword::TOP); + while (!list.Error() && !progressWasCancelled()) { + tree.append( new CTextRendering::KeyTreeItem(QString::fromLocal8Bit((const char*)list) , module, itemSettings) ); incProgress(); - (*list)++; + list.increment(); } const QString text = render->renderKeyTree(tree); @@ -142,7 +153,10 @@ bool CExportManager::saveKeyList(sword::ListKey* list, CSwordModuleInfo* module, return false; } -bool CExportManager::saveKeyList(QList& list, const Format format, const bool addText ) { +bool CExportManager::saveKeyList(const QList &list, + Format format, + bool addText) +{ if (!list.count()) return false; @@ -151,7 +165,7 @@ bool CExportManager::saveKeyList(QList& list, const Format format, c return false; } - CSwordBackend::FilterOptions filterOptions = m_filterOptions; + FilterOptions filterOptions = m_filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -160,7 +174,7 @@ bool CExportManager::saveKeyList(QList& list, const Format format, c filterOptions.textualVariants = false; CHTMLExportRendering::Settings settings(addText); - boost::scoped_ptr render ( + QSharedPointer render ( (format == HTML) ? new CHTMLExportRendering(settings, m_displayOptions, filterOptions) : new CPlainTextExportRendering(settings, m_displayOptions, filterOptions) @@ -197,7 +211,7 @@ bool CExportManager::copyKey(CSwordKey* key, const Format format, const bool add return false; } - CSwordBackend::FilterOptions filterOptions = m_filterOptions; + FilterOptions filterOptions = m_filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -206,7 +220,7 @@ bool CExportManager::copyKey(CSwordKey* key, const Format format, const bool add filterOptions.textualVariants = false; CHTMLExportRendering::Settings settings(addText); - boost::scoped_ptr render ( + QSharedPointer render ( (format == HTML) ? new CHTMLExportRendering(settings, m_displayOptions, filterOptions) : new CPlainTextExportRendering(settings, m_displayOptions, filterOptions) @@ -216,7 +230,7 @@ bool CExportManager::copyKey(CSwordKey* key, const Format format, const bool add QString startKey; QString stopKey; - QList modules; + QList modules; modules.append(key->module()); CSwordVerseKey *vk = dynamic_cast(key); @@ -235,11 +249,16 @@ bool CExportManager::copyKey(CSwordKey* key, const Format format, const bool add return true; } -bool CExportManager::copyKeyList(sword::ListKey* list, CSwordModuleInfo* module, const Format format, const bool addText) { - if (!list->Count()) +bool CExportManager::copyKeyList(const sword::ListKey &l, + const CSwordModuleInfo *module, + Format format, + bool addText) +{ + sword::ListKey list = l; + if (!list.Count()) return false; - CSwordBackend::FilterOptions filterOptions = m_filterOptions; + FilterOptions filterOptions = m_filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -248,7 +267,7 @@ bool CExportManager::copyKeyList(sword::ListKey* list, CSwordModuleInfo* module, filterOptions.textualVariants = false; CHTMLExportRendering::Settings settings(addText); - boost::scoped_ptr render ( + QSharedPointer render ( (format == HTML) ? new CHTMLExportRendering(settings, m_displayOptions, filterOptions) : new CPlainTextExportRendering(settings, m_displayOptions, filterOptions) @@ -258,11 +277,11 @@ bool CExportManager::copyKeyList(sword::ListKey* list, CSwordModuleInfo* module, CTextRendering::KeyTreeItem::Settings itemSettings; itemSettings.highlight = false; - *list = sword::TOP; - while (!list->Error() && !progressWasCancelled()) { - tree.append( new CTextRendering::KeyTreeItem(QString::fromLocal8Bit((const char*)(*list)) , module, itemSettings) ); + list.setPosition(sword::TOP); + while (!list.Error() && !progressWasCancelled()) { + tree.append( new CTextRendering::KeyTreeItem(QString::fromLocal8Bit((const char*)list) , module, itemSettings) ); - (*list)++; + list.increment(); } const QString text = render->renderKeyTree(tree); @@ -271,11 +290,14 @@ bool CExportManager::copyKeyList(sword::ListKey* list, CSwordModuleInfo* module, } -bool CExportManager::copyKeyList(QList& list, const Format format, const bool addText ) { +bool CExportManager::copyKeyList(const QList &list, + Format format, + bool addText) +{ if (!list.count()) return false; - CSwordBackend::FilterOptions filterOptions = m_filterOptions; + FilterOptions filterOptions = m_filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -284,7 +306,7 @@ bool CExportManager::copyKeyList(QList& list, const Format format, c filterOptions.textualVariants = false; CHTMLExportRendering::Settings settings(addText); - boost::scoped_ptr render ( + QSharedPointer render ( (format == HTML) ? new CHTMLExportRendering(settings, m_displayOptions, filterOptions) : new CPlainTextExportRendering(settings, m_displayOptions, filterOptions) @@ -310,31 +332,42 @@ bool CExportManager::copyKeyList(QList& list, const Format format, c return true; } -bool CExportManager::printKeyList(sword::ListKey* list, CSwordModuleInfo* module, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { +bool CExportManager::printKeyList(const sword::ListKey &l, + const CSwordModuleInfo *module, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ + /// \warning This is a workaround for Sword constness + sword::ListKey list = l; CPrinter::KeyTreeItem::Settings settings; CPrinter::KeyTree tree; QString startKey, stopKey; - setProgressRange(list->Count()); - - (*list) = sword::TOP; - while (!list->Error() && !progressWasCancelled()) { - sword::VerseKey* vk = dynamic_cast(list); - if (vk) { - startKey = QString::fromUtf8((const char*)(vk->LowerBound()) ); - stopKey = QString::fromUtf8((const char*)(vk->UpperBound()) ); - tree.append( new CPrinter::KeyTreeItem(startKey, stopKey, module, settings) ); + setProgressRange(list.Count()); + + list.setPosition(sword::TOP); + while (!list.Error() && !progressWasCancelled()) { + if (dynamic_cast(l) != 0) { + const sword::VerseKey &vk = static_cast(l); + startKey = QString::fromUtf8((const char*) vk.LowerBound()); + stopKey = QString::fromUtf8((const char*) vk.UpperBound()); + tree.append(new CTextRendering::KeyTreeItem(startKey, + stopKey, + module, + settings)); } else { startKey = QString::fromUtf8((const char*) * list); - tree.append( new CPrinter::KeyTreeItem(startKey, module, settings) ); + tree.append(new CTextRendering::KeyTreeItem(startKey, + module, + settings)); } - (*list)++; + list.increment(); incProgress(); } - boost::scoped_ptr printer(new CPrinter(0, displayOptions, filterOptions)); + QSharedPointer printer(new CPrinter(0, displayOptions, filterOptions)); if (!progressWasCancelled()) { printer->printKeyTree(tree); @@ -345,7 +378,12 @@ bool CExportManager::printKeyList(sword::ListKey* list, CSwordModuleInfo* module return false; } -bool CExportManager::printKey( CSwordModuleInfo* module, const QString& startKey, const QString& stopKey, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions ) { +bool CExportManager::printKey(const CSwordModuleInfo *module, + const QString &startKey, + const QString &stopKey, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ CPrinter::KeyTreeItem::Settings settings; settings.keyRenderingFace = displayOptions.verseNumbers @@ -360,12 +398,15 @@ bool CExportManager::printKey( CSwordModuleInfo* module, const QString& startKey tree.append( new CPrinter::KeyTreeItem(startKey, module, settings) ); } - boost::scoped_ptr printer(new CPrinter(0, displayOptions, filterOptions)); + QSharedPointer printer(new CPrinter(0, displayOptions, filterOptions)); printer->printKeyTree(tree); return true; } -bool CExportManager::printKey( CSwordKey* key, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { +bool CExportManager::printKey(const CSwordKey *key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ CPrinter::KeyTreeItem::Settings settings; settings.keyRenderingFace = displayOptions.verseNumbers @@ -375,13 +416,15 @@ bool CExportManager::printKey( CSwordKey* key, CSwordBackend::DisplayOptions dis CPrinter::KeyTree tree; tree.append( new CPrinter::KeyTreeItem(key->key(), key->module(), settings) ); - boost::scoped_ptr printer(new CPrinter(0, displayOptions, filterOptions)); + QSharedPointer printer(new CPrinter(0, displayOptions, filterOptions)); printer->printKeyTree(tree); return true; } -/** Prints a key using the hyperlink created by CReferenceManager. */ -bool CExportManager::printByHyperlink( const QString& hyperlink, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions ) { +bool CExportManager::printByHyperlink(const QString &hyperlink, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ QString moduleName; QString keyName; ReferenceManager::Type type; @@ -398,7 +441,7 @@ bool CExportManager::printByHyperlink( const QString& hyperlink, CSwordBackend:: ? CPrinter::KeyTreeItem::Settings::SimpleKey : CPrinter::KeyTreeItem::Settings::NoKey; - CSwordModuleInfo* module = backend()->findModuleByName(moduleName); + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); Q_ASSERT(module); if (module) { @@ -426,12 +469,16 @@ bool CExportManager::printByHyperlink( const QString& hyperlink, CSwordBackend:: } } - boost::scoped_ptr printer(new CPrinter(0, displayOptions, filterOptions)); + QSharedPointer printer(new CPrinter(0, displayOptions, filterOptions)); printer->printKeyTree(tree); return true; } -bool CExportManager::printKeyList(const QStringList& list, CSwordModuleInfo* module, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { +bool CExportManager::printKeyList(const QStringList &list, + const CSwordModuleInfo *module, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ CPrinter::KeyTreeItem::Settings settings; settings.keyRenderingFace = displayOptions.verseNumbers @@ -447,7 +494,7 @@ bool CExportManager::printKeyList(const QStringList& list, CSwordModuleInfo* mod incProgress(); } - boost::scoped_ptr printer(new CPrinter(0, displayOptions, filterOptions)); + QSharedPointer printer(new CPrinter(0, displayOptions, filterOptions)); if (!progressWasCancelled()) { printer->printKeyTree(tree); @@ -475,14 +522,6 @@ const QString CExportManager::getSaveFileName(const Format format) { return QFileDialog::getSaveFileName(0, QObject::tr("Save file"), "", filterString(format), 0); } -/** Returns a string containing the linebreak for the current format. */ -const QString CExportManager::lineBreak(const Format format) { - if (static_cast(m_displayOptions.lineBreaks)) - return (format == HTML) ? QString::fromLatin1("
    \n") : QString::fromLatin1("\n"); - - return QString::null; -} - /** No descriptions */ void CExportManager::setProgressRange( const int items ) { if (QProgressDialog* dlg = progressDialog()) { diff --git a/src/frontend/cexportmanager.h b/src/frontend/cexportmanager.h index ee8c2c4..d2a185d 100644 --- a/src/frontend/cexportmanager.h +++ b/src/frontend/cexportmanager.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,13 +10,10 @@ #ifndef CEXPORTMANAGER_H #define CEXPORTMANAGER_H -#include "util/cpointers.h" - #include #include #include "backend/config/cbtconfig.h" -#include "backend/managers/cswordbackend.h" - +#include "btglobal.h" class CSwordKey; class CSwordModuleInfo; @@ -26,7 +23,7 @@ class QProgressDialog; /** Contains the functions to export text to disk, clipboard or printer. * @author The BibleTime team */ -class CExportManager : CPointers { +class CExportManager { public: /** The format the export actions should have */ @@ -35,21 +32,60 @@ class CExportManager : CPointers { Text }; - CExportManager(const QString& caption, const bool showProgress = true, const QString& progressLabel = QString::null, const CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults(), const CSwordBackend::DisplayOptions displayOptions = CBTConfig::getDisplayOptionDefaults()); + CExportManager(const QString &caption, + const bool showProgress = true, + const QString &progressLabel = QString::null, + const FilterOptions &filterOptions = CBTConfig::getFilterOptionDefaults(), + const DisplayOptions &displayOptions = CBTConfig::getDisplayOptionDefaults()); bool saveKey(CSwordKey* key, const Format format, const bool addText); - bool saveKeyList(sword::ListKey* list, CSwordModuleInfo* module, const Format format, const bool addText); - bool saveKeyList(QList& list, const Format format, const bool addText ); + + bool saveKeyList(const sword::ListKey &list, + const CSwordModuleInfo *module, + Format format, + bool addText); + + bool saveKeyList(const QList &list, + Format format, + const bool addText ); bool copyKey(CSwordKey* key, const Format format, const bool addText); - bool copyKeyList(sword::ListKey* list, CSwordModuleInfo* module, const Format format, const bool addText); - bool copyKeyList(QList& list, const Format format, const bool addText ); - bool printKey(CSwordKey* key, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); - bool printKey( CSwordModuleInfo* module, const QString& startKey, const QString& stopKey, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions ); - bool printByHyperlink(const QString& hyperlink, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); - bool printKeyList(sword::ListKey* list, CSwordModuleInfo* module, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); - bool printKeyList(const QStringList& list, CSwordModuleInfo* module, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); + bool copyKeyList(const sword::ListKey &list, + const CSwordModuleInfo *module, + Format format, + bool addText); + + bool copyKeyList(const QList &list, + Format format, + bool addText); + + bool printKey(const CSwordKey *key, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); + + bool printKey(const CSwordModuleInfo *module, + const QString &startKey, + const QString &stopKey, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); + + /** + Prints a key using the hyperlink created by CReferenceManager. + */ + bool printByHyperlink(const QString &hyperlink, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); + + bool printKeyList(const sword::ListKey &list, + const CSwordModuleInfo *module, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); + + bool printKeyList(const QStringList &list, + const CSwordModuleInfo *module, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); protected: // Protected methods /** @@ -60,17 +96,13 @@ class CExportManager : CPointers { * Returns a filename to save a file. */ const QString getSaveFileName(const Format format); - /** - * Returns a string containing the linebreak for the current format. - */ - const QString lineBreak( const Format format ); private: QString m_caption; ///< \todo Useless field QString m_progressLabel; bool m_showProgress; - CSwordBackend::FilterOptions m_filterOptions; - CSwordBackend::DisplayOptions m_displayOptions; + FilterOptions m_filterOptions; + DisplayOptions m_displayOptions; QProgressDialog* m_progressDialog; diff --git a/src/frontend/cinfodisplay.cpp b/src/frontend/cinfodisplay.cpp index 474eacd..19323fc 100644 --- a/src/frontend/cinfodisplay.cpp +++ b/src/frontend/cinfodisplay.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/cinfodisplay.h" -#include +#include #include #include #include @@ -18,6 +18,7 @@ #include #include #include +#include #include "backend/config/cbtconfig.h" #include "backend/drivers/cswordmoduleinfo.h" @@ -47,9 +48,18 @@ CInfoDisplay::CInfoDisplay(QWidget *parent) : QWidget(parent) { m_htmlPart->setMouseTracking(false); //we don't want strong/lemma/note mouse infos m_htmlPart->view()->setAcceptDrops(false); - m_copyAction = new QAction(tr("Copy"), this); - m_copyAction->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_C) ); - QObject::connect(m_copyAction, SIGNAL(triggered()), m_htmlPart->connectionsProxy(), SLOT(copySelection()) ); + QAction* selectAllAction = new QAction(QIcon(), tr("Select all"), this); + selectAllAction->setShortcut(QKeySequence::SelectAll); + QObject::connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()) ); + + QAction* copyAction = new QAction(tr("Copy"), this); + copyAction->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_C) ); + QObject::connect(copyAction, SIGNAL(triggered()), m_htmlPart->connectionsProxy(), SLOT(copySelection()) ); + + QMenu* menu = new QMenu(); + menu->addAction(selectAllAction); + menu->addAction(copyAction); + m_htmlPart->installPopup(menu); connect( m_htmlPart->connectionsProxy(), @@ -59,7 +69,7 @@ CInfoDisplay::CInfoDisplay(QWidget *parent) : QWidget(parent) { layout->addWidget(m_htmlPart->view()); - CDisplayTemplateMgr *mgr(CPointers::displayTemplateManager()); + CDisplayTemplateMgr *mgr = CDisplayTemplateMgr::instance(); CDisplayTemplateMgr::Settings settings; settings.pageCSS_ID = "infodisplay"; QString divText("
    %1
    "); @@ -78,20 +88,19 @@ CInfoDisplay::CInfoDisplay(QWidget *parent) : QWidget(parent) { CInfoDisplay::~CInfoDisplay() { - delete m_copyAction; } void CInfoDisplay::lookupInfo(const QString &mod_name, const QString &key_text) { qDebug() << "CInfoDisplay::lookup"; qDebug() << mod_name << key_text; - CSwordModuleInfo* m = CPointers::backend()->findModuleByName(mod_name); + CSwordModuleInfo* m = CSwordBackend::instance()->findModuleByName(mod_name); Q_ASSERT(m); if (!m) return; - boost::scoped_ptr key( CSwordKey::createInstance(m) ); - key->key( key_text ); + QSharedPointer key( CSwordKey::createInstance(m) ); + key->setKey(key_text); - CDisplayTemplateMgr* mgr = CPointers::displayTemplateManager(); + CDisplayTemplateMgr *mgr = CDisplayTemplateMgr::instance(); CDisplayTemplateMgr::Settings settings; settings.pageCSS_ID = "infodisplay"; @@ -163,7 +172,7 @@ void CInfoDisplay::setInfo(const ListInfoData& list) { }; } - CDisplayTemplateMgr* mgr = CPointers::displayTemplateManager(); + CDisplayTemplateMgr *mgr = CDisplayTemplateMgr::instance(); CDisplayTemplateMgr::Settings settings; settings.pageCSS_ID = "infodisplay"; // settings.langAbbrev = ""; @@ -175,6 +184,9 @@ void CInfoDisplay::setInfo(const ListInfoData& list) { m_htmlPart->setText(content); } +void CInfoDisplay::selectAll() { + m_htmlPart->selectAll(); +} const QString CInfoDisplay::decodeAbbreviation( const QString& data ) { // QStringList strongs = QStringList::split("|", data); @@ -199,11 +211,11 @@ const QString CInfoDisplay::decodeCrossReference( const QString& data ) { // qWarning("setting crossref %s", data.latin1()); - CSwordBackend::DisplayOptions dispOpts; + DisplayOptions dispOpts; dispOpts.lineBreaks = false; dispOpts.verseNumbers = true; - CSwordBackend::FilterOptions filterOpts; + FilterOptions filterOpts; filterOpts.headings = false; filterOpts.strongNumbers = false; filterOpts.morphTags = false; @@ -228,7 +240,7 @@ const QString CInfoDisplay::decodeCrossReference( const QString& data ) { if (pos > 0) { const QString moduleName = data.left(pos); // qWarning("found module %s", moduleName.latin1()); - module = CPointers::backend()->findModuleByName(moduleName); + module = CSwordBackend::instance()->findModuleByName(moduleName); if (!module) { module = CBTConfig::get(CBTConfig::standardBible); } @@ -300,8 +312,8 @@ const QString CInfoDisplay::decodeCrossReference( const QString& data ) { } /*! - \fn CInfoDisplay::decodeFootnote( const QString& data ) - */ + \fn CInfoDisplay::decodeFootnote( const QString& data ) + */ const QString CInfoDisplay::decodeFootnote( const QString& data ) { QStringList list = data.split("/"); Q_ASSERT(list.count() >= 3); @@ -309,7 +321,7 @@ const QString CInfoDisplay::decodeFootnote( const QString& data ) { return QString::null; } - CSwordBackend::FilterOptions filterOpts; + FilterOptions filterOpts; filterOpts.headings = false; filterOpts.strongNumbers = false; filterOpts.morphTags = false; @@ -318,7 +330,7 @@ const QString CInfoDisplay::decodeFootnote( const QString& data ) { // turn scripRefs off, so that they do not show up as footnotes in the OSIS filter's EntryAttributes filterOpts.scriptureReferences = false; - CPointers::backend()->setFilterOptions(filterOpts); + CSwordBackend::instance()->setFilterOptions(filterOpts); const QString modulename = list.first(); const QString swordFootnote = list.last(); @@ -328,13 +340,13 @@ const QString CInfoDisplay::decodeFootnote( const QString& data ) { list.pop_front(); const QString keyname = list.join("/"); - CSwordModuleInfo* module = CPointers::backend()->findModuleByName(modulename); + CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(modulename); if (!module) { return QString::null; } - boost::scoped_ptr key( CSwordKey::createInstance(module) ); - key->key(keyname); + QSharedPointer key( CSwordKey::createInstance(module) ); + key->setKey(keyname); key->renderedText(CSwordKey::ProcessEntryAttributesOnly); //force entryAttributes const char* note = @@ -369,8 +381,8 @@ const QString CInfoDisplay::decodeStrongs( const QString& data ) { QString text; if (module) { - boost::scoped_ptr key( CSwordKey::createInstance(module) ); - key->key( (*it).mid(1) ); //skip H or G (language sign), will have to change later if we have better modules + QSharedPointer key( CSwordKey::createInstance(module) ); + key->setKey((*it).mid(1)); // skip H or G (language sign), will have to change later if we have better modules text = key->renderedText(); } //if the module could not be found just display an empty lemma info @@ -405,7 +417,7 @@ const QString CInfoDisplay::decodeMorph( const QString& data ) { if (valStart > -1) { valueClass = morph.mid(0, valStart); //qDebug() << "valueClass: " << valueClass; - module = CPointers::backend()->findModuleByName( valueClass ); + module = CSwordBackend::instance()->findModuleByName( valueClass ); } value = morph.mid(valStart + 1); //works for prepended module and without (-1 +1 == 0). @@ -443,15 +455,15 @@ const QString CInfoDisplay::decodeMorph( const QString& data ) { QString text; //Q_ASSERT(module); if (module) { - boost::scoped_ptr key( CSwordKey::createInstance(module) ); + QSharedPointer key( CSwordKey::createInstance(module) ); //skip H or G (language sign) if we have to skip it - const bool isOk = key->key( skipFirstChar ? value.mid(1) : value ); + const bool isOk = key->setKey(skipFirstChar ? value.mid(1) : value); //Q_ASSERT(isOk); if (!isOk) { //try to use the other morph lexicon, because this one failed with the current morph code - key->module(CBTConfig::get - (CBTConfig::standardHebrewMorphLexicon)); - key->key( skipFirstChar ? value.mid(1) : value ); + key->setModule(CBTConfig::get + (CBTConfig::standardHebrewMorphLexicon)); + key->setKey(skipFirstChar ? value.mid(1) : value); } text = key->renderedText(); @@ -479,8 +491,8 @@ const QString CInfoDisplay::getWordTranslation( const QString& data ) { return QString::null; } - boost::scoped_ptr key( CSwordKey::createInstance(module) ); - key->key( data ); + QSharedPointer key( CSwordKey::createInstance(module) ); + key->setKey(data); if (key->key().toUpper() != data.toUpper()) { //key not present in the lexicon return QString::null; } @@ -494,12 +506,8 @@ const QString CInfoDisplay::getWordTranslation( const QString& data ) { return ret; } - -/*! - \fn CInfoDisplay::clearInfo() - */ void CInfoDisplay::clearInfo() { - CDisplayTemplateMgr* tmgr = CPointers::displayTemplateManager(); + CDisplayTemplateMgr *tmgr = CDisplayTemplateMgr::instance(); CDisplayTemplateMgr::Settings settings; settings.pageCSS_ID = "infodisplay"; diff --git a/src/frontend/cinfodisplay.h b/src/frontend/cinfodisplay.h index 61c9eaf..17c36a5 100644 --- a/src/frontend/cinfodisplay.h +++ b/src/frontend/cinfodisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -58,10 +58,10 @@ class CInfoDisplay : public QWidget { protected slots: void lookupInfo(const QString &, const QString &); + void selectAll(); private: CReadDisplay* m_htmlPart; - QAction* m_copyAction; }; } //end of InfoDisplay namespace diff --git a/src/frontend/cinputdialog.cpp b/src/frontend/cinputdialog.cpp deleted file mode 100644 index 5833965..0000000 --- a/src/frontend/cinputdialog.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/cinputdialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "util/dialogutil.h" - - -CInputDialog::CInputDialog -(const QString& caption, const QString& description, const QString& text, QWidget *parent, Qt::WindowFlags wflags ) - : QDialog(parent, wflags) { - QVBoxLayout *vboxLayout; - QLabel *label; - QHBoxLayout *hboxLayout; - QPushButton *clearButton; - QSpacerItem *spacerItem; - QDialogButtonBox *buttonBox; - - setWindowTitle(caption); - - resize(400, 300); - vboxLayout = new QVBoxLayout(this); - label = new QLabel(description, this); - vboxLayout->addWidget(label); - - m_textEdit = new QTextEdit(this); - vboxLayout->addWidget(m_textEdit); - m_textEdit->setWordWrapMode( QTextOption::WordWrap ); - m_textEdit->setText(text); - if (!text.isEmpty()) - m_textEdit->selectAll(); - - hboxLayout = new QHBoxLayout(); - clearButton = new QPushButton(this); - clearButton->setText(tr("Clear")); - hboxLayout->addWidget(clearButton); - spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - hboxLayout->addItem(spacerItem); - buttonBox = new QDialogButtonBox(this); - buttonBox->setOrientation(Qt::Horizontal); - buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::NoButton | QDialogButtonBox::Ok); - util::prepareDialogBox(buttonBox); - hboxLayout->addWidget(buttonBox); - - vboxLayout->addLayout(hboxLayout); - - QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - QObject::connect(clearButton, SIGNAL(clicked()), m_textEdit, SLOT(clear())); - - m_textEdit->setFocus(); -} - -/** Returns the text entered at the moment. */ -const QString CInputDialog::text() { - return m_textEdit->toPlainText(); -} - -/** A static function to get some using CInputDialog. */ -const QString CInputDialog::getText -( const QString& caption, const QString& description, const QString& text, bool* ok, QWidget* parent, Qt::WindowFlags wflags) { - CInputDialog* dlg = new CInputDialog(caption, description, text, parent, wflags); - - QString ret = QString::null; - *ok = (dlg->exec() == QDialog::Accepted) ? true : false; - if (*ok) { - //qDebug() << "dialog was accepted, return text: " << dlg->text(); - ret = dlg->text(); - } - - delete dlg; - return ret; -} diff --git a/src/frontend/cinputdialog.h b/src/frontend/cinputdialog.h deleted file mode 100644 index 153c14e..0000000 --- a/src/frontend/cinputdialog.h +++ /dev/null @@ -1,41 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CINPUTDIALOG_H -#define CINPUTDIALOG_H - -#include - - -class QTextEdit; -class QWidget; - -/** This is a small input dialog with - * a multiline edit for the text input. - * @author The BibleTime team - */ -class CInputDialog : public QDialog { - Q_OBJECT - public: - CInputDialog(const QString& caption, const QString& description, const QString& text, QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); - /** - * A static function to get some using CInputDialog. - */ - static const QString getText( const QString& caption, const QString& description, const QString& text = QString::null, bool* ok = 0, QWidget* parent = 0, Qt::WindowFlags wflags = Qt::Dialog); - /** - * Returns the text entered at the moment. - */ - const QString text(); - // ~CInputDialog(); - - private: - QTextEdit* m_textEdit; -}; - -#endif diff --git a/src/frontend/cmdiarea.cpp b/src/frontend/cmdiarea.cpp index c499962..cfdb6ee 100644 --- a/src/frontend/cmdiarea.cpp +++ b/src/frontend/cmdiarea.cpp @@ -2,25 +2,39 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "bibletime.h" #include "frontend/cmdiarea.h" +#include "frontend/displaywindow/btmodulechooserbar.h" #include #include #include +#include #include #include CMDIArea::CMDIArea(BibleTime *parent) - : QMdiArea(parent), m_mdiArrangementMode(ArrangementModeManual) { + : QMdiArea(parent), m_mdiArrangementMode(ArrangementModeManual), m_activeWindow(0), m_bibleTime(parent) { Q_ASSERT(parent != 0); + #if QT_VERSION >= 0x040500 + // Set document-style tabs (for Mac): + setDocumentMode(true); + #endif + + /* + Activate windows based on the history of activation, e.g. when one has window A + activated, and activates window B and then closes window B, then window A is activated. + */ + setActivationOrder(QMdiArea::ActivationHistoryOrder); + + // Show scrollbars only when needed: setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); @@ -30,21 +44,24 @@ CMDIArea::CMDIArea(BibleTime *parent) static const int moveSize = 30; -QMdiSubWindow* CMDIArea::addSubWindow(QWidget * widget, Qt::WindowFlags windowFlags) { - QMdiSubWindow* subWindow = QMdiArea::addSubWindow(widget, windowFlags); - subWindow->installEventFilter(this); - - // Change Qt QMdiSubWindow Close action to have no shortcut +void CMDIArea::fixSystemMenu(QMdiSubWindow* subWindow) { + // Change Qt QMdiSubWindow Close action to have no shortcuts // This makes our closeWindow actions with Ctrl-W work correctly QList actions = subWindow->systemMenu()->actions(); for (int i=0; itext(); if (text.contains("Close")) { - action->setShortcut(QKeySequence()); + action->setShortcuts(QList()); break; } } +} + +QMdiSubWindow* CMDIArea::addSubWindow(QWidget * widget, Qt::WindowFlags windowFlags) { + QMdiSubWindow* subWindow = QMdiArea::addSubWindow(widget, windowFlags); + subWindow->installEventFilter(this); + fixSystemMenu(subWindow); // Manual arrangement mode enableWindowMinMaxFlags(true); @@ -84,13 +101,29 @@ QMdiSubWindow* CMDIArea::addSubWindow(QWidget * widget, Qt::WindowFlags windowFl void CMDIArea::setMDIArrangementMode( const MDIArrangementMode newArrangementMode ) { m_mdiArrangementMode = newArrangementMode; - triggerWindowUpdate(); + switch (m_mdiArrangementMode) { + case ArrangementModeManual: + setViewMode(QMdiArea::SubWindowView); + break; + case ArrangementModeTile: + setViewMode(QMdiArea::SubWindowView); + tileSubWindows(); + break; + case ArrangementModeTabbed: + setViewMode(QMdiArea::TabbedView); + break; + default: + setViewMode(QMdiArea::SubWindowView); + triggerWindowUpdate(); + break; + } } void CMDIArea::myTileVertical() { if (!updatesEnabled() || !usableWindowList().count() ) { return; } + setViewMode(QMdiArea::SubWindowView); QList windows = usableWindowList(); setUpdatesEnabled(false); @@ -117,6 +150,7 @@ void CMDIArea::myTileHorizontal() { if (!updatesEnabled() || !usableWindowList().count() ) { return; } + setViewMode(QMdiArea::SubWindowView); QList windows = usableWindowList(); setUpdatesEnabled(false); @@ -138,10 +172,12 @@ void CMDIArea::myTileHorizontal() { emitWindowCaptionChanged(); } +// Tile the windows, tiling implemented by Qt void CMDIArea::myTile() { if (!updatesEnabled() || !usableWindowList().count() ) { return; } + setViewMode(QMdiArea::SubWindowView); tileSubWindows(); emitWindowCaptionChanged(); } @@ -150,6 +186,7 @@ void CMDIArea::myCascade() { if (!updatesEnabled() || !usableWindowList().count() ) { return; } + setViewMode(QMdiArea::SubWindowView); QList windows = usableWindowList(); @@ -193,7 +230,7 @@ void CMDIArea::emitWindowCaptionChanged() { emit sigSetToplevelCaption(activeSubWindow()->windowTitle()); } else { - emit sigSetToplevelCaption(QString()); + emit sigSetToplevelCaption(QString::null); } } @@ -211,22 +248,34 @@ QList CMDIArea::usableWindowList() { } void CMDIArea::slotSubWindowActivated(QMdiSubWindow* client) { - if (!client || !updatesEnabled()) { + if (subWindowList().count() == 0) + m_bibleTime->clearMdiToolBars(); + + if (!client) { return; } emit sigSetToplevelCaption( client->windowTitle().trimmed() ); + + // Notify child window it is active + CDisplayWindow* activeWindow = qobject_cast(client->widget()); + if (activeWindow != 0 && activeWindow != m_activeWindow) { + m_activeWindow = activeWindow; + activeWindow->windowActivated(); + } } void CMDIArea::resizeEvent(QResizeEvent* e) { /* - Do not call QMdiArea::resizeEvent(e) unless we are in manual arrangement - mode, since this would mess up our layout. The manual arrangement mode - should be handled exactly as in QMdiArea. + Do not call QMdiArea::resizeEvent(e) if we are in manual arrangement + mode, since this would mess up our layout. Also, don't call it for the + automatic arrangement modes that we implement. Call it only for those + modes implemented by Qt */ - if (m_mdiArrangementMode == ArrangementModeManual) { + if (m_mdiArrangementMode == ArrangementModeTabbed) { QMdiArea::resizeEvent(e); } else if (updatesEnabled()) { + // Handle resize for automatic modes that we implement triggerWindowUpdate(); } } @@ -236,7 +285,8 @@ bool CMDIArea::eventFilter(QObject *o, QEvent *e) { QMdiSubWindow *w(qobject_cast(o)); // Let the event be handled by other filters: - if (w == 0) return QMdiArea::eventFilter(o, e); + if (w == 0) + return QMdiArea::eventFilter(o, e); switch (e->type()) { case QEvent::WindowStateChange: { @@ -268,6 +318,7 @@ bool CMDIArea::eventFilter(QObject *o, QEvent *e) { if (o == activeSubWindow()) { emit sigSetToplevelCaption(w->windowTitle()); } + return QMdiArea::eventFilter(o, e); break; default: break; @@ -285,12 +336,12 @@ void CMDIArea::triggerWindowUpdate() { case ArrangementModeTileHorizontal: QTimer::singleShot(0, this, SLOT(myTileHorizontal())); break; - case ArrangementModeCascade: - QTimer::singleShot(0, this, SLOT(myCascade())); - break; case ArrangementModeTile: QTimer::singleShot(0, this, SLOT(myTile())); break; + case ArrangementModeCascade: + QTimer::singleShot(0, this, SLOT(myCascade())); + break; default: break; } @@ -310,8 +361,6 @@ void CMDIArea::enableWindowMinMaxFlags(bool enable) flags &= ~Qt::WindowMaximizeButtonHint; } subWindow->setWindowFlags(flags); - subWindow->hide(); - subWindow->show(); } } diff --git a/src/frontend/cmdiarea.h b/src/frontend/cmdiarea.h index 858d0d4..9a62370 100644 --- a/src/frontend/cmdiarea.h +++ b/src/frontend/cmdiarea.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,6 +16,7 @@ class BibleTime; class CSwordModuleInfo; +class CDisplayWindow; /** A custom MDI area widget. @@ -33,7 +34,8 @@ class CMDIArea: public QMdiArea { ArrangementModeTileHorizontal = 2, ArrangementModeCascade = 3, ArrangementModeManual = 4, - ArrangementModeTile = 5 + ArrangementModeTile = 5, + ArrangementModeTabbed = 6 }; /** @@ -69,7 +71,7 @@ class CMDIArea: public QMdiArea { */ QList usableWindowList(); - /** + /** Show or hide the sub-window min/max buttons. */ void enableWindowMinMaxFlags(bool enable); @@ -82,6 +84,7 @@ class CMDIArea: public QMdiArea { arranging the subwindows into a tile automatically. */ void myTile(); + /** Our own cascade version which, if only one subwindow is left, shows it maximized. @@ -111,7 +114,7 @@ class CMDIArea: public QMdiArea { signals: /** - * Emits a signal to set the acption of the toplevel widget. + * Emits a signal to set the caption of the toplevel widget. */ void sigSetToplevelCaption(const QString&); @@ -129,6 +132,7 @@ class CMDIArea: public QMdiArea { bool eventFilter(QObject *o, QEvent *e); void emitWindowCaptionChanged(); + void fixSystemMenu(QMdiSubWindow* subWindow); protected slots: /** @@ -138,6 +142,10 @@ class CMDIArea: public QMdiArea { protected: MDIArrangementMode m_mdiArrangementMode; + + private: + CDisplayWindow* m_activeWindow; + BibleTime* m_bibleTime; }; #endif diff --git a/src/frontend/cmodulechooserdialog.cpp b/src/frontend/cmodulechooserdialog.cpp deleted file mode 100644 index d2d7505..0000000 --- a/src/frontend/cmodulechooserdialog.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/cmodulechooserdialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend/btmoduletreeitem.h" -#include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" -#include "util/cpointers.h" -#include "util/cresmgr.h" -#include "util/tool.h" -#include "util/dialogutil.h" -#include "util/directory.h" - - -CModuleChooserDialog::CModuleChooserDialog( QWidget* parent, QString title, QString label, QList* allModules) - : QDialog(parent), - m_title(title), - m_labelText(label) { - m_grouping = (BTModuleTreeItem::Grouping)CBTConfig::get(CBTConfig::bookshelfGrouping); - m_filters = QList(); - if (!allModules) { - m_moduleList = CPointers::backend()->moduleList(); - } - else m_moduleList = *allModules; -} - -/** -* Call init() after the constructor, either in the end of your own constructor or from outside. -*/ -void CModuleChooserDialog::init() { - //Set the flag to destroy when closed - otherwise eats memory - setAttribute(Qt::WA_DeleteOnClose); - setWindowTitle(m_title); - initView(); - initTree(); -} - -/** Initializes the view of this dialog */ -void CModuleChooserDialog::initView() { - /// \todo choose the button text? - - QVBoxLayout *vboxLayout; - QHBoxLayout *hboxLayout; - QSpacerItem *spacerItem; - - vboxLayout = new QVBoxLayout(this); - - QLabel* label = util::tool::explanationLabel(this, QString::null, m_labelText); - vboxLayout->addWidget(label); - - m_moduleChooser = new QTreeWidget(this); - m_moduleChooser->header()->hide(); - - vboxLayout->addWidget(m_moduleChooser); - - hboxLayout = new QHBoxLayout(); - - spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - hboxLayout->addItem(spacerItem); - - m_buttonBox = new QDialogButtonBox(this); - m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); - util::prepareDialogBox(m_buttonBox); - hboxLayout->addWidget(m_buttonBox); - - vboxLayout->addLayout(hboxLayout); - - QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(slotOk()) ); - //The QDialog doc is a bit unclear but calling reject also destroys the dialog - // in this situation. - QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()) ); -} - - -void CModuleChooserDialog::initTree() { - //qDebug() << "CModuleChooserDialog::initTree"; - - // See BTModuleTreeItem documentation. - BTModuleTreeItem root(m_filters, m_grouping, &m_moduleList); - createModuleTree(&root, m_moduleChooser->invisibleRootItem()); - -} - -void CModuleChooserDialog::createModuleTree(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem) { - foreach (BTModuleTreeItem* i, item->children()) { - createModuleTree(i, new QTreeWidgetItem(widgetItem)); - } - if (item->type() != BTModuleTreeItem::Root) { - widgetItem->setText(0, item->text()); - if (item->type() == BTModuleTreeItem::Category || item->type() == BTModuleTreeItem::Language) { - widgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate); - } - if (item->type() == BTModuleTreeItem::Module) { - initModuleItem(item, widgetItem); - } - } -} - - -/** Emits the signal with the list of the selected modules. */ -void CModuleChooserDialog::slotOk() { - Q_ASSERT(m_moduleChooser); - //create the list of selected modules - QList mods; - QTreeWidgetItemIterator it( m_moduleChooser ); - for ( ; *it; ++it ) { - //add the module to list if the box is checked - if ((*it)->checkState(0) == Qt::Checked) { - qDebug() << "was checked"; - for (QList::iterator all_iter(m_moduleList.begin()); all_iter != m_moduleList.end(); ++all_iter) { - if ((*all_iter)->name() == (*it)->text(0)) { - qDebug() << "append"; - mods.append(*all_iter); - break; - } - } - - } - } - - // The selection is handled first, then the dialog is closed and destroyed. - emit modulesChanged(mods, m_moduleChooser); - QDialog::done(QDialog::Accepted); -} - -QPushButton* CModuleChooserDialog::okButton() { - return m_buttonBox->button(QDialogButtonBox::Ok); -} diff --git a/src/frontend/cmodulechooserdialog.h b/src/frontend/cmodulechooserdialog.h deleted file mode 100644 index e74d743..0000000 --- a/src/frontend/cmodulechooserdialog.h +++ /dev/null @@ -1,107 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2007 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CMODULECHOOSERDIALOG_H -#define CMODULECHOOSERDIALOG_H - -#include - -#include "backend/btmoduletreeitem.h" -#include -#include - - -class CSwordModuleInfo; -class QDialogButtonBox; - -/** -* Abstract dialog which lets the user select modules with checkboxes. -* The dialog will be destroyed after closing. Connect the modulesChanged() signal -* to handle the selection before the dialog is destroyed. -*/ -class CModuleChooserDialog : public QDialog { - Q_OBJECT - public: - - /** - * Use your own constructor to set extra members. - * Filters list is given to the module tree creator, see BTModuleTreeItem. - * For module list see BTModuleTreeItem constructor documentation. - * Call init() after the constructor, either in the end of your own constructor or from outside. - */ - CModuleChooserDialog(QWidget* parent, QString title, QString label, QList* allModules = 0); - - virtual ~CModuleChooserDialog() {} - - /** Call this after/from the constructor.*/ - void init(); - - /** Set the module tree grouping. - * Initially it's taken from the CBTConfig so it needs to be set only if that default is not adequate. - * This must be called before the tree is initialized, i.e. before init(). - */ - void setGrouping(BTModuleTreeItem::Grouping grouping) { - m_grouping = grouping; - } - - /** Set the module tree filters. See setGrouping() for the calling convention and - * BTModuleTreeItem for the filters. By default the filters list is empty. - */ - void setFilters(QList filters) { - m_filters = filters; - } - - QTreeWidget* treeWidget() { - return m_moduleChooser; - } - - QPushButton* okButton(); - - signals: - - /** The signal is sent when the OK button is clicked. The list includes the selected (checked) modules. The tree widget can be used through the pointer for more complicated actions. */ - void modulesChanged(QList, QTreeWidget*); - - protected: - - /** - * Initialize one tree widget item. - * To be overridden. This is called for each QTreeWidgetItem when it is created. - * Here you can set for example the checked status of the item. - */ - virtual void initModuleItem(BTModuleTreeItem* btItem, QTreeWidgetItem* widgetItem) = 0; - - - - private slots: - - /** Emits the signal modulesChanged() with the list of the selected modules. */ - void slotOk(); - - private: - /** Initialize the module tree. */ - void initTree(); - - /** Initializes the view of this dialog.*/ - void initView(); - - /** Call this from initTree(). */ - void createModuleTree(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem); - - QTreeWidget *m_moduleChooser; - QDialogButtonBox *m_buttonBox; - QString m_title; - QString m_labelText; - QList m_filters; - BTModuleTreeItem::Grouping m_grouping; - QList m_moduleList; -}; - - -#endif diff --git a/src/frontend/cmoduleindexdialog.cpp b/src/frontend/cmoduleindexdialog.cpp deleted file mode 100644 index a32d1ea..0000000 --- a/src/frontend/cmoduleindexdialog.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/cmoduleindexdialog.h" - -#include -#include -#include -#include -#include "backend/managers/cswordbackend.h" -#include "util/cpointers.h" -#include "util/dialogutil.h" - - -CModuleIndexDialog* CModuleIndexDialog::getInstance() { - qDebug() << "CModuleIndexDialog::getInstance"; - static CModuleIndexDialog* instance = 0; - if (instance == 0) { - instance = new CModuleIndexDialog(); - } - qDebug() << "CModuleIndexDialog::getInstance end"; - return instance; -} - -void CModuleIndexDialog::indexAllModules( const QList& modules ) { - static bool indexing = false; - if (!indexing) { - indexing = true; - if (modules.count() < 1) return; - - m_currentModuleIndex = 0; - m_progress = new QProgressDialog(QString(""), tr("Cancel"), 0, modules.count()*100); - m_progress->setWindowModality(Qt::WindowModal); // not useful actually, should have parent for this - m_progress->setWindowTitle(tr("Creating indices")); - m_progress->show(); - m_progress->raise(); - - foreach (CSwordModuleInfo* info, modules) { - /// \todo how to cancel - //QObject::connect(CPointers::backend(), SIGNAL(sigSwordSetupChanged()), this, SLOT(swordSetupChanged())); - connect(this, SIGNAL(sigCancel()), info, SLOT(cancelIndexing()) ); - connect(m_progress, SIGNAL(canceled()), info, SLOT(cancelIndexing())); - connect(info, SIGNAL(indexingFinished()), this, SLOT(slotFinished())); - connect(info, SIGNAL(indexingProgress(int)), this, SLOT(slotModuleProgress(int)) ); - QString modname(info->name()); - const QString labelText = tr("Creating index for work: %1").arg(modname); - m_progress->setLabelText(labelText); - /// \todo if we want to cancel indexing from - info->buildIndex(); //waits until this module is finished - - m_currentModuleIndex++; - disconnect(m_progress, SIGNAL(canceled()), info, SLOT(cancelIndexing())); - disconnect(info, SIGNAL(indexingFinished()), this, SLOT(slotFinished())); - disconnect(info, SIGNAL(indexingProgress(int)), this, SLOT(slotModuleProgress(int)) ); - if (m_progress->wasCanceled()) break; - } - - delete m_progress; - m_progress = 0; - indexing = false; - } -} - -void CModuleIndexDialog::indexUnindexedModules( const QList& modules ) { - QList unindexedMods; - - QList::const_iterator end_it = modules.end(); - for ( QList::const_iterator it = modules.begin(); it != end_it; ++it) { - if ((*it)->hasIndex()) { - continue; - } - - unindexedMods << (*it); - } - indexAllModules(unindexedMods); -} - -void CModuleIndexDialog::slotModuleProgress( int percentage ) { - m_progress->setValue(m_currentModuleIndex * 100 + percentage); - qApp->processEvents(); -} - -void CModuleIndexDialog::slotFinished( ) { - m_progress->setValue(m_currentModuleIndex * 100 + 100); - qApp->processEvents(); -} - -// Modules may be removed -void CModuleIndexDialog::slotSwordSetupChanged() { - qDebug() << "CModuleIndexDialog::slotSwordSetupChanged"; /// \todo cancel if modules are removed - util::showInformation(0, tr("Indexing Is Cancelled"), tr("Indexing is cancelled because modules are removed.")); - emit sigCancel(); -} diff --git a/src/frontend/cmoduleindexdialog.h b/src/frontend/cmoduleindexdialog.h deleted file mode 100644 index b27b161..0000000 --- a/src/frontend/cmoduleindexdialog.h +++ /dev/null @@ -1,56 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CMODULEINDEXDIALOG_H -#define CMODULEINDEXDIALOG_H - -#include - - -class CSwordModuleInfo; -class QProgressDialog; - -/** - * This dialog is used to index a list of modules and to show progress for that.\ - * While the indexing is in progress it creates a blocking, top level dialog which shows the progress - * while the indexing is done. - * - * @author The BibleTime team -*/ -class CModuleIndexDialog : public QObject { - Q_OBJECT - public: - /** Get the singleton instance. - * - */ - static CModuleIndexDialog* getInstance(); - - /** Starts the actual indexing. It shows the dialog with progress information. - */ - void indexAllModules( const QList& modules ); - - /** Indexes all modules in the list which don't have an index yet. - */ - void indexUnindexedModules( const QList& modules ); - - signals: - /** Indexing is cancelled programmatically. */ - void sigCancel(); - - private: - QProgressDialog* m_progress; - int m_currentModuleIndex; - - protected slots: - void slotModuleProgress( int percentage ); - void slotFinished(); - void slotSwordSetupChanged(); -}; - -#endif diff --git a/src/frontend/cprinter.cpp b/src/frontend/cprinter.cpp index 11988a9..99d1daf 100644 --- a/src/frontend/cprinter.cpp +++ b/src/frontend/cprinter.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,15 +15,18 @@ #include #include "backend/keys/cswordversekey.h" #include "backend/managers/cdisplaytemplatemgr.h" -#include "util/cpointers.h" namespace Printing { -CPrinter::CPrinter(QObject*, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) - : QObject(0), - CDisplayRendering(displayOptions, filterOptions), - m_htmlPage(new QWebPage()) { +/// \todo WHY IS parent NOT USED!? +CPrinter::CPrinter(QObject *, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) + : QObject(0), + CDisplayRendering(displayOptions, filterOptions), + m_htmlPage(new QWebPage()) +{ m_htmlPage->setParent(this); //override the filteroptions set in the c-tor of CDisplayRendering @@ -49,11 +52,13 @@ void CPrinter::printKeyTree( KeyTree& tree ) { } } -const QString CPrinter::entryLink(const KeyTreeItem& item, CSwordModuleInfo* module) { +const QString CPrinter::entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module) +{ Q_ASSERT(module); if (module->type() == CSwordModuleInfo::Bible) { CSwordVerseKey vk(module); - vk.key(item.key()); + vk.setKey(item.key()); switch (item.settings().keyRenderingFace) { case KeyTreeItem::Settings::CompleteShort: return QString::fromUtf8(vk.getShortText()); @@ -94,7 +99,7 @@ const QString CPrinter::renderEntry( const KeyTreeItem& i, CSwordKey* ) { } const QString CPrinter::finishText(const QString& text, KeyTree& tree) { - QList modules = collectModules(&tree); + QList modules = collectModules(&tree); Q_ASSERT(modules.count() > 0); const CLanguageMgr::Language* const lang = modules.first()->language(); @@ -114,7 +119,7 @@ const QString CPrinter::finishText(const QString& text, KeyTree& tree) { settings.pageDirection = ( modules.first()->textDirection() == CSwordModuleInfo::LeftToRight ) ? "ltr" : "rtl"; } - CDisplayTemplateMgr* tMgr = CPointers::displayTemplateManager(); + CDisplayTemplateMgr *tMgr = CDisplayTemplateMgr::instance(); return tMgr->fillTemplate(CBTConfig::get(CBTConfig::displayStyle), text, settings); } diff --git a/src/frontend/cprinter.h b/src/frontend/cprinter.h index f119ec3..2252786 100644 --- a/src/frontend/cprinter.h +++ b/src/frontend/cprinter.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,12 +26,17 @@ namespace Printing { class CPrinter : public QObject, public Rendering::CDisplayRendering { Q_OBJECT public: - CPrinter(QObject* parent, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); + CPrinter(QObject *parent, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); + virtual ~CPrinter(); void printKeyTree( KeyTree& ); protected: - virtual const QString entryLink(const KeyTreeItem& item, CSwordModuleInfo* const module); + virtual const QString entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module); + virtual const QString renderEntry( const KeyTreeItem&, CSwordKey* = 0 ); virtual const QString finishText(const QString& arg1, KeyTree& tree); diff --git a/src/frontend/crossrefrendering.cpp b/src/frontend/crossrefrendering.cpp index 1d7ff63..616766c 100644 --- a/src/frontend/crossrefrendering.cpp +++ b/src/frontend/crossrefrendering.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,23 +16,27 @@ namespace InfoDisplay { -CrossRefRendering::CrossRefRendering( CSwordBackend::DisplayOptions displayOptions, - CSwordBackend::FilterOptions filterOptions - ) - : CHTMLExportRendering(Settings(), displayOptions, filterOptions) {} +CrossRefRendering::CrossRefRendering(const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) + : CHTMLExportRendering(Settings(), displayOptions, filterOptions) +{ + // Intentionally empty +} const QString CrossRefRendering::finishText( const QString& text, KeyTree& ) { // qDebug() << "CrossRefRendering::finishText"; return text; } -const QString CrossRefRendering::entryLink( const KeyTreeItem& item, CSwordModuleInfo* module ) { +const QString CrossRefRendering::entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module) +{ QString linkText; const bool isBible = module && (module->type() == CSwordModuleInfo::Bible); CSwordVerseKey vk(module); //only valid for bible modules, i.e. isBible == true if (isBible) { - vk.key(item.key()); + vk.setKey(item.key()); } switch (item.settings().keyRenderingFace) { diff --git a/src/frontend/crossrefrendering.h b/src/frontend/crossrefrendering.h index 561fd3e..1e65d06 100644 --- a/src/frontend/crossrefrendering.h +++ b/src/frontend/crossrefrendering.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,11 +20,13 @@ class CrossRefRendering : public Rendering::CHTMLExportRendering { friend class CInfoDisplay; CrossRefRendering( - CSwordBackend::DisplayOptions displayOptions = CBTConfig::getDisplayOptionDefaults(), - CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults() + const DisplayOptions &displayOptions = CBTConfig::getDisplayOptionDefaults(), + const FilterOptions &filterOptions = CBTConfig::getFilterOptionDefaults() ); - virtual const QString entryLink( const KeyTreeItem& item, CSwordModuleInfo* module ); + virtual const QString entryLink(const KeyTreeItem &item, + const CSwordModuleInfo *module); + virtual const QString finishText( const QString&, KeyTree& tree ); }; diff --git a/src/frontend/display/btcolorwidget.cpp b/src/frontend/display/btcolorwidget.cpp index 37bea2d..0d09259 100644 --- a/src/frontend/display/btcolorwidget.cpp +++ b/src/frontend/display/btcolorwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/display/btcolorwidget.h b/src/frontend/display/btcolorwidget.h index 0d8e8ad..5cc0f56 100644 --- a/src/frontend/display/btcolorwidget.h +++ b/src/frontend/display/btcolorwidget.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,10 +22,11 @@ class BtColorWidget : public QFrame { BtColorWidget(QWidget* parent = 0); ~BtColorWidget(); QSize sizeHint() const; + + public slots: void setColor(const QColor& color); protected: -// void paintEvent( QPaintEvent* ); void mouseReleaseEvent(QMouseEvent* event); private: diff --git a/src/frontend/display/btfontsizewidget.cpp b/src/frontend/display/btfontsizewidget.cpp index 116d0d7..b302fed 100644 --- a/src/frontend/display/btfontsizewidget.cpp +++ b/src/frontend/display/btfontsizewidget.cpp @@ -1,9 +1,9 @@ /********* * -* This file is part of BtFontSizeWidget's source code, http://www.bibletime.info/. +* This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BtFontSizeWidget developers. -* The BtFontSizeWidget source code is licensed under the GNU General Public License version 2.0. +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/display/btfontsizewidget.h b/src/frontend/display/btfontsizewidget.h index 3db867d..c2d7198 100644 --- a/src/frontend/display/btfontsizewidget.h +++ b/src/frontend/display/btfontsizewidget.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -19,9 +19,11 @@ class BtFontSizeWidget : public QComboBox { public: BtFontSizeWidget(QWidget* parent = 0); ~BtFontSizeWidget(); - void setFontSize(int size); int fontSize() const; + public slots: + void setFontSize(int size); + private slots: virtual void changed(const QString& text); diff --git a/src/frontend/display/bthtml.js b/src/frontend/display/bthtml.js index d64215d..689ba55 100644 --- a/src/frontend/display/bthtml.js +++ b/src/frontend/display/bthtml.js @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/display/bthtmlfindtext.cpp b/src/frontend/display/bthtmlfindtext.cpp index 70e8a5d..1b15b11 100644 --- a/src/frontend/display/bthtmlfindtext.cpp +++ b/src/frontend/display/bthtmlfindtext.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -49,10 +49,6 @@ void BtHtmlFindText::findNext() { } } -void BtHtmlFindText::doHide() { - hide(); -} - void BtHtmlFindText::findPrevious() { QWebView* webView = getActiveWindowWebView(); if (webView != 0) { diff --git a/src/frontend/display/bthtmlfindtext.h b/src/frontend/display/bthtmlfindtext.h index 3c24489..1d941c1 100644 --- a/src/frontend/display/bthtmlfindtext.h +++ b/src/frontend/display/bthtmlfindtext.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,7 +26,6 @@ class BtHtmlFindText : public QDialog { public slots: void findNext(); void findPrevious(); - void doHide(); private: QWebView* getActiveWindowWebView(); Ui_findTextDialog ui; diff --git a/src/frontend/display/bthtmlfindtext.ui b/src/frontend/display/bthtmlfindtext.ui index 97c373e..c04de0c 100644 --- a/src/frontend/display/bthtmlfindtext.ui +++ b/src/frontend/display/bthtmlfindtext.ui @@ -48,7 +48,7 @@ - Seach with case sensitivity + Search with case sensitivity Case &sensitive diff --git a/src/frontend/display/bthtmljsobject.cpp b/src/frontend/display/bthtmljsobject.cpp index 195564e..119c2a8 100644 --- a/src/frontend/display/bthtmljsobject.cpp +++ b/src/frontend/display/bthtmljsobject.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/bthtmljsobject.h" -#include +#include #include #include "backend/config/cbtconfig.h" #include "backend/keys/cswordkey.h" @@ -18,6 +18,7 @@ #include "frontend/cdragdrop.h" #include "frontend/cinfodisplay.h" #include "frontend/display/bthtmlreaddisplay.h" +#include "bibletime.h" using namespace InfoDisplay; @@ -28,7 +29,10 @@ using namespace InfoDisplay; // Access to DOM objects is implemented in Javascript and is communicated back to c++ through this class BtHtmlJsObject::BtHtmlJsObject(BtHtmlReadDisplay* display) - : m_display(display) { + : m_display(display) +{ + m_dndData.isDragging = false; + m_dndData.mousePressed = false; } void BtHtmlJsObject::moveToAnchor(const QString& anchor) { @@ -36,13 +40,6 @@ void BtHtmlJsObject::moveToAnchor(const QString& anchor) { emit gotoAnchor(anchor); } -void BtHtmlJsObject::setBodyEditable(bool editable) { - if (editable) - emit setDocumentEditable(); - else - emit setDocumentNotEditable(); -} - void BtHtmlJsObject::mouseDownLeft(const QString& url, const int& x, const int& y) { m_dndData.mousePressed = true; m_dndData.isDragging = false; @@ -75,7 +72,6 @@ void BtHtmlJsObject::mouseDownRight(const QString& url, const QString& lemma) { // The mouse move event starts in the javascript function "mouseMoveHandler" in bthtml.js. It calls this function void BtHtmlJsObject::mouseMoveEvent(const QString& attributes, const int& x, const int& y, const bool& shiftKey) { - /// \bug Valgrind reports uninitialized m_dndData or m_dndData member: if (!m_dndData.isDragging && m_dndData.mousePressed) { // If we have not started dragging, but the mouse button is down, create a the mime data QPoint current(x, y); @@ -92,9 +88,9 @@ void BtHtmlJsObject::mouseMoveEvent(const QString& attributes, const int& x, con BTMimeData* mimedata = new BTMimeData(moduleName, keyName, QString::null); drag->setMimeData(mimedata); //add real Bible text from module/key - if (CSwordModuleInfo* module = CPointers::backend()->findModuleByName(moduleName)) { - boost::scoped_ptr key( CSwordKey::createInstance(module) ); - key->key( keyName ); + if (CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName(moduleName)) { + QSharedPointer key( CSwordKey::createInstance(module) ); + key->setKey(keyName); mimedata->setText(key->strippedText()); // This works across applications! } } @@ -149,7 +145,7 @@ void BtHtmlJsObject::timeOutEvent(const QString& attributes) { } // Update the mag if valid attributes were found if (!(infoList.isEmpty())) { - CPointers::infoDisplay()->setInfo(infoList); + BibleTime::instance()->infoDisplay()->setInfo(infoList); } } diff --git a/src/frontend/display/bthtmljsobject.h b/src/frontend/display/bthtmljsobject.h index c3536ff..c49dc83 100644 --- a/src/frontend/display/bthtmljsobject.h +++ b/src/frontend/display/bthtmljsobject.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -24,7 +24,6 @@ class BtHtmlJsObject: public QObject { BtHtmlJsObject(BtHtmlReadDisplay* display); ~BtHtmlJsObject() {} void moveToAnchor(const QString& anchor); - void setBodyEditable(bool editable); void clearPrevAttribute(); public slots: @@ -39,8 +38,6 @@ class BtHtmlJsObject: public QObject { void mouseMoveAttribute(const QString& attrName, const QString& attrValue); void gotoAnchor(const QString& anchor); void selectAll(); - void setDocumentEditable(); - void setDocumentNotEditable(); private: int m_int; @@ -56,7 +53,7 @@ class BtHtmlJsObject: public QObject { Link, Text } dragType; - } m_dndData; + } m_dndData; }; diff --git a/src/frontend/display/bthtmlreaddisplay.cpp b/src/frontend/display/bthtmlreaddisplay.cpp index dd2132f..2d95c38 100644 --- a/src/frontend/display/bthtmlreaddisplay.cpp +++ b/src/frontend/display/bthtmlreaddisplay.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/bthtmlreaddisplay.h" -#include +#include #include #include #include "backend/config/cbtconfig.h" @@ -19,9 +19,9 @@ #include "frontend/cinfodisplay.h" #include "frontend/display/bthtmljsobject.h" #include "frontend/displaywindow/cdisplaywindow.h" +#include "frontend/displaywindow/cdisplaywindowfactory.h" #include "frontend/displaywindow/creadwindow.h" #include "util/directory.h" -#include "util/cpointers.h" using namespace InfoDisplay; @@ -35,7 +35,7 @@ BtHtmlReadDisplay::BtHtmlReadDisplay(CReadWindow* readWindow, QWidget* parentWid { settings()->setAttribute(QWebSettings::JavascriptEnabled, true); - m_view = new BtHtmlReadDisplayView(this, parentWidget ? parentWidget : readWindow); + m_view = new BtHtmlReadDisplayView(this, parentWidget ? parentWidget : readWindow, readWindow); m_view->setAcceptDrops(true); m_view->setPage(this); setParent(m_view); @@ -87,7 +87,7 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD else { CDisplayWindow* window = parentWindow(); CSwordKey* const key = window->key(); - CSwordModuleInfo* module = key->module(); + const CSwordModuleInfo *module = key->module(); //This is never used for Bibles, so it is not implemented for //them. If it should be, see CReadDisplay::print() for example //code. @@ -98,7 +98,7 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD module->type() == CSwordModuleInfo::Commentary || module->type() == CSwordModuleInfo::GenericBook) { /// \todo This is a BAD HACK, we have to fnd a better solution to manage the settings now - CSwordBackend::FilterOptions filterOptions; + FilterOptions filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -106,7 +106,7 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD filterOptions.scriptureReferences = false; filterOptions.textualVariants = false; - CPointers::backend()->setFilterOptions(filterOptions); + CSwordBackend::instance()->setFilterOptions(filterOptions); return QString(key->strippedText()).append("\n(") .append(key->key()) @@ -122,7 +122,7 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD return QString::null; } else if (format == HTMLText) { - // \todo It does not appear this is ever called + // \todo It does not appear this is ever called } else { //plain text requested return selectedText(); @@ -144,9 +144,9 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD ReferenceManager::Type type; ReferenceManager::decodeHyperlink(activeAnchor(), moduleName, keyName, type); - if (CSwordModuleInfo* module = backend()->findModuleByName(moduleName)) { - boost::scoped_ptr key( CSwordKey::createInstance(module) ); - key->key( keyName ); + if (CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName(moduleName)) { + QSharedPointer key( CSwordKey::createInstance(module) ); + key->setKey(keyName); return key->strippedText(); } @@ -159,12 +159,12 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD ReferenceManager::Type type; ReferenceManager::decodeHyperlink(activeAnchor(), moduleName, keyName, type); - if (CSwordModuleInfo* module = backend()->findModuleByName(moduleName)) { - boost::scoped_ptr key( CSwordKey::createInstance(module) ); - key->key( keyName ); + if (CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName(moduleName)) { + QSharedPointer key( CSwordKey::createInstance(module) ); + key->setKey(keyName); /// \todo This is a BAD HACK, we have to fnd a better solution to manage the settings now - CSwordBackend::FilterOptions filterOptions; + FilterOptions filterOptions; filterOptions.footnotes = false; filterOptions.strongNumbers = false; filterOptions.morphTags = false; @@ -172,7 +172,7 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD filterOptions.scriptureReferences = false; filterOptions.textualVariants = false; - CPointers::backend()->setFilterOptions(filterOptions); + CSwordBackend::instance()->setFilterOptions(filterOptions); return QString(key->strippedText()).append("\n(") .append(key->key()) @@ -180,16 +180,16 @@ const QString BtHtmlReadDisplay::text( const CDisplay::TextType format, const CD .append(key->module()->name()) .append(")"); /* ("%1\n(%2, %3)") - .arg() - .arg(key->key()) - .arg(key->module()->name());*/ + .arg() + .arg(key->key()) + .arg(key->module()->name());*/ } return QString::null; } default: return QString::null; } - return QString(); + return QString::null; } // Puts html text and javascript into QWebView @@ -198,11 +198,11 @@ void BtHtmlReadDisplay::setText( const QString& newText ) { QString jsText = newText; jsText.replace( - QString(""), - QString("") - ); + QString(""), + QString("") + ); - // Disconnect any previous connect and connect to slot that loads the javascript object + // Disconnect any previous connections and connect to slot that loads the javascript object QWebFrame* frame = mainFrame(); disconnect(frame, SIGNAL(javaScriptWindowObjectCleared()), 0, 0); bool ok = connect(frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(loadJSObject())); @@ -211,11 +211,11 @@ void BtHtmlReadDisplay::setText( const QString& newText ) { // Send text to the html viewer m_view->setHtml(jsText); - this->currentSource = jsText; + this->currentSource = jsText; } QString BtHtmlReadDisplay::getCurrentSource( ) { - return this->currentSource; + return this->currentSource; } // See if any text is selected @@ -233,10 +233,7 @@ QWidget* BtHtmlReadDisplay::view() { // Select all text in the viewer void BtHtmlReadDisplay::selectAll() { - m_jsObject->setBodyEditable(true); - m_view->triggerPageAction( QWebPage::MoveToStartOfDocument, true ); - m_view->triggerPageAction( QWebPage::SelectEndOfDocument, true ); - m_jsObject->setBodyEditable(false); + m_view->triggerPageAction( QWebPage::SelectAll, true ); } // Scroll QWebView to the correct location as specified by the anchor @@ -276,8 +273,8 @@ void BtHtmlReadDisplay::javaScriptConsoleMessage (const QString& message, int li // ----------------- BtHtmlReadDisplayView ------------------------------------- -BtHtmlReadDisplayView::BtHtmlReadDisplayView(BtHtmlReadDisplay* displayWidget, QWidget* parent) - : QWebView(parent), m_display(displayWidget) { +BtHtmlReadDisplayView::BtHtmlReadDisplayView(BtHtmlReadDisplay* displayWidget, QWidget* parent, CReadWindow* readWindow) + : QWebView(parent), m_display(displayWidget), m_readWindow(readWindow) { } BtHtmlReadDisplayView::~BtHtmlReadDisplayView() { @@ -307,17 +304,48 @@ void BtHtmlReadDisplayView::dropEvent( QDropEvent* e ) { } }; //don't accept the action! - e->ignore(); +// e->ignore(); } // Reimplementation from QWebView void BtHtmlReadDisplayView::dragEnterEvent( QDragEnterEvent* e ) { - if (e->mimeData()->hasFormat("BibleTime/Bookmark")) { - e->acceptProposedAction(); + if ( ! e->mimeData()->hasFormat("BibleTime/Bookmark")) + return; + + const QMimeData* mimedata = e->mimeData(); + if (mimedata == 0) + return; + + const BTMimeData* btmimedata = qobject_cast(mimedata); + if (btmimedata == 0) + return; + + BookmarkItem item = (qobject_cast(e->mimeData()))->bookmark(); + QString moduleName = item.module(); + CSwordModuleInfo *m = CSwordBackend::instance()->findModuleByName(moduleName); + Q_ASSERT(m); + if (m == 0) return; + + CSwordModuleInfo::ModuleType bookmarkType = m->type(); + CSwordModuleInfo::ModuleType windowType = CDisplayWindowFactory::getModuleType(m_readWindow); + + // Is bible reference bookmark compatible with the window type? + if ((bookmarkType == CSwordModuleInfo::Bible || + bookmarkType == CSwordModuleInfo::Commentary)) { + if (windowType == CSwordModuleInfo::Bible || + windowType == CSwordModuleInfo::Commentary) + e->acceptProposedAction(); + return; } - //don't accept the action! - e->ignore(); + + // Is reference type compatible with window type + if (bookmarkType == windowType) { + e->acceptProposedAction(); + return; + } + + return; } // Reimplementation from QWebView diff --git a/src/frontend/display/bthtmlreaddisplay.h b/src/frontend/display/bthtmlreaddisplay.h index e4011d0..21724b9 100644 --- a/src/frontend/display/bthtmlreaddisplay.h +++ b/src/frontend/display/bthtmlreaddisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -104,17 +104,18 @@ class BtHtmlReadDisplay : public QWebPage, public CReadDisplay { }; -class BtHtmlReadDisplayView : public QWebView, public CPointers { +class BtHtmlReadDisplayView : public QWebView { Q_OBJECT protected: friend class BtHtmlReadDisplay; void contextMenuEvent(QContextMenuEvent* event); - BtHtmlReadDisplayView(BtHtmlReadDisplay* display, QWidget* parent); + BtHtmlReadDisplayView(BtHtmlReadDisplay* display, QWidget* parent, CReadWindow* readWindow); ~BtHtmlReadDisplayView(); bool event(QEvent* e); private: BtHtmlReadDisplay* m_display; + CReadWindow* m_readWindow; void dropEvent( QDropEvent* e ); void dragEnterEvent( QDragEnterEvent* e ); void dragMoveEvent( QDragMoveEvent* e ); diff --git a/src/frontend/display/cdisplay.cpp b/src/frontend/display/cdisplay.cpp index 8135d03..78d9038 100644 --- a/src/frontend/display/cdisplay.cpp +++ b/src/frontend/display/cdisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -59,15 +59,18 @@ void CDisplayConnections::copyAll() { /** No descriptions */ void CDisplayConnections::copySelection() { - qWarning("copyign the selected text"); m_display->copy(CDisplay::PlainText, CDisplay::SelectedText); } -void CDisplayConnections::printAll(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { +void CDisplayConnections::printAll(const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ m_display->print(CDisplay::Document, displayOptions, filterOptions); } -void CDisplayConnections::printAnchorWithText(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { +void CDisplayConnections::printAnchorWithText(const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ m_display->print(CDisplay::AnchorWithText, displayOptions, filterOptions); } @@ -177,7 +180,7 @@ void CDisplay::emitReferenceDropped( const QString& reference ) { m_connections->emitReferenceDropped(key); } -/** Returns the connections obect used for signas and slots. */ +/** Returns the connections object used for signals and slots. */ CDisplayConnections* CDisplay::connectionsProxy() const { return m_connections; } diff --git a/src/frontend/display/cdisplay.h b/src/frontend/display/cdisplay.h index a7d6a03..af49178 100644 --- a/src/frontend/display/cdisplay.h +++ b/src/frontend/display/cdisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,8 +10,6 @@ #ifndef CDISPLAY_H #define CDISPLAY_H -#include "util/cpointers.h" - #include #include "backend/managers/cswordbackend.h" @@ -27,7 +25,7 @@ class QMenu; /** The base class for all display widgets. * @author The BibleTime team */ -class CDisplay : public CPointers { +class CDisplay { public: enum WriteDisplayType { HTMLDisplay = 0, @@ -84,15 +82,17 @@ class CDisplay : public CPointers { */ virtual void selectAll() = 0; /** - * Returns the connections obect used for signas and slots. + * Returns the connections object used for signals and slots. */ virtual CDisplayConnections* connectionsProxy() const; /** * Returns the parent window used for this display widget. */ CDisplayWindow* parentWindow() const; - virtual void print( const CDisplay::TextPart, CSwordBackend::DisplayOptions displayOptions, - CSwordBackend::FilterOptions filterOptions) = 0; + + virtual void print(const CDisplay::TextPart, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) = 0; /** * Installs the popup which should be opened when the right mouse button was pressed. */ @@ -151,9 +151,11 @@ class CDisplayConnections : public QObject { void saveAsHTML(); void saveAnchorWithText(); - void printAll(CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions); - void printAnchorWithText(CSwordBackend::DisplayOptions displayOptions, - CSwordBackend::FilterOptions filterOptions); + void printAll(const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); + + void printAnchorWithText(const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); void copySelection(); void copyAll(); diff --git a/src/frontend/display/chtmlwritedisplay.cpp b/src/frontend/display/chtmlwritedisplay.cpp index 4d08666..ce7b94c 100644 --- a/src/frontend/display/chtmlwritedisplay.cpp +++ b/src/frontend/display/chtmlwritedisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,13 +25,70 @@ class BtActionCollection; CHTMLWriteDisplay::CHTMLWriteDisplay(CWriteWindow* parentWindow, QWidget* parent) - : CPlainWriteDisplay(parentWindow, parent), m_fontFamilyChooser(0), - m_fontSizeChooser(0), m_colorChooser(0) { +: CPlainWriteDisplay(parentWindow, parent) { m_actions.bold = 0; m_actions.italic = 0; m_actions.underline = 0; m_actions.selectAll = 0; + //--------------------bold toggle------------------------- + namespace DU = util::directory; + m_actions.bold = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::boldText::icon), + tr("Bold"), + this); + m_actions.bold->setCheckable(true); + m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::boldText::accel); + m_actions.bold->setToolTip( tr("Bold") ); + connect(m_actions.bold, SIGNAL(toggled(bool)), this, SLOT(toggleBold(bool))); + + //--------------------italic toggle------------------------- + m_actions.italic = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::italicText::icon), + tr("Italic"), + this ); + m_actions.italic->setCheckable(true); + m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::italicText::accel); + connect(m_actions.italic, SIGNAL(toggled(bool)), this, SLOT(toggleItalic(bool))); + m_actions.italic->setToolTip( tr("Italic") ); + + //--------------------underline toggle------------------------- + m_actions.underline = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::underlinedText::icon), + tr("Underline"), + this ); + m_actions.underline->setCheckable(true); + m_actions.underline->setShortcut(CResMgr::displaywindows::writeWindow::underlinedText::accel); + connect(m_actions.underline, SIGNAL(toggled(bool)), this, SLOT(toggleUnderline(bool))); + m_actions.underline->setToolTip( tr("Underline") ); + + //--------------------align left toggle------------------------- + m_actions.alignLeft = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::alignLeft::icon), + tr("Left"), this); + m_actions.alignLeft->setCheckable(true); + m_actions.alignLeft->setShortcut(CResMgr::displaywindows::writeWindow::alignLeft::accel); + connect(m_actions.alignLeft, SIGNAL(toggled(bool)), this, SLOT(alignLeft(bool))); + m_actions.alignLeft->setToolTip( tr("Align left") ); + + //--------------------align center toggle------------------------- + m_actions.alignCenter = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::alignCenter::icon), + tr("Center"), this); + m_actions.alignCenter->setCheckable(true); + m_actions.alignCenter->setShortcut(CResMgr::displaywindows::writeWindow::alignCenter::accel); + connect(m_actions.alignCenter, SIGNAL(toggled(bool)), this, SLOT(alignCenter(bool))); + m_actions.alignCenter->setToolTip( tr("Center") ); + + //--------------------align right toggle------------------------- + m_actions.alignRight = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::alignRight::icon), + tr("Right"), this); + m_actions.alignRight->setCheckable(true); + m_actions.alignRight->setShortcut(CResMgr::displaywindows::writeWindow::alignRight::accel); + connect(m_actions.alignRight, SIGNAL(toggled(bool)), this, SLOT(alignRight(bool))); + m_actions.alignRight->setToolTip( tr("Align right") ); + setAcceptRichText(true); setAcceptDrops(true); viewport()->setAcceptDrops(true); @@ -118,12 +175,12 @@ void CHTMLWriteDisplay::slotColorSelected( const QColor& c) { /** Is called when a text with another color was selected. */ void CHTMLWriteDisplay::slotColorChanged(const QColor& c) { - m_colorChooser->setColor(c); + emit setColor(c); } void CHTMLWriteDisplay::slotFontChanged( const QFont& font ) { - m_fontFamilyChooser->setCurrentFont(font); - m_fontSizeChooser->setFontSize( font.pointSize() ); + emit fontChanged(font); + emit fontSizeChanged(font.pointSize()); m_actions.bold->setChecked( font.bold() ); m_actions.italic->setChecked( font.italic() ); @@ -135,104 +192,46 @@ void CHTMLWriteDisplay::slotFontFamilyChoosen(const QFont& font) { } void CHTMLWriteDisplay::setupToolbar(QToolBar * bar, BtActionCollection * actions) { - namespace DU = util::directory; //--------------------font chooser------------------------- - m_fontFamilyChooser = new QFontComboBox(this); - actions->addAction(CResMgr::displaywindows::writeWindow::fontFamily::actionName, m_fontFamilyChooser); - m_fontFamilyChooser->setToolTip( tr("Font") ); - bar->addWidget(m_fontFamilyChooser); - bool ok = connect(m_fontFamilyChooser, SIGNAL(currentFontChanged(const QFont&)), + QFontComboBox* fontFamilyCombo = new QFontComboBox(this); + fontFamilyCombo->setToolTip( tr("Font") ); + bar->addWidget(fontFamilyCombo); + bool ok = connect(fontFamilyCombo, SIGNAL(currentFontChanged(const QFont&)), this, SLOT(slotFontFamilyChoosen(const QFont&))); Q_ASSERT(ok); + ok = connect(this, SIGNAL(fontChanged(const QFont&)), fontFamilyCombo, SLOT(setCurrentFont(const QFont&))); + Q_ASSERT(ok); //--------------------font size chooser------------------------- - m_fontSizeChooser = new BtFontSizeWidget(this); - m_fontSizeChooser->setToolTip( tr("Font size") ); - bar->addWidget(m_fontSizeChooser); - ok = connect(m_fontSizeChooser, SIGNAL(fontSizeChanged(int)), this, SLOT(changeFontSize(int))); + BtFontSizeWidget* fontSizeChooser = new BtFontSizeWidget(this); + fontSizeChooser->setToolTip( tr("Font size") ); + bar->addWidget(fontSizeChooser); + ok = connect(fontSizeChooser, SIGNAL(fontSizeChanged(int)), this, SLOT(changeFontSize(int))); + Q_ASSERT(ok); + ok = connect(this, SIGNAL(fontSizeChanged(int)), fontSizeChooser, SLOT(setFontSize(int))); Q_ASSERT(ok); //--------------------color button------------------------- - m_colorChooser = new BtColorWidget(); - m_colorChooser->setToolTip(tr("Font color")); - bar->addWidget(m_colorChooser); - ok = connect(m_colorChooser, SIGNAL(changed(const QColor&)), this, SLOT(slotColorSelected(const QColor&))); + BtColorWidget* colorChooser = new BtColorWidget(); + colorChooser->setToolTip(tr("Font color")); + bar->addWidget(colorChooser); + ok = connect(colorChooser, SIGNAL(changed(const QColor&)), this, SLOT(slotColorSelected(const QColor&))); + Q_ASSERT(ok); + ok = connect(this, SIGNAL(setColor(const QColor&)), colorChooser, SLOT(setColor(const QColor&))); Q_ASSERT(ok); bar->addSeparator(); - //--------------------bold toggle------------------------- - m_actions.bold = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::boldText::icon), - tr("Bold"), - actions); - m_actions.bold->setCheckable(true); - m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::boldText::accel); - actions->addAction(CResMgr::displaywindows::writeWindow::boldText::actionName, m_actions.bold); - m_actions.bold->setToolTip( tr("Bold") ); - connect(m_actions.bold, SIGNAL(toggled(bool)), this, SLOT(toggleBold(bool))); - bar->addAction(m_actions.bold); - - //--------------------italic toggle------------------------- - m_actions.italic = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::italicText::icon), - tr("Italic"), - actions ); - m_actions.italic->setCheckable(true); - m_actions.bold->setShortcut(CResMgr::displaywindows::writeWindow::italicText::accel); - actions->addAction(CResMgr::displaywindows::writeWindow::italicText::actionName, m_actions.italic); - connect(m_actions.italic, SIGNAL(toggled(bool)), this, SLOT(toggleItalic(bool))); - m_actions.italic->setToolTip( tr("Italic") ); bar->addAction(m_actions.italic); - - //--------------------underline toggle------------------------- - m_actions.underline = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::underlinedText::icon), - tr("Underline"), - actions ); - m_actions.underline->setCheckable(true); - m_actions.underline->setShortcut(CResMgr::displaywindows::writeWindow::underlinedText::accel); - actions->addAction(CResMgr::displaywindows::writeWindow::underlinedText::actionName, m_actions.underline); - connect(m_actions.underline, SIGNAL(toggled(bool)), this, SLOT(toggleUnderline(bool))); - m_actions.underline->setToolTip( tr("Underline") ); bar->addAction(m_actions.underline); //seperate formatting from alignment buttons bar->addSeparator(); - //--------------------align left toggle------------------------- - m_actions.alignLeft = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::alignLeft::icon), - tr("Left"), actions); - m_actions.alignLeft->setCheckable(true); - m_actions.alignLeft->setShortcut(CResMgr::displaywindows::writeWindow::alignLeft::accel); - actions->addAction(CResMgr::displaywindows::writeWindow::alignLeft::actionName, m_actions.alignLeft); - connect(m_actions.alignLeft, SIGNAL(toggled(bool)), this, SLOT(alignLeft(bool))); - m_actions.alignLeft->setToolTip( tr("Align left") ); bar->addAction(m_actions.alignLeft); - - //--------------------align center toggle------------------------- - m_actions.alignCenter = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::alignCenter::icon), - tr("Center"), actions); - m_actions.alignCenter->setCheckable(true); - m_actions.alignCenter->setShortcut(CResMgr::displaywindows::writeWindow::alignCenter::accel); - actions->addAction(CResMgr::displaywindows::writeWindow::alignCenter::actionName, m_actions.alignCenter); - connect(m_actions.alignCenter, SIGNAL(toggled(bool)), this, SLOT(alignCenter(bool))); - m_actions.alignCenter->setToolTip( tr("Center") ); bar->addAction(m_actions.alignCenter); - - //--------------------align right toggle------------------------- - m_actions.alignRight = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::alignRight::icon), - tr("Right"), actions); - m_actions.alignRight->setCheckable(true); - m_actions.alignRight->setShortcut(CResMgr::displaywindows::writeWindow::alignRight::accel); - actions->addAction(CResMgr::displaywindows::writeWindow::alignRight::actionName, m_actions.alignRight); - connect(m_actions.alignRight, SIGNAL(toggled(bool)), this, SLOT(alignRight(bool))); - m_actions.alignRight->setToolTip( tr("Align right") ); bar->addAction(m_actions.alignRight); connect(this, SIGNAL(currentFontChanged(const QFont&)), SLOT(slotFontChanged(const QFont&))); @@ -244,16 +243,3 @@ void CHTMLWriteDisplay::setupToolbar(QToolBar * bar, BtActionCollection * action slotAlignmentChanged( alignment() ); slotColorChanged( textColor() ); } - -/** Reimplementation to show a popup menu if the right mouse button was clicked. */ -QMenu* CHTMLWriteDisplay::createPopupMenu( const QPoint& ) { - if (!m_actions.selectAll) { - m_actions.selectAll = new QAction(tr("Select all"), this); - connect(m_actions.selectAll, SIGNAL(triggered(bool)), SLOT(selectAll())); - } - - QMenu* popup = new QMenu(this); - popup->setTitle(tr("HTML editor window")); - popup->addAction(m_actions.selectAll); - return popup; -} diff --git a/src/frontend/display/chtmlwritedisplay.h b/src/frontend/display/chtmlwritedisplay.h index 56f3f53..e8e4e7c 100644 --- a/src/frontend/display/chtmlwritedisplay.h +++ b/src/frontend/display/chtmlwritedisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -48,11 +48,6 @@ class CHTMLWriteDisplay : public CPlainWriteDisplay { friend class CDisplay; CHTMLWriteDisplay(CWriteWindow* parentWindow, QWidget* parent); ~CHTMLWriteDisplay(); - /** - * Reimplementation to show a popup menu if the right mouse button was clicked. - * (CPlainWriteDisplay) - */ - virtual QMenu* createPopupMenu( const QPoint& pos ); protected slots: void toggleBold(bool); @@ -81,6 +76,11 @@ class CHTMLWriteDisplay : public CPlainWriteDisplay { */ void slotColorChanged( const QColor& ); + signals: + void fontChanged(const QFont& font); + void fontSizeChanged(int); + void setColor(const QColor&); + private: struct { QAction* bold; @@ -95,10 +95,6 @@ class CHTMLWriteDisplay : public CPlainWriteDisplay { QAction* selectAll; } m_actions; - - QFontComboBox* m_fontFamilyChooser; - BtFontSizeWidget* m_fontSizeChooser; - BtColorWidget* m_colorChooser; }; #endif diff --git a/src/frontend/display/cplainwritedisplay.cpp b/src/frontend/display/cplainwritedisplay.cpp index 720aa72..bfcbe0b 100644 --- a/src/frontend/display/cplainwritedisplay.cpp +++ b/src/frontend/display/cplainwritedisplay.cpp @@ -2,14 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ #include "frontend/display/cplainwritedisplay.h" -#include +#include #include #include #include @@ -42,7 +42,7 @@ void CPlainWriteDisplay::selectAll() { void CPlainWriteDisplay::setText( const QString& newText ) { //make sure the text has been converted to show \n instead of
    QString text = newText; -// text.replace("\n
    \n", "\n"); +// text.replace("\n
    \n", "\n"); text.replace("
    ", "\n"); //inserted by BT or the Qt textedit widget QTextEdit::setText(text); @@ -62,9 +62,6 @@ const QString CPlainWriteDisplay::text( const CDisplay::TextType /*format*/, con return QString::null; } -void CPlainWriteDisplay::print( const CDisplay::TextPart, CSwordBackend::DisplayOptions, CSwordBackend::FilterOptions) { -} - /** Sets the current status of the edit widget. */ void CPlainWriteDisplay::setModified( const bool modified ) { document()->setModified(modified); @@ -86,16 +83,6 @@ const QString CPlainWriteDisplay::plainText() { return ret; } -/** Reimplementation from QTextEdit. Provides an popup menu for the given position. */ -QMenu* CPlainWriteDisplay::createPopupMenu( const QPoint& /*pos*/ ) { - return installedPopup(); -} -// -///** Reimplementation from QTextEdit. Provides an popup menu for the given position. */ -//QMenu* CPlainWriteDisplay::createPopupMenu( ) { -// return installedPopup(); -//} - /** Creates the necessary action objects and puts them on the toolbar. */ void CPlainWriteDisplay::setupToolbar(QToolBar*, BtActionCollection*) {} @@ -138,9 +125,9 @@ void CPlainWriteDisplay::dropEvent( QDropEvent* e ) { BTMimeData::ItemList::iterator it; for (it = items.begin(); it != items.end(); ++it) { - CSwordModuleInfo* module = backend()->findModuleByName((*it).module()); - boost::scoped_ptr key( CSwordKey::createInstance(module) ); - key->key( (*it).key() ); + CSwordModuleInfo *module = CSwordBackend::instance()->findModuleByName((*it).module()); + QSharedPointer key( CSwordKey::createInstance(module) ); + key->setKey((*it).key()); QString moduleText = key->strippedText(); const QString text = QString::fromLatin1("%1\n(%2, %3)\n").arg(moduleText).arg((*it).key()).arg((*it).module()); diff --git a/src/frontend/display/cplainwritedisplay.h b/src/frontend/display/cplainwritedisplay.h index 30efc72..2c7e1be 100644 --- a/src/frontend/display/cplainwritedisplay.h +++ b/src/frontend/display/cplainwritedisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -44,7 +44,14 @@ class CPlainWriteDisplay : public QTextEdit, public CWriteDisplay { */ virtual QWidget* view(); virtual const QString text( const CDisplay::TextType format = CDisplay::HTMLText, const CDisplay::TextPart part = CDisplay::Document ); - virtual void print( const CDisplay::TextPart, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions ); + + /** + Reimplemented from CDisplay. + */ + virtual inline void print(const CDisplay::TextPart, + const DisplayOptions &, + const FilterOptions &) {} + /** * Reimplementation (CWriteDisplay). */ @@ -68,14 +75,7 @@ class CPlainWriteDisplay : public QTextEdit, public CWriteDisplay { CPlainWriteDisplay(CWriteWindow* parentWindow, QWidget* parent); virtual ~CPlainWriteDisplay(); - /** - * Reimplementation from QTextEdit. Provides an popup menu for the given position. - */ - virtual QMenu* createPopupMenu( const QPoint& pos ); -// /** -// * Reimplementation from QTextEdit. Provides an popup menu. -// */ -// virtual QMenu* createPopupMenu(); + /** * Reimplementation from QTextEdit to manage drops of our drag and drop objects. */ diff --git a/src/frontend/display/creaddisplay.cpp b/src/frontend/display/creaddisplay.cpp index 90175d4..690ee57 100644 --- a/src/frontend/display/creaddisplay.cpp +++ b/src/frontend/display/creaddisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -46,10 +46,14 @@ bool CReadDisplay::hasActiveAnchor() { } -void CReadDisplay::print(const CDisplay::TextPart type, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions) { +void CReadDisplay::print(const CDisplay::TextPart type, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions) +{ + typedef CSwordBibleModuleInfo CSBiMI; CDisplayWindow* window = parentWindow(); CSwordKey* const key = window->key(); - CSwordModuleInfo* module = key->module(); + const CSwordModuleInfo *module = key->module(); const CDisplayWindow *displayWindow = parentWindow(); CExportManager mgr(QObject::tr("Print keys"), false, QString::null, displayWindow->filterOptions(), displayWindow->displayOptions()); @@ -64,7 +68,7 @@ void CReadDisplay::print(const CDisplay::TextPart type, CSwordBackend::DisplayOp CSwordVerseKey stopKey(*vk); - CSwordBibleModuleInfo* bible = dynamic_cast(module); + const CSBiMI *bible = dynamic_cast(module); if (bible) { stopKey.Verse( bible->verseCount( bible->bookNumber(startKey.book()), startKey.Chapter() ) ); } diff --git a/src/frontend/display/creaddisplay.h b/src/frontend/display/creaddisplay.h index b766f5b..d1e81c4 100644 --- a/src/frontend/display/creaddisplay.h +++ b/src/frontend/display/creaddisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -33,8 +33,10 @@ class CReadDisplay : public CDisplay { * Moves the widget to the given anchor. */ virtual void moveToAnchor( const QString& ) = 0; - virtual void print(const CDisplay::TextPart, CSwordBackend::DisplayOptions displayOptions, - CSwordBackend::FilterOptions filterOptions); + + virtual void print(const CDisplay::TextPart, + const DisplayOptions &displayOptions, + const FilterOptions &filterOptions); void setMouseTracking(const bool trackingEnabled) { m_useMouseTracking = trackingEnabled; diff --git a/src/frontend/display/cwritedisplay.cpp b/src/frontend/display/cwritedisplay.cpp index f30d217..47a3302 100644 --- a/src/frontend/display/cwritedisplay.cpp +++ b/src/frontend/display/cwritedisplay.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/display/cwritedisplay.h b/src/frontend/display/cwritedisplay.h index 33ef5a5..3591efe 100644 --- a/src/frontend/display/cwritedisplay.h +++ b/src/frontend/display/cwritedisplay.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/displaywindow/btactioncollection.cpp b/src/frontend/displaywindow/btactioncollection.cpp index f1956d5..9c26143 100644 --- a/src/frontend/displaywindow/btactioncollection.cpp +++ b/src/frontend/displaywindow/btactioncollection.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,8 +21,10 @@ class BtActionItem : public QObject { public: - BtActionItem(QObject* parent) - : QObject(parent) { + BtActionItem(QAction *action, QObject *parent = 0) + : QObject(parent), defaultKeys(action->shortcut()), action(action) + { + // Intentionally empty } QKeySequence defaultKeys; QAction* action; @@ -56,13 +58,11 @@ QAction* BtActionCollection::action(const QString& name) { QAction* BtActionCollection::addAction(const QString& name, QAction* action) { Q_ASSERT(action != 0); - Q_ASSERT(m_actions[name] == 0); /// \todo replacing actions is ok??? - int count; - count = m_actions.count(); - BtActionItem* item = new BtActionItem(this); - item->action = action; - item->defaultKeys = action->shortcut(); - m_actions[name] = item; + if (m_actions.contains(name)) { + delete m_actions[name]; + } + BtActionItem* item = new BtActionItem(action, this); + m_actions.insert(name, item); return action; } diff --git a/src/frontend/displaywindow/btactioncollection.h b/src/frontend/displaywindow/btactioncollection.h index 9a02958..2ce273d 100644 --- a/src/frontend/displaywindow/btactioncollection.h +++ b/src/frontend/displaywindow/btactioncollection.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/displaywindow/btdisplaysettingsbutton.cpp b/src/frontend/displaywindow/btdisplaysettingsbutton.cpp index e809efc..2fa1d2d 100644 --- a/src/frontend/displaywindow/btdisplaysettingsbutton.cpp +++ b/src/frontend/displaywindow/btdisplaysettingsbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,7 +15,6 @@ #include #include #include "util/directory.h" -#include "util/cpointers.h" #include "util/cresmgr.h" @@ -37,7 +36,8 @@ BtDisplaySettingsButton::BtDisplaySettingsButton(QWidget *parent) } void BtDisplaySettingsButton::setDisplayOptions( - const CSwordBackend::DisplayOptions &displaySettings, bool repopulate) + const DisplayOptions &displaySettings, + bool repopulate) { m_displayOptions = displaySettings; if (repopulate) { @@ -46,7 +46,7 @@ void BtDisplaySettingsButton::setDisplayOptions( } void BtDisplaySettingsButton::setFilterOptions( - const CSwordBackend::FilterOptions &moduleSettings, + const FilterOptions &moduleSettings, bool repopulate) { m_filterOptions = moduleSettings; @@ -55,7 +55,9 @@ void BtDisplaySettingsButton::setFilterOptions( } } -void BtDisplaySettingsButton::setModules(const QList &modules) { +void BtDisplaySettingsButton::setModules( + const QList &modules) +{ m_modules = modules; repopulateMenu(); } @@ -225,7 +227,7 @@ void BtDisplaySettingsButton::addMenuEntry(QAction *action, bool checked) { } bool BtDisplaySettingsButton::isOptionAvailable(const CSwordModuleInfo::FilterTypes option) { - foreach (CSwordModuleInfo *module, m_modules) { + Q_FOREACH (const CSwordModuleInfo *module, m_modules) { if (module->has(option)) return true; } return false; diff --git a/src/frontend/displaywindow/btdisplaysettingsbutton.h b/src/frontend/displaywindow/btdisplaysettingsbutton.h index e947e83..489395e 100644 --- a/src/frontend/displaywindow/btdisplaysettingsbutton.h +++ b/src/frontend/displaywindow/btdisplaysettingsbutton.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,6 +13,7 @@ #include #include "backend/managers/cswordbackend.h" +#include "btglobal.h" class CSwordModuleInfo; @@ -27,15 +28,18 @@ class BtDisplaySettingsButton: public QToolButton { public: BtDisplaySettingsButton(QWidget *parent = 0); - void setDisplayOptions(const CSwordBackend::DisplayOptions &displaySettings, + public slots: + void setDisplayOptions(const DisplayOptions &displaySettings, bool repopulate = true); - void setFilterOptions(const CSwordBackend::FilterOptions &moduleSettings, + void setFilterOptions(const FilterOptions &moduleSettings, bool repopulate = true); - void setModules(const QList &modules); + + void setModules(const QList &modules); signals: - void sigFilterOptionsChanged(CSwordBackend::FilterOptions filterOptions); - void sigDisplayOptionsChanged(CSwordBackend::DisplayOptions displayOptions); + void sigFilterOptionsChanged(FilterOptions filterOptions); + void sigDisplayOptionsChanged(DisplayOptions displayOptions); + void sigModulesChanged(const QList &modules); void sigChanged(void); protected slots: @@ -51,9 +55,9 @@ class BtDisplaySettingsButton: public QToolButton { void addMenuEntry(QAction *action, bool checked); private: - CSwordBackend::FilterOptions m_filterOptions; - CSwordBackend::DisplayOptions m_displayOptions; - QList m_modules; + FilterOptions m_filterOptions; + DisplayOptions m_displayOptions; + QList m_modules; QMenu *m_popup; QAction *m_lineBreakAction; diff --git a/src/frontend/displaywindow/btmodulechooserbar.cpp b/src/frontend/displaywindow/btmodulechooserbar.cpp index e07e739..29be862 100644 --- a/src/frontend/displaywindow/btmodulechooserbar.cpp +++ b/src/frontend/displaywindow/btmodulechooserbar.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,24 +17,18 @@ #include -BtModuleChooserBar::BtModuleChooserBar(QStringList useModules, CSwordModuleInfo::ModuleType type, CReadWindow *parent) +BtModuleChooserBar::BtModuleChooserBar(QWidget *parent) : QToolBar(parent), - BtWindowModuleChooser(parent, type), - m_idCounter(0) { + BtWindowModuleChooser(CSwordModuleInfo::Unknown, 0), + m_idCounter(0), + m_window(0) { qDebug() << "BtModuleChooserBar::BtModuleChooserBar"; setAllowedAreas(Qt::TopToolBarArea); setFloatable(false); - setModules(useModules); - connect(parent, SIGNAL(sigModuleListSet(QStringList)), SLOT(slotBackendModulesChanged())); - connect(parent, SIGNAL(sigModuleListChanged()), SLOT(slotWindowModulesChanged())); } void BtModuleChooserBar::slotBackendModulesChanged() { - backendModulesChanged(); -} - -void BtModuleChooserBar::backendModulesChanged() { m_modules = m_window->getModuleList(); adjustButtonCount(); @@ -48,10 +42,6 @@ void BtModuleChooserBar::backendModulesChanged() { } } -void BtModuleChooserBar::slotWindowModulesChanged() { - windowModulesChanged(); -} - void BtModuleChooserBar::adjustButtonCount(bool adjustToZero) { //qDebug() << "BtModuleChooserBar::ajustButtonCount"; int buttonCountDifference = 0; @@ -67,11 +57,7 @@ void BtModuleChooserBar::adjustButtonCount(bool adjustToZero) { //if there are more buttons than modules, delete buttons if (buttonCountDifference > 0) { for (int j = 0; j < buttonCountDifference; j++) { - //qDebug() << "delete first button, " << j; - // it should be safe to delete the button later - BtModuleChooserButton* b = m_buttonList.takeFirst(); - b->setParent(0); - b->deleteLater(); + delete m_buttonList.takeFirst(); } } // if there are more modules than buttons, add buttons @@ -82,7 +68,7 @@ void BtModuleChooserBar::adjustButtonCount(bool adjustToZero) { } } -void BtModuleChooserBar::windowModulesChanged() { +void BtModuleChooserBar::slotWindowModulesChanged() { //qDebug() << "BtModuleChooserBar::windowModulesChanged"; m_modules = m_window->getModuleList(); adjustButtonCount(); @@ -105,10 +91,16 @@ BtModuleChooserButton* BtModuleChooserBar::addButton() { return b; } + /** Sets the modules which are chosen in this module chooser bar. */ -void BtModuleChooserBar::setModules( QStringList useModules ) { +void BtModuleChooserBar::setModules( QStringList useModules,CSwordModuleInfo::ModuleType type, CReadWindow* window) { qDebug() << "BtModuleChooserBar::setModules"; m_modules = useModules; + m_window = window; + m_moduleType = type; + + clear(); + adjustButtonCount(true); //if (!useModules.count()) return; @@ -120,6 +112,9 @@ void BtModuleChooserBar::setModules( QStringList useModules ) { } updateButtonMenus(); qDebug() << "BtModuleChooserBar::setModules end"; + + connect(m_window, SIGNAL(sigModuleListSet(QStringList)), SLOT(slotBackendModulesChanged())); + connect(m_window, SIGNAL(sigModuleListChanged()), SLOT(slotWindowModulesChanged())); } void BtModuleChooserBar::updateButtonMenus() { diff --git a/src/frontend/displaywindow/btmodulechooserbar.h b/src/frontend/displaywindow/btmodulechooserbar.h index 7ae903c..977d3c0 100644 --- a/src/frontend/displaywindow/btmodulechooserbar.h +++ b/src/frontend/displaywindow/btmodulechooserbar.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,31 +21,26 @@ class BtModuleChooserButton; class BtModuleChooserBar: public QToolBar, public BtWindowModuleChooser { Q_OBJECT public: - BtModuleChooserBar(QStringList useModules, CSwordModuleInfo::ModuleType type, CReadWindow* parent); + BtModuleChooserBar(QWidget* parent); + /** Initialize with module list.*/ + void setModules( QStringList useModules,CSwordModuleInfo::ModuleType type, CReadWindow* window); public slots: - /** The backend module list was updated, module list and widgets must be updated*/ - void slotBackendModulesChanged(); - void slotWindowModulesChanged(); - - protected: /** * The backend module list was updated, module list and widgets must be updated. * The signal comes from the window, not from the backend. The new list can * be shorter but not longer than the old list. */ - virtual void backendModulesChanged(); + void slotBackendModulesChanged(); + /** * The window module list was changed, i.e. 1 module added, removed or replaced. */ - virtual void windowModulesChanged(); + void slotWindowModulesChanged(); private: /** Adds an empty button to the toolbar.*/ BtModuleChooserButton* addButton(); - /** Initialize with module list.*/ - void setModules( QStringList useModules ); - /** Updates every button's menu without recreating it.*/ void updateButtonMenus(); /** @@ -56,6 +51,8 @@ class BtModuleChooserBar: public QToolBar, public BtWindowModuleChooser { private: int m_idCounter; + CReadWindow* m_window; + CSwordModuleInfo::ModuleType m_moduleType; QList m_buttonList; }; diff --git a/src/frontend/displaywindow/btmodulechooserbutton.cpp b/src/frontend/displaywindow/btmodulechooserbutton.cpp index 549123f..9c8ad2f 100644 --- a/src/frontend/displaywindow/btmodulechooserbutton.cpp +++ b/src/frontend/displaywindow/btmodulechooserbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,7 +20,6 @@ #include "frontend/displaywindow/btmodulechooserbar.h" #include "util/cresmgr.h" #include "util/directory.h" -#include "util/cpointers.h" BtModuleChooserButton::BtModuleChooserButton(BtModuleChooserBar *parent, CSwordModuleInfo::ModuleType mtype) diff --git a/src/frontend/displaywindow/btmodulechooserbutton.h b/src/frontend/displaywindow/btmodulechooserbutton.h index 9835eb0..270603b 100644 --- a/src/frontend/displaywindow/btmodulechooserbutton.h +++ b/src/frontend/displaywindow/btmodulechooserbutton.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/displaywindow/bttextwindowheader.cpp b/src/frontend/displaywindow/bttextwindowheader.cpp index cd5392f..5bacf2b 100644 --- a/src/frontend/displaywindow/bttextwindowheader.cpp +++ b/src/frontend/displaywindow/bttextwindowheader.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,9 +22,12 @@ #include #include -BtTextWindowHeader::BtTextWindowHeader ( CDisplayWindow* window, CSwordModuleInfo::ModuleType modtype, QStringList modules ) - : QWidget ( window ), - BtWindowModuleChooser(window, modtype) { +BtTextWindowHeader::BtTextWindowHeader(CSwordModuleInfo::ModuleType modtype, + QStringList modules, + CDisplayWindow *window) + : QWidget(window), + BtWindowModuleChooser(modtype, window) +{ QHBoxLayout* layout = new QHBoxLayout ( this ); layout->setContentsMargins(0, 0, 0, 0); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); @@ -37,10 +40,6 @@ BtTextWindowHeader::BtTextWindowHeader ( CDisplayWindow* window, CSwordModuleInf BtTextWindowHeader::~BtTextWindowHeader() {} void BtTextWindowHeader::slotBackendModulesChanged() { - backendModulesChanged(); -} - -void BtTextWindowHeader::backendModulesChanged() { m_modules = m_window->getModuleList(); adjustWidgetCount(); @@ -55,10 +54,6 @@ void BtTextWindowHeader::backendModulesChanged() { } void BtTextWindowHeader::slotWindowModulesChanged() { - windowModulesChanged(); -} - -void BtTextWindowHeader::windowModulesChanged() { m_modules = m_window->getModuleList(); adjustWidgetCount(); updateWidgets(); diff --git a/src/frontend/displaywindow/bttextwindowheader.h b/src/frontend/displaywindow/bttextwindowheader.h index a3e6b6b..1ea86b4 100644 --- a/src/frontend/displaywindow/bttextwindowheader.h +++ b/src/frontend/displaywindow/bttextwindowheader.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,19 +22,20 @@ class BtTextWindowHeaderWidget; class BtTextWindowHeader: public QWidget, public BtWindowModuleChooser { Q_OBJECT public: - BtTextWindowHeader(CDisplayWindow* window, CSwordModuleInfo::ModuleType modtype, QStringList modules); + BtTextWindowHeader(CSwordModuleInfo::ModuleType modtype, QStringList modules, CDisplayWindow *window); virtual ~BtTextWindowHeader(); public slots: + /** + The backend module list was updated, module list and widgets must be updated from + scratch. + */ void slotBackendModulesChanged(); - void slotWindowModulesChanged(); - - protected: - /** The backend module list was updated, module list and widgets must be updated from scratch.*/ - void backendModulesChanged(); - /** The window module list was updated, module list and widgets must be updated.*/ - void windowModulesChanged(); + /** + The window module list was updated, module list and widgets must be updated. + */ + void slotWindowModulesChanged(); signals: /** User selected a module from menu to replace another module*/ diff --git a/src/frontend/displaywindow/bttextwindowheaderwidget.cpp b/src/frontend/displaywindow/bttextwindowheaderwidget.cpp index 3858efb..f0829bc 100644 --- a/src/frontend/displaywindow/bttextwindowheaderwidget.cpp +++ b/src/frontend/displaywindow/bttextwindowheaderwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -24,7 +24,6 @@ #include "frontend/displaywindow/bttextwindowheader.h" #include "util/cresmgr.h" #include "util/directory.h" -#include "util/cpointers.h" const char* ActionType = "ActionType"; diff --git a/src/frontend/displaywindow/bttextwindowheaderwidget.h b/src/frontend/displaywindow/bttextwindowheaderwidget.h index 2b5379e..d2bbe40 100644 --- a/src/frontend/displaywindow/bttextwindowheaderwidget.h +++ b/src/frontend/displaywindow/bttextwindowheaderwidget.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/displaywindow/bttoolbarpopupaction.cpp b/src/frontend/displaywindow/bttoolbarpopupaction.cpp index 49b145e..1a5593b 100644 --- a/src/frontend/displaywindow/bttoolbarpopupaction.cpp +++ b/src/frontend/displaywindow/bttoolbarpopupaction.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,15 +15,18 @@ #include -class BtToolButton : public QToolButton { +namespace { + +class BtToolButton: public QToolButton { public: - BtToolButton(QWidget* parent = 0) : QToolButton(parent) { - } + inline BtToolButton(QWidget *parent = 0) + : QToolButton(parent) {} private: - void nextCheckState() { - } + virtual inline void nextCheckState() {} }; +} // anonymous namespace + // This class provides a toolbar widget that has a icon plus a right side down arrow // The icon is typically set to a back or forward arrow and the down arrow has a popup diff --git a/src/frontend/displaywindow/bttoolbarpopupaction.h b/src/frontend/displaywindow/bttoolbarpopupaction.h index 202a006..ebbc848 100644 --- a/src/frontend/displaywindow/bttoolbarpopupaction.h +++ b/src/frontend/displaywindow/bttoolbarpopupaction.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -32,9 +32,6 @@ class BtToolBarPopupAction : public QWidgetAction { // Function to catch the Shortcut event and emit the triggered signal virtual bool event(QEvent* e); - signals: - void triggered(); - protected: QWidget* createWidget(QWidget* parent); diff --git a/src/frontend/displaywindow/btwindowmodulechooser.h b/src/frontend/displaywindow/btwindowmodulechooser.h index c30c284..1cf3fd1 100644 --- a/src/frontend/displaywindow/btwindowmodulechooser.h +++ b/src/frontend/displaywindow/btwindowmodulechooser.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -35,20 +35,20 @@ class CDisplayWindow; */ class BtWindowModuleChooser { public: - BtWindowModuleChooser ( CDisplayWindow* parentWindow, CSwordModuleInfo::ModuleType moduleType ) - : m_window ( parentWindow ), m_moduleType ( moduleType ) {} + BtWindowModuleChooser(CSwordModuleInfo::ModuleType moduleType, + CDisplayWindow *parentWindow) + : m_window(parentWindow), m_moduleType (moduleType) {} virtual ~BtWindowModuleChooser() {} - protected: /** * The backend module list was updated, module list and widgets must be updated. * This expects that the window module list has already been updated, so * the corresponding slot should be connected to the window, not to the backend. */ - virtual void backendModulesChanged() = 0; + virtual void slotBackendModulesChanged() = 0; /** Modules have been added, replaced or removed in the window without backend changing.*/ - virtual void windowModulesChanged() = 0; + virtual void slotWindowModulesChanged() = 0; protected: diff --git a/src/frontend/displaywindow/cbiblereadwindow.cpp b/src/frontend/displaywindow/cbiblereadwindow.cpp index 70dbd35..868dd8d 100644 --- a/src/frontend/displaywindow/cbiblereadwindow.cpp +++ b/src/frontend/displaywindow/cbiblereadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -46,8 +46,8 @@ CBibleReadWindow::~CBibleReadWindow() { void CBibleReadWindow::applyProfileSettings(CProfileWindow* const settings) { /** - \todo Make \ref CProfileWindow properly handle these things so we wouldn't have to mess - around with bits. + \todo Make CProfileWindow properly handle these things so we wouldn't have + to mess around with bits. */ CLexiconReadWindow::applyProfileSettings(settings); @@ -68,14 +68,17 @@ void CBibleReadWindow::applyProfileSettings(CProfileWindow* const settings) { displayOptions().lineBreaks = (result & 0x1000) != 0; displayOptions().verseNumbers = (result & 0x2000) != 0; - displaySettingsButton()->setFilterOptions(filterOptions(), false); - displaySettingsButton()->setDisplayOptions(displayOptions()); + emit sigFilterOptionsChanged(filterOptions()); + emit sigDisplayOptionsChanged(displayOptions()); + + // Apply settings to display: + lookup(); } void CBibleReadWindow::storeProfileSettings( CProfileWindow * const settings) { /** - \todo Make \ref CProfileWindow properly handle these things so we wouldn't have to mess - around with bits. + \todo Make CProfileWindow properly handle these things so we wouldn't have + to mess around with bits. */ int result = 0x0000; @@ -142,13 +145,13 @@ void CBibleReadWindow::insertKeyboardActions( BtActionCollection* const a ) { qaction->setShortcut(QKeySequence::Print); a->addAction("printChapter", qaction); -// qaction = new QAction( /* QIcon(CResMgr::displaywindows::general::findStrongs::icon), */ tr("Strong's search"), a); -// qaction->setShortcut(CResMgr::displaywindows::general::findStrongs::accel); -// qaction->setToolTip(tr("Find all occurences of the Strong number currently under the mouse cursor")); -// a->addAction(CResMgr::displaywindows::general::findStrongs::actionName, qaction); +// qaction = new QAction( /* QIcon(CResMgr::displaywindows::general::findStrongs::icon), */ tr("Strong's search"), a); +// qaction->setShortcut(CResMgr::displaywindows::general::findStrongs::accel); +// qaction->setToolTip(tr("Find all occurences of the Strong number currently under the mouse cursor")); +// a->addAction(CResMgr::displaywindows::general::findStrongs::actionName, qaction); -// qaction = new QAction(tr("Reference only"), a ); -// a->addAction("copyReferenceOnly", qaction); +// qaction = new QAction(tr("Reference only"), a ); +// a->addAction("copyReferenceOnly", qaction); qaction = new QAction(tr("Text of reference"), a); a->addAction("copyTextOfReference", qaction); @@ -364,7 +367,7 @@ void CBibleReadWindow::previousVerse() { } } -/** rapper around key() to return the right type of key. */ +/** wrapper around key() to return the right type of key. */ CSwordVerseKey* CBibleReadWindow::verseKey() { CSwordVerseKey* k = dynamic_cast(CDisplayWindow::key()); Q_ASSERT(k); @@ -380,7 +383,7 @@ void CBibleReadWindow::copyDisplayedText() { CSwordVerseKey vk(*verseKey()); vk.LowerBound(dummy); - CSwordBibleModuleInfo* bible = dynamic_cast(modules().first()); + const CSwordBibleModuleInfo* bible = dynamic_cast(modules().first()); dummy.Verse(bible->verseCount(dummy.book(), dummy.Chapter())); vk.UpperBound(dummy); @@ -391,10 +394,8 @@ void CBibleReadWindow::copyDisplayedText() { /** Saves the chapter as valid HTML page. */ void CBibleReadWindow::saveChapterHTML() { //saves the complete chapter to disk - CSwordBibleModuleInfo* bible = dynamic_cast(modules().first()); - Q_ASSERT(bible); - if (!bible) //shouldn't happen - return; + Q_ASSERT(dynamic_cast(modules().first()) != 0); + const CSwordBibleModuleInfo *bible = static_cast(modules().first()); CSwordVerseKey dummy(*verseKey()); dummy.Verse(1); @@ -419,7 +420,7 @@ void CBibleReadWindow::saveChapterPlain() { dummy.Verse(1); vk.LowerBound(dummy); - CSwordBibleModuleInfo* bible = dynamic_cast(modules().first()); + const CSwordBibleModuleInfo* bible = dynamic_cast(modules().first()); dummy.Verse(bible->verseCount(dummy.book(), dummy.Chapter())); vk.UpperBound(dummy); @@ -436,7 +437,7 @@ void CBibleReadWindow::reload(CSwordBackend::SetupChangedReason reason) { } //refresh the book lists - verseKey()->setLocale( backend()->booknameLanguage().toLatin1() ); + verseKey()->setLocale( CSwordBackend::instance()->booknameLanguage().toLatin1() ); keyChooser()->refreshContent(); CBTConfig::setupAccelSettings(CBTConfig::bibleWindow, actionCollection()); @@ -477,3 +478,7 @@ void CBibleReadWindow::syncWindows() { } } } + +void CBibleReadWindow::setupMainWindowToolBars() { + CLexiconReadWindow::setupMainWindowToolBars(); +} diff --git a/src/frontend/displaywindow/cbiblereadwindow.h b/src/frontend/displaywindow/cbiblereadwindow.h index 11f0275..117c778 100644 --- a/src/frontend/displaywindow/cbiblereadwindow.h +++ b/src/frontend/displaywindow/cbiblereadwindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -48,6 +48,8 @@ class CBibleReadWindow : public CLexiconReadWindow { virtual void initToolbars(); virtual void initConnections(); virtual void initView(); + /** Called to add actions to mainWindow toolbars */ + virtual void setupMainWindowToolBars(); /** * Reimplementation. */ diff --git a/src/frontend/displaywindow/cbookreadwindow.cpp b/src/frontend/displaywindow/cbookreadwindow.cpp index 062d42d..3aba333 100644 --- a/src/frontend/displaywindow/cbookreadwindow.cpp +++ b/src/frontend/displaywindow/cbookreadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,6 +13,7 @@ #include #include #include +#include "bibletime.h" #include "backend/config/cbtconfig.h" #include "backend/keys/cswordtreekey.h" #include "frontend/display/cdisplay.h" @@ -91,29 +92,27 @@ void CBookReadWindow::initConnections() { /** Init the view */ void CBookReadWindow::initView() { QSplitter* splitter = new QSplitter(this); + m_treeChooser = new CBookTreeChooser(modules(), history(), key(), splitter); + setDisplayWidget( CDisplay::createReadInstance(this, splitter) ); + m_treeChooser->hide(); + // Create Navigation toolbar setMainToolBar( new QToolBar(this) ); mainToolBar()->setAllowedAreas(Qt::TopToolBarArea); mainToolBar()->setFloatable(false); - addToolBar(mainToolBar()); + setKeyChooser( CKeyChooser::createInstance(modules(), history(), key(), mainToolBar()) ); - m_treeChooser = new CBookTreeChooser(modules(), key(), splitter); - setDisplayWidget( CDisplay::createReadInstance(this, splitter) ); - - setKeyChooser( CKeyChooser::createInstance(modules(), key(), mainToolBar()) ); - - setModuleChooserBar( new BtModuleChooserBar(getModuleList(), modules().first()->type(), this) ); + // Create the Works toolbar + setModuleChooserBar( new BtModuleChooserBar(this)); + moduleChooserBar()->setModules(getModuleList(), modules().first()->type(), this); addToolBar(moduleChooserBar()); + // Create the Tools toolbar setButtonsToolBar( new QToolBar(this) ); buttonsToolBar()->setAllowedAreas(Qt::TopToolBarArea); buttonsToolBar()->setFloatable(false); - - setDisplaySettingsButton(new BtDisplaySettingsButton(buttonsToolBar())); - addToolBar(buttonsToolBar()); - m_treeChooser->hide(); setCentralWidget( splitter ); setWindowIcon(util::tool::getIconForModule(modules().first())); @@ -125,18 +124,44 @@ void CBookReadWindow::initToolbars() { mainToolBar()->addAction(m_actions.backInHistory); mainToolBar()->addAction(m_actions.forwardInHistory); - mainToolBar()->addWidget(keyChooser()); - buttonsToolBar()->addAction(m_treeAction); + // Tools toolbar + buttonsToolBar()->addAction(m_treeAction); // Tree m_treeAction->setChecked(false); + BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); + setDisplaySettingsButton(button); + buttonsToolBar()->addWidget(button); // Display settings + QAction* action = qobject_cast(actionCollection()->action( + CResMgr::displaywindows::general::search::actionName )); + if (action) { + buttonsToolBar()->addAction(action); // Search + } +} - buttonsToolBar()->addWidget(displaySettingsButton()); - +void CBookReadWindow::setupMainWindowToolBars() { + // Navigation toolbar + btMainWindow()->navToolBar()->addAction(m_actions.backInHistory); //1st button + btMainWindow()->navToolBar()->addAction(m_actions.forwardInHistory); //2nd button + CKeyChooser* keyChooser = CKeyChooser::createInstance(modules(), history(), key(), btMainWindow()->navToolBar() ); + btMainWindow()->navToolBar()->addWidget(keyChooser); + bool ok = connect(keyChooser, SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); + Q_ASSERT(ok); + ok = connect(this, SIGNAL(sigKeyChanged(CSwordKey*)), keyChooser, SLOT(updateKey(CSwordKey*)) ); + Q_ASSERT(ok); + + // Works toolbar + btMainWindow()->worksToolBar()->setModules(getModuleList(), modules().first()->type(), this); + + // Tools toolbar + btMainWindow()->toolsToolBar()->addAction(m_treeAction); // Tree + BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); + setDisplaySettingsButton(button); + btMainWindow()->toolsToolBar()->addWidget(button); // Display settings QAction* action = qobject_cast(actionCollection()->action( CResMgr::displaywindows::general::search::actionName )); if (action) { - buttonsToolBar()->addAction(action); + btMainWindow()->toolsToolBar()->addAction(action); // Search } } diff --git a/src/frontend/displaywindow/cbookreadwindow.h b/src/frontend/displaywindow/cbookreadwindow.h index b059aff..8b85504 100644 --- a/src/frontend/displaywindow/cbookreadwindow.h +++ b/src/frontend/displaywindow/cbookreadwindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's BtActionCollection code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime BtActionCollection code is licensed under the GNU General Public License version 2.0. * **********/ @@ -48,6 +48,8 @@ class CBookReadWindow : public CLexiconReadWindow { virtual void initToolbars(); virtual void initConnections(); virtual void initView(); + /** Called to add actions to mainWindow toolbars */ + virtual void setupMainWindowToolBars(); virtual void setupPopupMenu(); diff --git a/src/frontend/displaywindow/ccommentaryreadwindow.cpp b/src/frontend/displaywindow/ccommentaryreadwindow.cpp index 4b4d3c2..b1a291f 100644 --- a/src/frontend/displaywindow/ccommentaryreadwindow.cpp +++ b/src/frontend/displaywindow/ccommentaryreadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,9 +15,11 @@ #include #include "backend/config/cbtconfig.h" #include "backend/keys/cswordversekey.h" +#include "bibletime.h" #include "frontend/display/cdisplay.h" #include "frontend/display/creaddisplay.h" #include "frontend/displaywindow/btactioncollection.h" +#include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/profile/cprofilewindow.h" #include "util/directory.h" @@ -29,6 +31,7 @@ CCommentaryReadWindow::CCommentaryReadWindow(QList modules, C } void CCommentaryReadWindow::insertKeyboardActions(BtActionCollection* const a) { + namespace DU = util::directory; QAction* qaction; qaction = new QAction(tr("Next book"), a); @@ -54,6 +57,13 @@ void CCommentaryReadWindow::insertKeyboardActions(BtActionCollection* const a) { qaction = new QAction(tr("Previous verse"), a); qaction->setShortcut(CResMgr::displaywindows::bibleWindow::previousVerse::accel); a->addAction("previousVerse", qaction); + + qaction = new QAction(QIcon(DU::getIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon)), + tr("Synchronize"), a); + qaction->setCheckable(true); + qaction->setShortcut(CResMgr::displaywindows::commentaryWindow::syncWindow::accel); + qaction->setToolTip(tr("Synchronize the displayed entry of this work with the active Bible window")); + a->addAction(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName, qaction); } void CCommentaryReadWindow::initActions() { @@ -91,6 +101,10 @@ void CCommentaryReadWindow::initActions() { QObject::connect(qaction, SIGNAL(triggered()), this, SLOT(previousVerse()) ); addAction(qaction); + qaction = ac->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + m_syncButton = qaction; + addAction(qaction); + CBTConfig::setupAccelSettings(CBTConfig::commentaryWindow, actionCollection()); } @@ -107,28 +121,21 @@ void CCommentaryReadWindow::storeProfileSettings( CProfileWindow* profileWindow } void CCommentaryReadWindow::initToolbars() { - namespace DU = util::directory; - CLexiconReadWindow::initToolbars(); - - m_syncButton = new QAction( - QIcon(DU::getIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon)), - tr("Synchronize"), - actionCollection() - ); - m_syncButton->setCheckable(true); - m_syncButton->setShortcut(CResMgr::displaywindows::commentaryWindow::syncWindow::accel); - m_syncButton->setToolTip(tr("Synchronize the displayed entry of this work with the active Bible window")); - actionCollection()->addAction(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName, m_syncButton); buttonsToolBar()->addAction(m_syncButton); } +void CCommentaryReadWindow::setupMainWindowToolBars() { + CLexiconReadWindow::setupMainWindowToolBars(); + btMainWindow()->toolsToolBar()->addAction(m_syncButton); +} + /** Reimplementation to handle the keychooser refresh. */ void CCommentaryReadWindow::reload(CSwordBackend::SetupChangedReason reason) { CLexiconReadWindow::reload(reason); //refresh the book lists - verseKey()->setLocale( backend()->booknameLanguage().toLatin1() ); + verseKey()->setLocale( CSwordBackend::instance()->booknameLanguage().toLatin1() ); keyChooser()->refreshContent(); CBTConfig::setupAccelSettings(CBTConfig::commentaryWindow, actionCollection()); diff --git a/src/frontend/displaywindow/ccommentaryreadwindow.h b/src/frontend/displaywindow/ccommentaryreadwindow.h index d75da67..679906c 100644 --- a/src/frontend/displaywindow/ccommentaryreadwindow.h +++ b/src/frontend/displaywindow/ccommentaryreadwindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -54,6 +54,8 @@ class CCommentaryReadWindow : public CLexiconReadWindow { protected: virtual void initActions(); virtual void initToolbars(); + /** Called to add actions to mainWindow toolbars */ + virtual void setupMainWindowToolBars(); private: QAction* m_syncButton; diff --git a/src/frontend/displaywindow/cdisplaywindow.cpp b/src/frontend/displaywindow/cdisplaywindow.cpp index 3900a92..2b712c7 100644 --- a/src/frontend/displaywindow/cdisplaywindow.cpp +++ b/src/frontend/displaywindow/cdisplaywindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -35,30 +35,34 @@ using namespace Profile; CDisplayWindow::CDisplayWindow(QList modules, CMDIArea *parent) : QMainWindow(parent), + m_actionCollection(0), m_mdi(parent), - m_displaySettingsButton(0), m_keyChooser(0), m_swordKey(0), m_isReady(false), m_moduleChooserBar(0), m_mainToolBar(0), + m_buttonsToolBar(0), + m_formatToolBar(0), + m_headerBar(0), m_popupMenu(0), - m_displayWidget(0) { + m_displayWidget(0), + m_history(0) { qDebug() << "CDisplayWindow::CDisplayWindow"; setAttribute(Qt::WA_DeleteOnClose); //we want to destroy this window when it is closed - parent->addSubWindow(this); m_actionCollection = new BtActionCollection(this); setModules(modules); // Connect this to the backend module list changes - connect(CPointers::backend(), + connect(CSwordBackend::instance(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), SLOT(reload(CSwordBackend::SetupChangedReason))); - BibleTime* mainwindow = dynamic_cast(m_mdi->parent()); + BibleTime* mainwindow = btMainWindow(); connect(mainwindow, SIGNAL(toggledTextWindowHeader(bool)), SLOT(slotShowHeader(bool)) ); connect(mainwindow, SIGNAL(toggledTextWindowNavigator(bool)), SLOT(slotShowNavigator(bool)) ); connect(mainwindow, SIGNAL(toggledTextWindowToolButtons(bool)), SLOT(slotShowToolButtons(bool)) ); connect(mainwindow, SIGNAL(toggledTextWindowModuleChooser(bool)), SLOT(slotShowModuleChooser(bool)) ); + connect(mainwindow, SIGNAL(toggledTextWindowFormatToolbar(bool)), SLOT(slotShowFormatToolBar(bool)) ); } CDisplayWindow::~CDisplayWindow() { @@ -66,6 +70,33 @@ CDisplayWindow::~CDisplayWindow() { m_swordKey = 0; } +BibleTime* CDisplayWindow::btMainWindow() { + return dynamic_cast(m_mdi->parent()); +} + +void CDisplayWindow::setToolBarsHidden() { + // Hide current window toolbars + if (mainToolBar()) + mainToolBar()->setHidden(true); + if (buttonsToolBar()) + buttonsToolBar()->setHidden(true); + if (moduleChooserBar()) + moduleChooserBar()->setHidden(true); + if (formatToolBar()) + formatToolBar()->setHidden(true); +} +void CDisplayWindow::clearMainWindowToolBars() { + // Clear main window toolbars, except for works toolbar + btMainWindow()->navToolBar()->clear(); + btMainWindow()->toolsToolBar()->clear(); + btMainWindow()->formatToolBar()->clear(); +} + +void CDisplayWindow::windowActivated() { + clearMainWindowToolBars(); + setupMainWindowToolBars(); +} + /** Returns the right window caption. */ const QString CDisplayWindow::windowCaption() { if (!m_modules.count()) { @@ -76,10 +107,10 @@ const QString CDisplayWindow::windowCaption() { } /** Returns the used modules as a pointer list */ -QList CDisplayWindow::modules() { +const QList CDisplayWindow::modules() const { //qDebug() << "CDisplayWindow::modules"; - return CPointers::backend()->getPointerList(m_modules); + return CSwordBackend::instance()->getConstPointerList(m_modules); } void CDisplayWindow::insertKeyboardActions( BtActionCollection* a ) { @@ -188,7 +219,7 @@ void CDisplayWindow::reload(CSwordBackend::SetupChangedReason) { //first make sure all used Sword modules are still present QMutableStringListIterator it(m_modules); while (it.hasNext()) { - if (!backend()->findModuleByName(it.next())) { + if (!CSwordBackend::instance()->findModuleByName(it.next())) { it.remove(); } } @@ -234,13 +265,15 @@ void CDisplayWindow::slotRemoveModule(int index) { } /** Sets the new display options for this window. */ -void CDisplayWindow::setDisplayOptions(const CSwordBackend::DisplayOptions &displayOptions) { +void CDisplayWindow::setDisplayOptions(const DisplayOptions &displayOptions) { m_displayOptions = displayOptions; + emit sigDisplayOptionsChanged(m_displayOptions); } /** Sets the new filter options of this window. */ -void CDisplayWindow::setFilterOptions(const CSwordBackend::FilterOptions &filterOptions) { +void CDisplayWindow::setFilterOptions(const FilterOptions &filterOptions) { m_filterOptions = filterOptions; + emit sigFilterOptionsChanged(m_filterOptions); } /** Set the ready status */ @@ -264,6 +297,12 @@ void CDisplayWindow::setKey( CSwordKey* key ) { m_swordKey = key; } +BTHistory* CDisplayWindow::history() { + if (m_history == 0) + m_history = new BTHistory(this); + return m_history; +} + void CDisplayWindow::modulesChanged() { // this would only set the stringlist again //if (moduleChooserBar()) { //necessary for write windows @@ -273,11 +312,8 @@ void CDisplayWindow::modulesChanged() { close(); } else { - if (displaySettingsButton()) { - displaySettingsButton()->setModules(modules()); - } - - key()->module(modules().first()); + emit sigModulesChanged(modules()); + key()->setModule(modules().first()); keyChooser()->setModules(modules()); } } @@ -298,7 +334,7 @@ void CDisplayWindow::setModuleChooserBar( BtModuleChooserBar* bar ) { } } -/** Sets the module header of text area. */ +/** Setup the module header of text area. */ void CDisplayWindow::setHeaderBar( QToolBar* header ) { m_headerBar = header; header->setMovable(false); @@ -328,73 +364,92 @@ bool CDisplayWindow::init() { parentWidget()->setFocusPolicy(Qt::ClickFocus); initActions(); initToolbars(); + if ( ! CBTConfig::get(CBTConfig::showToolbarsInEachWindow)) + setToolBarsHidden(); + btMainWindow()->clearMdiToolBars(); + clearMainWindowToolBars(); initConnections(); setupPopupMenu(); m_filterOptions = CBTConfig::getFilterOptionDefaults(); m_displayOptions = CBTConfig::getDisplayOptionDefaults(); - if (displaySettingsButton()) { - displaySettingsButton()->setFilterOptions(m_filterOptions, false); - displaySettingsButton()->setDisplayOptions(m_displayOptions, false); - displaySettingsButton()->setModules(modules()); - } + emit sigDisplayOptionsChanged(m_displayOptions); + emit sigFilterOptionsChanged(m_filterOptions); + emit sigModulesChanged(modules()); setReady(true); return true; } -/** Sets the main toolbar. */ -void CDisplayWindow::setMainToolBar( QToolBar* bar ) { - m_mainToolBar = bar; +static void prepareToolBar(QToolBar* bar, const QString& title, bool visible) { bar->setAllowedAreas(Qt::TopToolBarArea); bar->setFloatable(false); - bar->setWindowTitle(tr("Navigation")); - bar->setVisible(CBTConfig::get(CBTConfig::showTextWindowNavigator)); + bar->setWindowTitle(title); + bar->setVisible(visible); } -/** Sets the main toolbar. */ +/** Setup the Navigation toolbar. */ +void CDisplayWindow::setMainToolBar( QToolBar* bar ) { + prepareToolBar(bar, tr("Navigation"), CBTConfig::get(CBTConfig::showTextWindowNavigator) ); + m_mainToolBar = bar; +} + +/** Setup the Tools toolbar. */ void CDisplayWindow::setButtonsToolBar( QToolBar* bar ) { + prepareToolBar(bar, tr("Tool"), CBTConfig::get(CBTConfig::showTextWindowToolButtons) ); m_buttonsToolBar = bar; - bar->setAllowedAreas(Qt::TopToolBarArea); - bar->setFloatable(false); - bar->setWindowTitle(tr("Tools")); - bar->setVisible( CBTConfig::get(CBTConfig::showTextWindowToolButtons) ); } -/** Sets the display settings button. */ -void CDisplayWindow::setDisplaySettingsButton( BtDisplaySettingsButton* button ) { - if (m_displaySettingsButton) { - m_displaySettingsButton->disconnect(this); - } +/** Setup the Format toolbar. */ +void CDisplayWindow::setFormatToolBar( QToolBar* bar ) { + prepareToolBar(bar, tr("Format"), true ); + m_formatToolBar = bar; +} - m_displaySettingsButton = button; +/** Sets the display settings button. */ +void CDisplayWindow::setDisplaySettingsButton(BtDisplaySettingsButton *button) { + connect(this, SIGNAL(sigDisplayOptionsChanged(const DisplayOptions&)), + button, SLOT(setDisplayOptions(const DisplayOptions&))); + connect(this, SIGNAL(sigFilterOptionsChanged(const FilterOptions&)), + button, SLOT(setFilterOptions(const FilterOptions&))); + connect(this, SIGNAL(sigModulesChanged(const QList&)), + button, SLOT(setModules(const QList&))); button->setDisplayOptions(displayOptions(), false); button->setFilterOptions(filterOptions(), false); button->setModules(modules()); - connect(button, SIGNAL(sigFilterOptionsChanged(CSwordBackend::FilterOptions)), - this, SLOT(setFilterOptions(CSwordBackend::FilterOptions))); - connect(button, SIGNAL(sigDisplayOptionsChanged(CSwordBackend::DisplayOptions)), - this, SLOT(setDisplayOptions(CSwordBackend::DisplayOptions))); + connect(button, SIGNAL(sigFilterOptionsChanged(const FilterOptions&)), + this, SLOT(setFilterOptions(const FilterOptions&))); + connect(button, SIGNAL(sigDisplayOptionsChanged(const DisplayOptions&)), + this, SLOT(setDisplayOptions(const DisplayOptions&))); connect(button, SIGNAL(sigChanged()), this, SLOT(lookup())); } void CDisplayWindow::slotShowHeader(bool show) { - headerBar()->setVisible(show); + if (headerBar()) + headerBar()->setVisible(show); } void CDisplayWindow::slotShowNavigator(bool show) { - mainToolBar()->setVisible(show); + if (mainToolBar()) + mainToolBar()->setVisible(show); } void CDisplayWindow::slotShowToolButtons(bool show) { - buttonsToolBar()->setVisible(show); + if (buttonsToolBar()) + buttonsToolBar()->setVisible(show); } void CDisplayWindow::slotShowModuleChooser(bool show) { - moduleChooserBar()->setVisible(show); + if (moduleChooserBar()) + moduleChooserBar()->setVisible(show); +} + +void CDisplayWindow::slotShowFormatToolBar(bool show) { + if (formatToolBar()) + formatToolBar()->setVisible(show); } /** Lookup the current key. Used to refresh the display. */ @@ -407,25 +462,25 @@ void CDisplayWindow::lookupModKey( const QString& moduleName, const QString& key return; } - CSwordModuleInfo* m = backend()->findModuleByName(moduleName); - Q_ASSERT(m); + CSwordModuleInfo *m = CSwordBackend::instance()->findModuleByName(moduleName); if (!m) { - return; + return; /// \todo check if this is correct behavior } /// \todo check for containsRef compat if (m && modules().contains(m)) { - key()->key(keyName); + key()->setKey(keyName); keyChooser()->setKey(key()); //the key chooser does send an update signal + emit sigKeyChanged(key()); } - else { //given module not displayed in this window + else { //given module not displayed in this window //if the module is displayed in another display window we assume a wrong drop //create a new window for the given module QList mList; mList.append(m); - Q_ASSERT(qobject_cast(mdi()->parent()) != 0); - BibleTime *mainWindow(static_cast(mdi()->parent())); + BibleTime *mainWindow = btMainWindow(); + Q_ASSERT(mainWindow != 0); mainWindow->createReadDisplayWindow(mList, keyName); } } diff --git a/src/frontend/displaywindow/cdisplaywindow.h b/src/frontend/displaywindow/cdisplaywindow.h index b23d856..c54aab0 100644 --- a/src/frontend/displaywindow/cdisplaywindow.h +++ b/src/frontend/displaywindow/cdisplaywindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,10 +11,10 @@ #define CDISPLAYWINDOW_H #include -#include "util/cpointers.h" #include #include "backend/managers/cswordbackend.h" +#include "btglobal.h" #include "frontend/profile/cprofilewindow.h" @@ -23,29 +23,30 @@ class CDisplay; class BtDisplaySettingsButton; class CKeyChooser; class CMDIArea; -//class CModuleChooserBar; class BtModuleChooserBar; -class CReadWindow; class CSwordModuleInfo; -class CWriteWindow; class QCloseEvent; class QMenu; class QToolBar; - -/** The base class for all display windows of BibleTime. +class BTHistory; +class BibleTime; + +/** The base class for all display windows of BibleTime. + * + * Inherits QMainWindow. + * + * Inherited by CReadWindow and CWriteWindow. + * * @author The BibleTime team */ -class CDisplayWindow : public QMainWindow, public CPointers { +class CDisplayWindow : public QMainWindow { Q_OBJECT public: - enum WriteWindowType { - HTMLWindow = 1, - PlainTextWindow = 2 - }; /** Insert the keyboard accelerators of this window into the given actioncollection.*/ static void insertKeyboardActions( BtActionCollection* const a ); + /** Returns pointer to the mdi area object.*/ inline CMDIArea *mdi() const { return m_mdi; } @@ -54,7 +55,7 @@ class CDisplayWindow : public QMainWindow, public CPointers { const QString windowCaption(); /** Returns the used modules as a pointer list.*/ - QList modules(); + const QList modules() const; /** Returns the used modules as a string list. */ inline const QStringList &getModuleList() const { @@ -64,16 +65,16 @@ class CDisplayWindow : public QMainWindow, public CPointers { /** Store the settings of this window in the given CProfileWindow object.*/ virtual void storeProfileSettings( Profile::CProfileWindow* profileWindow ) = 0; - /** Store the settings of this window in the given profile window.*/ + /** Load the settings the given CProfileWindow object into this window.*/ virtual void applyProfileSettings( Profile::CProfileWindow* profileWindow ) = 0; /** Returns the display options used by this display window. */ - inline const CSwordBackend::DisplayOptions &displayOptions() const { + inline const DisplayOptions &displayOptions() const { return m_displayOptions; } /** Returns the filter options used by this window. */ - inline const CSwordBackend::FilterOptions &filterOptions() const { + inline const FilterOptions &filterOptions() const { return m_filterOptions; } @@ -88,6 +89,9 @@ class CDisplayWindow : public QMainWindow, public CPointers { /** Returns true if the window may be closed.*/ virtual bool queryClose(); + /** Returns history for this window */ + BTHistory* history(); + /** Returns the keychooser widget of this display window. */ inline CKeyChooser *keyChooser() const { return m_keyChooser; @@ -114,6 +118,9 @@ class CDisplayWindow : public QMainWindow, public CPointers { /** Sets and inits the properties of the tool buttons toolbar.*/ void setButtonsToolBar( QToolBar* bar ); + /** Sets and inits the properties of the format toolbar.*/ + void setFormatToolBar( QToolBar* bar ); + /** Returns the main navigation toolbar. */ inline QToolBar *mainToolBar() const { return m_mainToolBar; @@ -124,14 +131,14 @@ class CDisplayWindow : public QMainWindow, public CPointers { return m_buttonsToolBar; } + /** Returns the format toolbar. */ + inline QToolBar *formatToolBar() const { + return m_formatToolBar; + } + /** Initialize the toolbars.*/ virtual void initToolbars() = 0; - /** Returns the display settings button. */ - inline BtDisplaySettingsButton *displaySettingsButton() const { - return m_displaySettingsButton; - } - /** Sets the display settings button.*/ void setDisplaySettingsButton( BtDisplaySettingsButton* button ); @@ -154,6 +161,15 @@ class CDisplayWindow : public QMainWindow, public CPointers { return false; }; + /** + * Return pointer to the BibleTime main window + */ + BibleTime* btMainWindow(); + /** + * Called when this window is activated + */ + void windowActivated(); + inline BtActionCollection *actionCollection() const { return m_actionCollection; } @@ -167,6 +183,23 @@ class CDisplayWindow : public QMainWindow, public CPointers { void sigModuleRemoved(int index); /** The module list of window changed but backend list didn't.*/ void sigModuleListChanged(); + + /** + Signal emitted when display options are changed. + */ + void sigDisplayOptionsChanged(const DisplayOptions &displayOptions); + + /** + Signal emitted when display options are changed. + */ + void sigFilterOptionsChanged(const FilterOptions &filterOptions); + + /** signal for change of modules */ + void sigModulesChanged(const QList &modules); + + /** signal for sword key change */ + void sigKeyChanged(CSwordKey* key); + public slots: /** Receives a signal telling that a module should be added.*/ void slotAddModule(int index, QString module); @@ -188,6 +221,7 @@ class CDisplayWindow : public QMainWindow, public CPointers { void slotShowNavigator(bool show); void slotShowToolButtons(bool show); void slotShowModuleChooser(bool show); + void slotShowFormatToolBar(bool show); void slotShowHeader(bool show); protected: @@ -197,13 +231,17 @@ class CDisplayWindow : public QMainWindow, public CPointers { CDisplayWindow(QList modules, CMDIArea* parent); virtual ~CDisplayWindow(); - /** Returns the display options used by this display window. */ - inline CSwordBackend::DisplayOptions &displayOptions() { + /** + \returns the display options used by this display window. + */ + inline DisplayOptions &displayOptions() { return m_displayOptions; } - /** Returns the filter options used by this window. */ - inline CSwordBackend::FilterOptions &filterOptions() { + /** + \returns the filter options used by this window. + */ + inline FilterOptions &filterOptions() { return m_filterOptions; } @@ -242,18 +280,31 @@ class CDisplayWindow : public QMainWindow, public CPointers { /** Returns the installed RMB popup menu.*/ QMenu* popup(); + /** Called to add actions to mainWindow toolbars */ + virtual void setupMainWindowToolBars() = 0; + virtual void closeEvent(QCloseEvent* e); + void setToolBarsHidden(); + void clearMainWindowToolBars(); + protected slots: - /** Sets the new filter options of this window.*/ - void setFilterOptions(const CSwordBackend::FilterOptions &filterOptions); + /** + Sets the new filter options of this window. + */ + void setFilterOptions(const FilterOptions &filterOptions); - /** Sets the new display options for this window.*/ - void setDisplayOptions(const CSwordBackend::DisplayOptions &displayOptions); + /** + Sets the new display options for this window. + */ + void setDisplayOptions(const DisplayOptions &displayOptions); virtual void modulesChanged(); - /** Lookup the current key. Used to refresh the display.*/ + /** + Lookup the current key. Used to refresh the display. This also needs to be called + after programmatically changing filter/display options. + */ void lookup(); virtual void updatePopupMenu(); @@ -270,22 +321,23 @@ class CDisplayWindow : public QMainWindow, public CPointers { BtActionCollection* m_actionCollection; CMDIArea* m_mdi; - //we may only cache the module names bacause after a backend relaod the pointers are invalid! + //we may only cache the module names bacause after a backend reload the pointers are invalid! QStringList m_modules; - CSwordBackend::FilterOptions m_filterOptions; - CSwordBackend::DisplayOptions m_displayOptions; + FilterOptions m_filterOptions; + DisplayOptions m_displayOptions; - BtDisplaySettingsButton* m_displaySettingsButton; CKeyChooser* m_keyChooser; CSwordKey* m_swordKey; bool m_isReady; BtModuleChooserBar* m_moduleChooserBar; QToolBar* m_mainToolBar; QToolBar* m_buttonsToolBar; + QToolBar* m_formatToolBar; QToolBar* m_headerBar; QMenu* m_popupMenu; CDisplay* m_displayWidget; + BTHistory* m_history; }; #endif diff --git a/src/frontend/displaywindow/cdisplaywindowfactory.cpp b/src/frontend/displaywindow/cdisplaywindowfactory.cpp index 05fa963..9e1b5f6 100644 --- a/src/frontend/displaywindow/cdisplaywindowfactory.cpp +++ b/src/frontend/displaywindow/cdisplaywindowfactory.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -25,24 +25,29 @@ CReadWindow* CDisplayWindowFactory::createReadInstance(QList modules, CMDIArea* parent) { qDebug() << "CDisplayWindowFactory::createReadInstance"; + CReadWindow* win = 0; switch (modules.first()->type()) { case CSwordModuleInfo::Bible: - return new CBibleReadWindow(modules, parent); + win = new CBibleReadWindow(modules, parent); + break; case CSwordModuleInfo::Commentary: - return new CCommentaryReadWindow(modules, parent); + win = new CCommentaryReadWindow(modules, parent); + break; case CSwordModuleInfo::Lexicon: - return new CLexiconReadWindow(modules, parent); + win = new CLexiconReadWindow(modules, parent); + break; case CSwordModuleInfo::GenericBook: - return new CBookReadWindow(modules, parent); + win = new CBookReadWindow(modules, parent); + break; default: qWarning("unknown module type"); break; } - return 0; + return win; } -CWriteWindow* CDisplayWindowFactory::createWriteInstance(QList modules, CMDIArea* parent, const CDisplayWindow::WriteWindowType type) { - if (type == CDisplayWindow::HTMLWindow) { +CWriteWindow* CDisplayWindowFactory::createWriteInstance(QList modules, CMDIArea* parent, const CWriteWindow::WriteWindowType type) { + if (type == CWriteWindow::HTMLWindow) { return new CHTMLWriteWindow(modules, parent); } else { @@ -50,3 +55,15 @@ CWriteWindow* CDisplayWindowFactory::createWriteInstance(QList(widget) != 0 ) + return CSwordModuleInfo::Bible; + if (qobject_cast(widget) != 0 ) + return CSwordModuleInfo::Commentary; + if (qobject_cast(widget) != 0 ) + return CSwordModuleInfo::GenericBook; + if (qobject_cast(widget) != 0 ) + return CSwordModuleInfo::Lexicon; + return CSwordModuleInfo::Unknown; +} diff --git a/src/frontend/displaywindow/cdisplaywindowfactory.h b/src/frontend/displaywindow/cdisplaywindowfactory.h index b4d856a..06d9aa4 100644 --- a/src/frontend/displaywindow/cdisplaywindowfactory.h +++ b/src/frontend/displaywindow/cdisplaywindowfactory.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,6 +11,7 @@ #define CDISPLAYWINDOWFACTORY_H #include "frontend/displaywindow/cdisplaywindow.h" +#include "frontend/displaywindow/cwritewindow.h" class CMDIArea; @@ -22,7 +23,8 @@ class CWriteWindow; class CDisplayWindowFactory { public: static CReadWindow* createReadInstance(QList modules, CMDIArea* parent); - static CWriteWindow* createWriteInstance(QList modules, CMDIArea* parent, const CDisplayWindow::WriteWindowType type = CDisplayWindow::HTMLWindow); + static CWriteWindow* createWriteInstance(QList modules, CMDIArea* parent, const CWriteWindow::WriteWindowType type = CWriteWindow::HTMLWindow); + static const CSwordModuleInfo::ModuleType getModuleType(QObject* widget); private: CDisplayWindowFactory(); diff --git a/src/frontend/displaywindow/chtmlwritewindow.cpp b/src/frontend/displaywindow/chtmlwritewindow.cpp index 31cb92b..df36080 100644 --- a/src/frontend/displaywindow/chtmlwritewindow.cpp +++ b/src/frontend/displaywindow/chtmlwritewindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,10 +11,12 @@ #include #include +#include "bibletime.h" #include "backend/keys/cswordkey.h" #include "frontend/display/chtmlwritedisplay.h" #include "frontend/display/cwritedisplay.h" #include "frontend/displaywindow/btactioncollection.h" +#include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/profile/cprofilewindow.h" #include "util/directory.h" @@ -35,13 +37,25 @@ void CHTMLWriteWindow::initView() { setDisplayWidget( writeDisplay ); setCentralWidget( displayWidget()->view() ); + // Create Navigation toolbar setMainToolBar( new QToolBar(this) ); - mainToolBar()->setAllowedAreas(Qt::TopToolBarArea); - mainToolBar()->setFloatable(false); addToolBar(mainToolBar()); - setKeyChooser( CKeyChooser::createInstance(modules(), key(), mainToolBar()) ); - mainToolBar()->addWidget(keyChooser()); + // Create the Tools toolbar + setButtonsToolBar( new QToolBar(this) ); + addToolBar(buttonsToolBar()); + + // Create the Format toolbar + setFormatToolBar( new QToolBar(this) ); + addToolBar(formatToolBar()); +} + +void CHTMLWriteWindow::initActions() { + insertKeyboardActions(actionCollection()); + CPlainWriteWindow::initActions(); +} + +void CHTMLWriteWindow::insertKeyboardActions( BtActionCollection* const a) { } void CHTMLWriteWindow::initConnections() { @@ -54,76 +68,32 @@ void CHTMLWriteWindow::initConnections() { void CHTMLWriteWindow::initToolbars() { namespace DU = util::directory; - //setup the main toolbar - m_actions.syncWindow = new QAction( - DU::getIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon), - tr("Sync with active Bible"), - actionCollection() - ); - m_actions.syncWindow->setCheckable(true); - m_actions.syncWindow->setShortcut(CResMgr::displaywindows::commentaryWindow::syncWindow::accel); - m_actions.syncWindow->setToolTip(tr("Synchronize (show the same verse) with the active Bible window")); - actionCollection()->addAction(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName, m_actions.syncWindow); - mainToolBar()->addAction(m_actions.syncWindow); - - m_actions.saveText = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::saveText::icon), - tr("Save text"), - actionCollection() - ); - m_actions.saveText->setShortcut(CResMgr::displaywindows::writeWindow::saveText::accel); - m_actions.saveText->setToolTip( tr("Save text") ); - QObject::connect(m_actions.saveText, SIGNAL(triggered()), this, SLOT( saveCurrentText() ) ); - actionCollection()->addAction(CResMgr::displaywindows::writeWindow::saveText::actionName, m_actions.saveText); - mainToolBar()->addAction(m_actions.saveText); - - - m_actions.deleteEntry = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::deleteEntry::icon), - tr("Delete current entry"), - actionCollection() - ); - m_actions.deleteEntry->setShortcut(CResMgr::displaywindows::writeWindow::deleteEntry::accel); - m_actions.deleteEntry->setToolTip( tr("Delete current entry (no undo)") ); - QObject::connect(m_actions.deleteEntry, SIGNAL(triggered()), this, SLOT( deleteEntry() ) ); - actionCollection()->addAction(CResMgr::displaywindows::writeWindow::deleteEntry::actionName, m_actions.deleteEntry); - mainToolBar()->addAction(m_actions.deleteEntry); - - m_actions.restoreText = new QAction( - DU::getIcon(CResMgr::displaywindows::writeWindow::restoreText::icon), - tr("Restore original text"), - actionCollection() - ); - m_actions.restoreText->setShortcut(CResMgr::displaywindows::writeWindow::restoreText::accel); - m_actions.restoreText->setToolTip( tr("Restore original text, new text will be lost") ); - QObject::connect(m_actions.restoreText, SIGNAL(triggered()), this, SLOT( restoreText() ) ); - actionCollection()->addAction(CResMgr::displaywindows::writeWindow::restoreText::actionName, m_actions.restoreText); - mainToolBar()->addAction(m_actions.restoreText); - - //html formatting toolbar - QToolBar* bar = new QToolBar(this); - bar->setAllowedAreas(Qt::TopToolBarArea); - bar->setFloatable(false); - ((CWriteDisplay*)displayWidget())->setupToolbar( bar, actionCollection() ); - addToolBar(bar); + CPlainWriteWindow::initToolbars(); + + //Formatting toolbar + ((CWriteDisplay*)displayWidget())->setupToolbar( formatToolBar(), actionCollection() ); } void CHTMLWriteWindow::storeProfileSettings( CProfileWindow* profileWindow ) { CWriteWindow::storeProfileSettings(profileWindow); - profileWindow->setWindowSettings( m_actions.syncWindow->isChecked() ); + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + profileWindow->setWindowSettings( action->isChecked() ); } void CHTMLWriteWindow::applyProfileSettings( CProfileWindow* profileWindow ) { CWriteWindow::applyProfileSettings(profileWindow); if (profileWindow->windowSettings()) { - m_actions.syncWindow->setChecked(true); + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + action->setChecked(true); } } /** Is called when the current text was changed. */ void CHTMLWriteWindow::textChanged() { - m_actions.saveText->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); - m_actions.restoreText->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); + QAction* action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); + action->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); + action->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); } /** Loads the original text from the module. */ @@ -134,7 +104,8 @@ void CHTMLWriteWindow::restoreText() { } bool CHTMLWriteWindow::syncAllowed() const { - return m_actions.syncWindow->isChecked(); + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + return action->isChecked(); } /** Saves the text for the current key. Directly writes the changed text into the module. */ @@ -148,8 +119,8 @@ void CHTMLWriteWindow::saveCurrentText( const QString& /*key*/ ) { const QString& oldKey = this->key()->key(); if ( modules().first()->isWritable() ) { - modules().first()->write(this->key(), t ); - this->key()->key( oldKey ); + const_cast(modules().first())->write(this->key(), t); + this->key()->setKey(oldKey); ((CWriteDisplay*)displayWidget())->setModified(false); textChanged(); @@ -161,3 +132,9 @@ void CHTMLWriteWindow::saveCurrentText( const QString& /*key*/ ) { .arg( tr("Either the module may not be edited, or you do not have write permission.") ) ); } } + +void CHTMLWriteWindow::setupMainWindowToolBars() { + CPlainWriteWindow::setupMainWindowToolBars(); + //Formatting toolbar + ((CWriteDisplay*)displayWidget())->setupToolbar( btMainWindow()->formatToolBar(), actionCollection() ); +} diff --git a/src/frontend/displaywindow/chtmlwritewindow.h b/src/frontend/displaywindow/chtmlwritewindow.h index 4d140cf..b669f94 100644 --- a/src/frontend/displaywindow/chtmlwritewindow.h +++ b/src/frontend/displaywindow/chtmlwritewindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,7 +15,11 @@ class QAction; -/** The WYSIWYG implementation of the editor. +/** + * The write window class which offers a WYSIWYG text editor for creating a personal commentary. + * + * Inherits CPlainWriteWindow. + * * @author The BibleTime team */ class CHTMLWriteWindow : public CPlainWriteWindow { @@ -28,11 +32,15 @@ class CHTMLWriteWindow : public CPlainWriteWindow { * Store the settings of this window in the given CProfileWindow object. */ virtual void storeProfileSettings( Profile::CProfileWindow* ); + /** * Store the settings of this window in the given profile window. */ virtual void applyProfileSettings( Profile::CProfileWindow* ); + /** + * Returns true if the sync toolbar is enabled. + */ virtual bool syncAllowed() const; protected: @@ -42,9 +50,20 @@ class CHTMLWriteWindow : public CPlainWriteWindow { virtual void initView(); virtual void initConnections(); virtual void initToolbars(); - virtual CDisplayWindow::WriteWindowType writeWindowType() { - return CDisplayWindow::HTMLWindow; + virtual void initActions(); + + /** + * Insert the keyboard accelerators of this window into the given KAccel object. + */ + static void insertKeyboardActions( BtActionCollection* const a ); + + virtual CWriteWindow::WriteWindowType writeWindowType() { + return CWriteWindow::HTMLWindow; } + /** + * Called to add actions to mainWindow toolbars + */ + virtual void setupMainWindowToolBars(); protected slots: /** @@ -59,14 +78,6 @@ class CHTMLWriteWindow : public CPlainWriteWindow { * Saves the text for the current key. Directly writes the changed text into the module. */ virtual void saveCurrentText( const QString& ); - private: - struct { - QAction* saveText; - QAction* restoreText; - QAction* deleteEntry; - QAction* syncWindow; - } - m_actions; }; #endif diff --git a/src/frontend/displaywindow/clexiconreadwindow.cpp b/src/frontend/displaywindow/clexiconreadwindow.cpp index 894c787..dae85e3 100644 --- a/src/frontend/displaywindow/clexiconreadwindow.cpp +++ b/src/frontend/displaywindow/clexiconreadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,6 +16,7 @@ #include #include +#include "bibletime.h" #include "backend/config/cbtconfig.h" #include "backend/keys/cswordldkey.h" #include "backend/keys/cswordkey.h" @@ -154,7 +155,7 @@ void CLexiconReadWindow::initConnections() { Q_ASSERT(keyChooser()); connect(keyChooser(), SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); - connect(keyChooser()->history(), SIGNAL(historyChanged(bool, bool)), this, SLOT(slotUpdateHistoryButtons(bool, bool))); + connect(history(), SIGNAL(historyChanged(bool, bool)), this, SLOT(slotUpdateHistoryButtons(bool, bool))); //connect the history actions to the right slots bool ok = connect( @@ -182,42 +183,81 @@ void CLexiconReadWindow::initConnections() { void CLexiconReadWindow::initView() { qDebug() << "CLexiconReadWindow::initView"; + + // Create display widget for this window setDisplayWidget( CDisplay::createReadInstance(this) ); + setCentralWidget( displayWidget()->view() ); + setWindowIcon(util::tool::getIconForModule(modules().first())); + + // Create the Navigation toolbar setMainToolBar( new QToolBar(this) ); addToolBar(mainToolBar()); - setKeyChooser( CKeyChooser::createInstance(modules(), key(), mainToolBar()) ); - mainToolBar()->addWidget(keyChooser()); - setModuleChooserBar( new BtModuleChooserBar(getModuleList(), modules().first()->type(), this) ); + + // Create keychooser + setKeyChooser( CKeyChooser::createInstance(modules(), history(), key(), mainToolBar()) ); + + // Create the Works toolbar + setModuleChooserBar( new BtModuleChooserBar(this)); + moduleChooserBar()->setModules(getModuleList(), modules().first()->type(), this); addToolBar(moduleChooserBar()); + + // Create the Tools toolbar setButtonsToolBar( new QToolBar(this) ); addToolBar(buttonsToolBar()); + + // Create the Text Header toolbar addToolBarBreak(); setHeaderBar(new QToolBar(this)); addToolBar(headerBar()); - BtTextWindowHeader* h = new BtTextWindowHeader(this, modules().first()->type(), getModuleList()); - headerBar()->addWidget(h); - setWindowIcon(util::tool::getIconForModule(modules().first())); - setCentralWidget( displayWidget()->view() ); } void CLexiconReadWindow::initToolbars() { - //main toolbar + //Navigation toolbar Q_ASSERT(m_actions.backInHistory); + mainToolBar()->addWidget(keyChooser()); mainToolBar()->addAction(m_actions.backInHistory); //1st button mainToolBar()->addAction(m_actions.forwardInHistory); //2nd button - //buttons toolbar + //Tools toolbar QAction* action = qobject_cast(actionCollection()->action( CResMgr::displaywindows::general::search::actionName)); Q_ASSERT( action ); if (action) { buttonsToolBar()->addAction(action); } + BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); + setDisplaySettingsButton(button); + buttonsToolBar()->addWidget(button); - setDisplaySettingsButton(new BtDisplaySettingsButton(buttonsToolBar())); + // Text Header toolbar + BtTextWindowHeader *h = new BtTextWindowHeader(modules().first()->type(), getModuleList(), this); + headerBar()->addWidget(h); +} - /// \todo find the right place for the button - buttonsToolBar()->addWidget(displaySettingsButton()); +void CLexiconReadWindow::setupMainWindowToolBars() { + // Navigation toolbar + CKeyChooser* keyChooser = CKeyChooser::createInstance(modules(), history(), key(), btMainWindow()->navToolBar() ); + btMainWindow()->navToolBar()->addWidget(keyChooser); + bool ok = connect(keyChooser, SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); + Q_ASSERT(ok); + ok = connect(this, SIGNAL(sigKeyChanged(CSwordKey*)), keyChooser, SLOT(updateKey(CSwordKey*)) ); + Q_ASSERT(ok); + btMainWindow()->navToolBar()->addAction(m_actions.backInHistory); //1st button + btMainWindow()->navToolBar()->addAction(m_actions.forwardInHistory); //2nd button + + // Works toolbar + btMainWindow()->worksToolBar()->setModules(getModuleList(), modules().first()->type(), this); + + // Tools toolbar + QAction* action = actionCollection()->action( + CResMgr::displaywindows::general::search::actionName); + Q_ASSERT( action ); + if (action) { + btMainWindow()->toolsToolBar()->addAction(action); + } + BtDisplaySettingsButton* button = new BtDisplaySettingsButton(buttonsToolBar()); + setDisplaySettingsButton(button); + btMainWindow()->toolsToolBar()->addWidget(button); } void CLexiconReadWindow::setupPopupMenu() { diff --git a/src/frontend/displaywindow/clexiconreadwindow.h b/src/frontend/displaywindow/clexiconreadwindow.h index 2a32cec..36b47db 100644 --- a/src/frontend/displaywindow/clexiconreadwindow.h +++ b/src/frontend/displaywindow/clexiconreadwindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,26 +22,21 @@ class CSwordKey; class QAction; class QMenu; -/** - *@author The BibleTime team +/** The class used to display lexicons. It is also used as the class that other display window types are derived from. + * + * Inherits CReadWindow. + * + * Inherited by CBibleReadWindow, CBookReadWindow, and CCommentaryReadWindow. + * + * @author The BibleTime team */ class CLexiconReadWindow : public CReadWindow { Q_OBJECT public: CLexiconReadWindow(QList modules, CMDIArea* parent); virtual ~CLexiconReadWindow(); - /** - * Store the settings of this window in the given CProfileWindow object. - */ - // virtual void storeProfileSettings( CProfileWindow* profileWindow ); - /** - * Store the settings of this window in the given profile window. - */ - // virtual void applyProfileSettings( CProfileWindow* profileWindow ); - /** - * Reimplementation. - */ - // static void insertKeyboardActions( KAccel* a ); + + /** Insert the keyboard accelerators of this window into the given actioncollection.*/ static void insertKeyboardActions( BtActionCollection* const a ); public slots: @@ -58,6 +53,8 @@ class CLexiconReadWindow : public CReadWindow { virtual void updatePopupMenu(); virtual void setupPopupMenu(); + /** Called to add actions to mainWindow toolbars */ + virtual void setupMainWindowToolBars(); struct ActionsStruct { BtToolBarPopupAction* backInHistory; diff --git a/src/frontend/displaywindow/cplainwritewindow.cpp b/src/frontend/displaywindow/cplainwritewindow.cpp index 6394998..ad3b978 100644 --- a/src/frontend/displaywindow/cplainwritewindow.cpp +++ b/src/frontend/displaywindow/cplainwritewindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,10 +13,12 @@ #include #include #include +#include "bibletime.h" #include "backend/config/cbtconfig.h" #include "backend/keys/cswordkey.h" #include "frontend/display/cwritedisplay.h" #include "frontend/displaywindow/btactioncollection.h" +#include "frontend/displaywindow/btmodulechooserbar.h" #include "frontend/keychooser/ckeychooser.h" #include "frontend/profile/cprofilewindow.h" #include "util/cresmgr.h" @@ -40,69 +42,52 @@ void CPlainWriteWindow::initView() { setDisplayWidget( CDisplay::createWriteInstance(this) ); setCentralWidget( displayWidget()->view() ); + // Create Navigation toolbar setMainToolBar( new QToolBar(this) ); - mainToolBar()->setAllowedAreas(Qt::TopToolBarArea); - mainToolBar()->setFloatable(false); addToolBar(mainToolBar()); - addToolBarBreak(); - setKeyChooser( CKeyChooser::createInstance(modules(), key(), mainToolBar()) ); - mainToolBar()->addWidget(keyChooser()); + // Create the Tools toolbar + setButtonsToolBar( new QToolBar(this) ); + addToolBar(buttonsToolBar()); } void CPlainWriteWindow::initToolbars() { namespace DU = util::directory; - m_actions.syncWindow = new QAction( - //KIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon), - DU::getIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon), - tr("Sync with active Bible"), - actionCollection() - ); - m_actions.syncWindow->setCheckable(true); - m_actions.syncWindow->setShortcut(CResMgr::displaywindows::commentaryWindow::syncWindow::accel); - m_actions.syncWindow->setToolTip(tr("Synchronize (show the same verse) with the active Bible window")); - mainToolBar()->addAction(m_actions.syncWindow); - actionCollection()->addAction(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName, m_actions.syncWindow); - - - m_actions.saveText = new QAction( - //KIcon(CResMgr::displaywindows::writeWindow::saveText::icon), - DU::getIcon(CResMgr::displaywindows::writeWindow::saveText::icon), - tr("Save text"), - actionCollection() - ); - m_actions.saveText->setShortcut(CResMgr::displaywindows::writeWindow::saveText::accel); - QObject::connect(m_actions.saveText, SIGNAL(triggered()), this, SLOT(saveCurrentText())); - m_actions.saveText->setToolTip( tr("Save text") ); - actionCollection()->addAction(CResMgr::displaywindows::writeWindow::saveText::actionName, m_actions.saveText); - mainToolBar()->addAction(m_actions.saveText); - - - m_actions.deleteEntry = new QAction( - //KIcon(CResMgr::displaywindows::writeWindow::deleteEntry::icon), - DU::getIcon(CResMgr::displaywindows::writeWindow::deleteEntry::icon), - tr("Delete current entry"), - actionCollection() - ); - m_actions.deleteEntry->setShortcut(CResMgr::displaywindows::writeWindow::deleteEntry::accel); - QObject::connect(m_actions.deleteEntry, SIGNAL(triggered()), this, SLOT(deleteEntry()) ); - m_actions.deleteEntry->setToolTip( tr("Delete current entry (no undo)") ); - actionCollection()->addAction(CResMgr::displaywindows::writeWindow::deleteEntry::actionName, m_actions.deleteEntry); - mainToolBar()->addAction(m_actions.deleteEntry); + // Navigation toolbar + setKeyChooser( CKeyChooser::createInstance(modules(), + history(), key(), mainToolBar()) ); + mainToolBar()->addWidget(keyChooser()); + // Tools toolbar + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + buttonsToolBar()->addAction(action); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); + buttonsToolBar()->addAction(action); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::deleteEntry::actionName); + buttonsToolBar()->addAction(action); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); + buttonsToolBar()->addAction(action); +} - m_actions.restoreText = new QAction( - //KIcon(CResMgr::displaywindows::writeWindow::restoreText::icon), - DU::getIcon(CResMgr::displaywindows::writeWindow::restoreText::icon), - tr("Restore original text"), - actionCollection() - ); - m_actions.restoreText->setShortcut(CResMgr::displaywindows::writeWindow::restoreText::accel); - QObject::connect(m_actions.restoreText, SIGNAL(triggered()), this, SLOT(restoreText()) ); - m_actions.restoreText->setToolTip( tr("Restore original text, new text will be lost") ); - actionCollection()->addAction(CResMgr::displaywindows::writeWindow::restoreText::actionName, m_actions.restoreText); - mainToolBar()->addAction(m_actions.restoreText); +void CPlainWriteWindow::setupMainWindowToolBars() { + // Navigation toolbar + CKeyChooser* keyChooser = CKeyChooser::createInstance(modules(), history(), key(), btMainWindow()->navToolBar() ); + btMainWindow()->navToolBar()->addWidget(keyChooser); + bool ok = connect(keyChooser, SIGNAL(keyChanged(CSwordKey*)), this, SLOT(lookupSwordKey(CSwordKey*))); + Q_ASSERT(ok); + ok = connect(keyChooser, SIGNAL(beforeKeyChange(const QString&)), this, SLOT(beforeKeyChange(const QString&))); + Q_ASSERT(ok); + + // Tools toolbar + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + btMainWindow()->toolsToolBar()->addAction(action); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); + btMainWindow()->toolsToolBar()->addAction(action); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::deleteEntry::actionName); + btMainWindow()->toolsToolBar()->addAction(action); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); + btMainWindow()->toolsToolBar()->addAction(action); } void CPlainWriteWindow::initConnections() { @@ -113,13 +98,15 @@ void CPlainWriteWindow::initConnections() { void CPlainWriteWindow::storeProfileSettings( CProfileWindow* profileWindow ) { CWriteWindow::storeProfileSettings(profileWindow); - profileWindow->setWindowSettings( m_actions.syncWindow->isChecked() ); + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + profileWindow->setWindowSettings( action->isChecked() ); } void CPlainWriteWindow::applyProfileSettings( CProfileWindow* profileWindow ) { CWriteWindow::applyProfileSettings(profileWindow); if (profileWindow->windowSettings()) { - m_actions.syncWindow->setChecked(true); + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + action->setChecked(true); } } @@ -134,8 +121,8 @@ void CPlainWriteWindow::saveCurrentText( const QString& /*key*/ ) { const QString& oldKey = this->key()->key(); if ( modules().first()->isWritable() ) { - modules().first()->write(this->key(), t ); - this->key()->key( oldKey ); + const_cast(modules().first())->write(this->key(), t); + this->key()->setKey(oldKey); ((CWriteDisplay*)displayWidget())->setModified(false); textChanged(); @@ -158,13 +145,15 @@ void CPlainWriteWindow::restoreText() { /** Is called when the current text was changed. */ void CPlainWriteWindow::textChanged() { - m_actions.saveText->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); - m_actions.restoreText->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); + QAction* action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); + action->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); + action->setEnabled( ((CWriteDisplay*)displayWidget())->isModified() ); } /** Deletes the module entry and clears the edit widget, */ void CPlainWriteWindow::deleteEntry() { - modules().first()->deleteEntry( key() ); + const_cast(modules().first())->deleteEntry(key()); lookupSwordKey( key() ); ((CWriteDisplay*)displayWidget())->setModified(false); } @@ -173,11 +162,68 @@ void CPlainWriteWindow::deleteEntry() { void CPlainWriteWindow::setupPopupMenu() {} bool CPlainWriteWindow::syncAllowed() const { - return m_actions.syncWindow->isChecked(); + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + return action->isChecked(); } void CPlainWriteWindow::initActions() { + insertKeyboardActions(actionCollection()); + + QAction* action = actionCollection()->action(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName); + bool ok = QObject::connect(action, SIGNAL(triggered()), this, SLOT(saveCurrentText())); + Q_ASSERT(ok); + + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::saveText::actionName); + ok = QObject::connect(action, SIGNAL(triggered()), this, SLOT(saveCurrentText())); + Q_ASSERT(ok); + + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::deleteEntry::actionName); + ok = QObject::connect(action, SIGNAL(triggered()), this, SLOT(deleteEntry()) ); + Q_ASSERT(ok); + + action = actionCollection()->action(CResMgr::displaywindows::writeWindow::restoreText::actionName); + ok = QObject::connect(action, SIGNAL(triggered()), this, SLOT(restoreText()) ); + Q_ASSERT(ok); } -void CPlainWriteWindow::insertKeyboardActions( BtActionCollection* const ) { +void CPlainWriteWindow::insertKeyboardActions( BtActionCollection* const a) { + + namespace DU = util::directory; + + QAction* action = new QAction( + DU::getIcon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon), + tr("Sync with active Bible"), + a + ); + action->setCheckable(true); + action->setShortcut(CResMgr::displaywindows::commentaryWindow::syncWindow::accel); + action->setToolTip(tr("Synchronize (show the same verse) with the active Bible window")); + a->addAction(CResMgr::displaywindows::commentaryWindow::syncWindow::actionName, action); + + action = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::saveText::icon), + tr("Save text"), + a + ); + action->setShortcut(CResMgr::displaywindows::writeWindow::saveText::accel); + action->setToolTip( tr("Save text") ); + a->addAction(CResMgr::displaywindows::writeWindow::saveText::actionName, action); + + action = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::deleteEntry::icon), + tr("Delete current entry"), + a + ); + action->setShortcut(CResMgr::displaywindows::writeWindow::deleteEntry::accel); + action->setToolTip( tr("Delete current entry (no undo)") ); + a->addAction(CResMgr::displaywindows::writeWindow::deleteEntry::actionName, action); + + action = new QAction( + DU::getIcon(CResMgr::displaywindows::writeWindow::restoreText::icon), + tr("Restore original text"), + a + ); + action->setShortcut(CResMgr::displaywindows::writeWindow::restoreText::accel); + action->setToolTip( tr("Restore original text, new text will be lost") ); + a->addAction(CResMgr::displaywindows::writeWindow::restoreText::actionName, action); } diff --git a/src/frontend/displaywindow/cplainwritewindow.h b/src/frontend/displaywindow/cplainwritewindow.h index ec9fe5e..9d3f29c 100644 --- a/src/frontend/displaywindow/cplainwritewindow.h +++ b/src/frontend/displaywindow/cplainwritewindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,7 +17,12 @@ class BtActionCollection; class QAction; class QString; -/** The write window class which offers a plain editor for source code editing. +/** The write window class which offers a plain text editor for creating a personal commentary. + * + * Inherits CWriteWindow. + * + * Inherited by CHTMLWriteWindow. + * * @author The BibleTime team */ class CPlainWriteWindow : public CWriteWindow { @@ -39,6 +44,10 @@ class CPlainWriteWindow : public CWriteWindow { * Setups the popup menu of this display widget. */ virtual void setupPopupMenu(); + + /** + * Returns true if the sync toolbar is enabled. + */ virtual bool syncAllowed() const; protected: // Protected methods @@ -48,10 +57,12 @@ class CPlainWriteWindow : public CWriteWindow { virtual void initView(); virtual void initConnections(); virtual void initToolbars(); - virtual CDisplayWindow::WriteWindowType writeWindowType() { - return CDisplayWindow::PlainTextWindow; + virtual CWriteWindow::WriteWindowType writeWindowType() { + return CWriteWindow::PlainTextWindow; }; + /** Called to add actions to mainWindow toolbars */ + virtual void setupMainWindowToolBars(); /** * Initializes the intern keyboard actions. */ @@ -61,15 +72,6 @@ class CPlainWriteWindow : public CWriteWindow { */ static void insertKeyboardActions( BtActionCollection* const a ); - private: - struct { - QAction* saveText; - QAction* deleteEntry; - QAction* restoreText; - QAction* syncWindow; - } - m_actions; - protected slots: // Protected slots /** * Saves the text for the current key. Directly writes the changed text into the module. diff --git a/src/frontend/displaywindow/creadwindow.cpp b/src/frontend/displaywindow/creadwindow.cpp index 07c0abb..4c18b0b 100644 --- a/src/frontend/displaywindow/creadwindow.cpp +++ b/src/frontend/displaywindow/creadwindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -83,13 +83,13 @@ void CReadWindow::lookupSwordKey( CSwordKey* newKey ) { using namespace Rendering; -// Q_ASSERT(isReady() && newKey && modules().first()); +// Q_ASSERT(isReady() && newKey && modules().first()); if (!isReady() || !newKey || modules().empty() || !modules().first()) { return; } if (key() != newKey) { - key()->key(newKey->key()); + key()->setKey(newKey->key()); } /// \todo next-TODO how about options? @@ -146,11 +146,8 @@ void CReadWindow::storeProfileSettings(CProfileWindow * const settings) { } QStringList mods; - - QList allMods = modules(); - QList::iterator end_it = allMods.end(); - for (QList::iterator it(allMods.begin()); it != end_it; ++it) { - mods.append((*it)->name()); + Q_FOREACH (const CSwordModuleInfo *module, modules()) { + mods.append(module->name()); } settings->setModules(mods); } @@ -191,7 +188,7 @@ void CReadWindow::resizeEvent(QResizeEvent* /*e*/) { } void CReadWindow::openSearchStrongsDialog() { -// qWarning("looking for lemma %s", displayWidget()->getCurrentNodeInfo()[CDisplay::Lemma].latin1() ); +// qWarning("looking for lemma %s", displayWidget()->getCurrentNodeInfo()[CDisplay::Lemma].latin1() ); QString searchText = QString::null; if (displayWidget()->getCurrentNodeInfo()[CDisplay::Lemma] != QString::null) { diff --git a/src/frontend/displaywindow/creadwindow.h b/src/frontend/displaywindow/creadwindow.h index 7a529b8..855baa2 100644 --- a/src/frontend/displaywindow/creadwindow.h +++ b/src/frontend/displaywindow/creadwindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -20,12 +20,18 @@ class BtActionCollection; class QResizeEvent; /** The base class for all read-only display windows. + * + * Inherits CDisplayWindow. + * + * Inherited by CLexiconReadWindow + * * @author The BibleTime team */ class CReadWindow : public CDisplayWindow { Q_OBJECT public: + /** Insert the keyboard accelerators of this window into the given actioncollection.*/ static void insertKeyboardActions( BtActionCollection* const a ); CReadWindow(QList modules, CMDIArea* parent); @@ -35,7 +41,7 @@ class CReadWindow : public CDisplayWindow { */ virtual void storeProfileSettings(Profile::CProfileWindow * const settings); /** - * Store the settings of this window in the given CProfileWindow object. + * Load the settings the given CProfileWindow object into this window. */ virtual void applyProfileSettings(Profile::CProfileWindow * const settings); @@ -45,9 +51,13 @@ class CReadWindow : public CDisplayWindow { */ virtual void setDisplayWidget( CDisplay* newDisplay ); /** + * Reimplemented Qt function for resize of window. */ virtual void resizeEvent(QResizeEvent* e); + /** Called to add actions to mainWindow toolbars.*/ + virtual void setupMainWindowToolBars() = 0; + protected slots: /** * Load the text using the key @@ -62,8 +72,8 @@ class CReadWindow : public CDisplayWindow { * Update the status of the popup menu entries. */ virtual void copyDisplayedText(); - /** Open the search dialog with the strong info of the last clicked word. - * + /** + * Open the search dialog with the strong info of the last clicked word. */ void openSearchStrongsDialog(); diff --git a/src/frontend/displaywindow/cwritewindow.cpp b/src/frontend/displaywindow/cwritewindow.cpp index 7496dd7..3369d8a 100644 --- a/src/frontend/displaywindow/cwritewindow.cpp +++ b/src/frontend/displaywindow/cwritewindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -65,10 +65,8 @@ void CWriteWindow::storeProfileSettings(CProfileWindow * const settings) { } QStringList mods; - QList allMods = modules(); - QList::iterator end_it = allMods.end(); - for (QList::iterator it(allMods.begin()); it != end_it; ++it) { - mods.append((*it)->name()); + Q_FOREACH(const CSwordModuleInfo *m, modules()) { + mods.append(m->name()); } settings->setModules(mods); } @@ -103,7 +101,7 @@ void CWriteWindow::lookupSwordKey( CSwordKey* newKey ) { return; if (key() != newKey) { //set passage of newKey to key() if they're different, otherwise we'd get mixed up if we look up newkey which may have a different module set - key()->key(newKey->key()); + key()->setKey(newKey->key()); } if ( modules().count() ) { diff --git a/src/frontend/displaywindow/cwritewindow.h b/src/frontend/displaywindow/cwritewindow.h index 5d6a316..7a5a524 100644 --- a/src/frontend/displaywindow/cwritewindow.h +++ b/src/frontend/displaywindow/cwritewindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,11 +18,22 @@ class CWriteDisplay; class QString; /** The base class for all write-only display windows. + * + * Inherits CDisplayWindow. + * + * Inherited by CPlainWriteWindow. + * *@author The BibleTime team */ class CWriteWindow : public CDisplayWindow { Q_OBJECT public: + enum WriteWindowType { + HTMLWindow = 1, + PlainTextWindow = 2 + }; + + /** Insert the keyboard accelerators of this window into the given actioncollection.*/ static void insertKeyboardActions( BtActionCollection* const a ); CWriteWindow(QList modules, CMDIArea* parent); @@ -32,10 +43,14 @@ class CWriteWindow : public CDisplayWindow { */ virtual void storeProfileSettings(Profile::CProfileWindow * const settings); /** - * Store the settings of this window in the given CProfileWindow object. + * Load the settings the given CProfileWindow object into this window. */ virtual void applyProfileSettings(Profile::CProfileWindow * const settings); + + /** Initializes the signal / slot connections of this display window.*/ virtual void initConnections(); + + /** Initializes the internel keyboard actions.*/ virtual void initActions(); public slots: @@ -47,14 +62,22 @@ class CWriteWindow : public CDisplayWindow { protected: // Protected methods /** - * Saves the given text as text of the given key. Use this function - * as backend in each write window implementation. + * Set the displayWidget which is a subclass of QWebPage. */ void setDisplayWidget( CDisplay* display ); - virtual CDisplayWindow::WriteWindowType writeWindowType() = 0; + + /** Returns the type of the write window.*/ + virtual CWriteWindow::WriteWindowType writeWindowType() = 0; + + /** Returns true if the window may be closed.*/ virtual bool queryClose(); + + /** Saves the text for the current key. Directly writes the changed text into the module. */ virtual void saveCurrentText( const QString& key ) = 0; + /** Called to add actions to mainWindow toolbars */ + virtual void setupMainWindowToolBars() = 0; + protected slots: /** Save text to the module */ diff --git a/src/frontend/htmldialogs/btaboutdialog.cpp b/src/frontend/htmldialogs/btaboutdialog.cpp deleted file mode 100644 index 528d9d5..0000000 --- a/src/frontend/htmldialogs/btaboutdialog.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/htmldialogs/btaboutdialog.h" - -#include "util/directory.h" - -// Sword includes: -#include - - -// Forwards -static QString make_body(const QString& content); -static QString make_bold(const QString& content); -static QString make_br(); -static QString make_center(const QString& content); -static QString make_head(const QString& content); -static QString make_html(const QString& content); -static QString make_file_icon(const QString& icon); -static QString make_link(const QString& link, const QString& text); - - -// Implements the Help > About dialog box - -BtAboutDialog::BtAboutDialog(QWidget *parent, Qt::WindowFlags wflags ) - : BtTabHtmlDialog (tr("About BibleTime"), 5, parent, wflags) { - resize(550, 340); - init_lic_tab(); - init_sword_tab(); - init_qt_tab(); - init_contributors_tab(); - init_bt_tab(); -} - -BtAboutDialog::~BtAboutDialog() { -} - -void BtAboutDialog::init_bt_tab() { - selectTab(0); - setTabText("BibleTime" ); - QString content; - content = make_file_icon("bibletime"); - content += "  "; - content += make_bold("BibleTime " BT_VERSION); - content = make_center(content) + make_br(); - content += tr("BibleTime is an easy to use but powerful Bible study tool."); - content += make_br() + make_br(); - content += tr("We are looking for developers and translators."); - content += " "; - content += tr("If you would like to join our team, please send an email to info@bibletime.info."); - content += make_br() + make_br(); - content += tr("(c)1999-2009, The BibleTime Team"); - content += make_br(); - content += make_link("http://www.bibletime.info", "http://www.bibletime.info"); - QString bibletime = make_html(make_head("") + make_body(content)); - setHtml(bibletime); -} - -void BtAboutDialog::init_contributors_tab() { - selectTab(1); - setTabText(tr("Contributors")); - QString content; - content += make_bold(tr("The following people contributed to BibleTime:")) + make_br(); - - /**************************************************************************************** - *** NB!!! Credits are sorted alphabetically by last name! *** - ****************************************************************************************/ - content += "
      "; - content += "
    • Thomas Abthorpe (" + tr("documentation and translation manager") + ")
    • "; - content += "
    • Joachim Ansorg (" + tr("project founder, developer") + ")
    • "; - content += "
    • David Blue (" + tr("designer") + ")
    • "; - content += "
    • Tim Brodie (" + tr("developer") + ")
    • "; - content += "
    • Timothy R. Butler (" + tr("designer") + ")
    • "; - content += "
    • Jim Campbell (" + tr("developer") + ")
    • "; - content += "
    • Lee Carpenter (" + tr("developer") + ")
    • "; - content += "
    • Jeremy Erickson (" + tr("packager") + ")
    • "; - content += "
    • Troy A. Griffitts (" + tr("creator of The Sword Project") + ")
    • "; - content += "
    • Martin Gruner (" + tr("project manager, developer") + ")
    • "; - content += "
    • Thomas Hagedorn (" + tr("domain sponsor") + ")
    • "; - content += "
    • Bob Harman (" + tr("howto") + ")
    • "; - content += "
    • Gary Holmlund (" + tr("developer") + ")
    • "; - content += "
    • Nikolay Igotti (" + tr("developer") + ")
    • "; - content += "
    • Eeli Kaikkonnen (" + tr("developer") + ")
    • "; - content += "
    • Chris Kujawa (" + tr("developer") + ")
    • "; - content += "
    • Mark Lybarger (" + tr("developer") + ")
    • "; - content += "
    • Luke Mauldin (" + tr("developer") + ")
    • "; - content += "
    • James Ots (" + tr("designer") + ")
    • "; - /** \todo BibleTime 2.6: Add tr("artist"): */ - content += "
    • Andrus Raag
    • "; - content += "
    • Jaak Ristioja (" + tr("developer") + ")
    • "; - content += "
    • Fred Saalbach (" + tr("documentation") + ")
    • "; - content += "
    • Gary Sims (" + tr("developer") + ")
    • "; - content += "
    • Wolfgang Stradner (" + tr("tester, usability expert") + ")
    • "; - content += "
    • Kang Sun (" + tr("developer") + ")
    • "; - content += "
    • Thorsten Uhlmann (" + tr("developer") + ")
    • "; - content += "
    • David White (" + tr("developer") + ")
    • "; - content += "
    • Mark Zealey (" + tr("developer") + ")
    • "; - content += "
    "; - - content += make_bold(tr("The following people translated BibleTime into their language:")) + make_br(); - - /**************************************************************************************** - *** NB!!! Credits are sorted alphabetically by last name! *** - ****************************************************************************************/ - content += "
      "; - content += "
    • Horatiu Alexe
    • "; - content += "
    • Luis Barron
    • "; - content += "
    • Jan Bělohoubek
    • "; - content += "
    • Chun-shek Chan
    • "; - content += "
    • Nouhoun Y. Diarra
    • "; - content += "
    • Rafael Fagundes
    • "; - content += "
    • Ilpo Kantonen
    • "; - content += "
    • Pavel Laukko
    • "; - content += "
    • Piotr Markiewicz
    • "; - content += "
    • Géza Novák
    • "; - content += "
    • Gabriel Pérez
    • "; - content += "
    • Igor Plisco
    • "; - content += "
    • Zdenko Podobný
    • "; - content += "
    • Jaak Ristioja
    • "; - content += "
    • Igor Rykhlin
    • "; - content += "
    • Vlad Savitsky
    • "; - content += "
    • Henrik Sonesson
    • "; - content += "
    • Johan van der Lingen
    • "; - content += "
    • Jean Van Schaftingen
    • "; - content += "
    • Roland Teschner
    • "; - content += "
    • Giovanni Tedaldi
    • "; - content += "
    • Dmitry Yurevich
    • "; - content += "
    • Esteban Zeller
    • "; - content += "
    "; - content += make_br(); - content += tr("Some names may be missing, please email bibletime-translations@lists.sourceforge.net if you notice errors or omissions."); - - QString contributors = make_html(make_head("") + make_body(content)); - setHtml(contributors); -} - - -void BtAboutDialog::init_sword_tab() { - selectTab(2); - setTabText("Sword" ); - - QString version( sword::SWVersion::currentVersion.getText()); - QString content = make_br() + make_br(); - content += make_center(make_bold(tr("SWORD library version %1").arg(version))); - content += make_br(); - - content += tr("BibleTime makes use of the SWORD Project. The SWORD Project is the CrossWire Bible Society's free Bible software project. Its purpose is to create cross-platform open-source tools-- covered by the GNU General Public License-- that allow programmers and Bible societies to write new Bible software more quickly and easily."); - content += make_br() + make_br(); - content += tr("The SWORD Project") + make_br(); - content += make_link("http://www.crosswire.org/sword/index.jsp", "www.crosswire.org/sword/index.jsp"); - - setHtml(content); - -} - -void BtAboutDialog::init_qt_tab() { - selectTab(3); - setTabText("Qt"); - QString content; - content += make_br() + make_br(); - content += make_center(make_bold("Qt")); - content += make_br(); - content += tr("This program uses Qt version %1.").arg(qVersion()); - content += make_br() + make_br(); - content += tr("Qt is a cross-platform application and UI framework, created with C++ language. It has been released under the LGPL license."); - content += make_br() + make_br(); - content += make_link("http://qt.nokia.com/", "http://qt.nokia.com/"); - //content += tr("Please see "); - //content += make_link("http://qtsoftware.com/company/model/", "qtsoftware.com/company/model"); - //content += tr(" for an overview of Qt licensing."); - QString qt = make_html(make_head("") + make_body(content)); - setHtml(qt); -} - -void BtAboutDialog::init_lic_tab() { - namespace DU = util::directory; - - selectTab(4); - setTabText(tr("License")); - - QByteArray text; - text += tr("BibleTime is released under the GPL license."); - text += " "; - text += tr("You can download and use (but not distribute) the program for personal, private, public or commercial purposes without restrictions."); - text += " "; - text += tr("You can give away or distribute the program if you also distribute the corresponding source code."); - text += "

    "; - //text += tr("It is allowed to distribute software under GPL for a small fee, but it must be accompanied with the complete source code, and the fact that it is freely available with no cost must not be hidden."); - //text += "

    "; - text += tr("The complete legally binding license is below."); - - QFile licFile(DU::getLicenseDir().path() + "/license.html"); - if (licFile.open(QFile::ReadOnly)) { - QByteArray html; - while (!licFile.atEnd()) { - QByteArray line = licFile.readLine(); - html = html + line; - } - licFile.close(); - html.replace("TRANSLATED TEXT", text); - setHtml(QString(html)); - } -} - - - -// Helper functions - -static QString make_center(const QString& content) { - return "
    " + content + "
    "; -} - -static QString make_br() { - return "
    "; -} - -static QString make_bold(const QString& content) { - return "" + content + ""; -} - -static QString make_html(const QString& content) { - return "" + content + ""; -} - -static QString make_head(const QString& content) { - return "" + content + ""; -} - -static QString make_body(const QString& content) { - return "" + content + ""; -} - -static QString make_link(const QString& link, const QString& text) { - return "" + text + ""; -} - -static QString make_file_icon(const QString& icon) { - namespace DU = util::directory; - QUrl url = QUrl::fromLocalFile( DU::getIconDir().path() + "/" + icon + ".svg"); - QString html = ""; - return html; -} - diff --git a/src/frontend/htmldialogs/btaboutdialog.h b/src/frontend/htmldialogs/btaboutdialog.h deleted file mode 100644 index 2fed22a..0000000 --- a/src/frontend/htmldialogs/btaboutdialog.h +++ /dev/null @@ -1,29 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BTABOUTDIALOG_H -#define BTABOUTDIALOG_H - -#include "frontend/htmldialogs/bttabhtmldialog.h" - - -class BtAboutDialog : public BtTabHtmlDialog { - Q_OBJECT - public: - BtAboutDialog(QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); - ~BtAboutDialog(); - - void init_bt_tab(); - void init_contributors_tab(); - void init_sword_tab(); - void init_qt_tab(); - void init_lic_tab(); -}; - -#endif diff --git a/src/frontend/htmldialogs/bttabhtmldialog.cpp b/src/frontend/htmldialogs/bttabhtmldialog.cpp deleted file mode 100644 index bd52464..0000000 --- a/src/frontend/htmldialogs/bttabhtmldialog.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/htmldialogs/bttabhtmldialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include "util/dialogutil.h" -#include "util/directory.h" - - -BtTabHtmlDialog::BtTabHtmlDialog -(const QString& title, int tabs, QWidget *parent, Qt::WindowFlags wflags ) - : QDialog(parent, wflags), m_webView(0), m_tabWidget(0), m_tabs(tabs) { - //Set the flag to destroy when closed - setAttribute(Qt::WA_DeleteOnClose); - setWindowTitle(title); - resize(400, 300); - - QVBoxLayout *vboxLayout = new QVBoxLayout(this); - if (tabs == 0) { - m_webView = new BtWebView(this); - init_connections(m_webView); - vboxLayout->addWidget(m_webView); - m_webView->setHtml("Hi"); - } - else { - m_tabWidget = new QTabWidget(this); - vboxLayout->addWidget(m_tabWidget); - for (int i = 0; i < tabs; i++) { - QWebView* webView = new BtWebView(this); - init_connections(webView); - webView->setObjectName("View" + QString::number(i)); - webView->setHtml(" "); - m_tabWidget->addTab(webView, "Tab" + QString::number(i)); - m_tabWidget->show(); - } - } - - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this); - util::prepareDialogBox(buttonBox); - vboxLayout->addWidget(buttonBox); - - bool ok; - ok = connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - Q_ASSERT(ok); - ok = connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - Q_ASSERT(ok); -} - -BtTabHtmlDialog::~BtTabHtmlDialog() { -} - -void BtTabHtmlDialog::init_connections(QWebView* webView) { - webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); - bool ok = connect(webView, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl))); - Q_ASSERT(ok); -} - -void BtTabHtmlDialog::linkClicked(const QUrl url) { - QDesktopServices::openUrl(url); -} - -void BtTabHtmlDialog::selectTab(int tab) { - Q_ASSERT(tab >= 0 && tab < m_tabWidget->count()); - m_tabWidget->setCurrentIndex(tab); -} - -QWebView* BtTabHtmlDialog::webView() { - QWebView* webview = 0; - if (m_tabs == 0) - webview = m_webView; - else { - QWidget* widget = m_tabWidget->currentWidget(); - QString name = widget->objectName(); - webview = qobject_cast(widget); - } - Q_ASSERT(webview != 0); - return webview; -} - -void BtTabHtmlDialog::setHtml(const QString& html, const QUrl& baseUrl) { - namespace DU = util::directory; - QUrl url = baseUrl; - if (url == QUrl()) { - QUrl url = QUrl::fromLocalFile(DU::getIconDir().path()); - } - webView()->setHtml(html, url); -} - -void BtTabHtmlDialog::setUrl(const QUrl& url) { - webView()->setUrl(url); -} - -void BtTabHtmlDialog::setTabText(const QString& tabName) { - Q_ASSERT(m_tabs != 0); // There are no tabs to name - int index = m_tabWidget->currentIndex(); - m_tabWidget->setTabText(index, tabName); -} - -// ******************* BtWebView ******************* - -BtWebView::BtWebView(QWidget* parent) - : QWebView(parent), m_popup(0) { - m_popup = new QMenu(this); - QAction* copyAction = pageAction(QWebPage::Copy); - m_popup->addAction(copyAction); -} - -void BtWebView::contextMenuEvent(QContextMenuEvent* event) { - m_popup->exec(event->globalPos()); -} - diff --git a/src/frontend/htmldialogs/bttabhtmldialog.h b/src/frontend/htmldialogs/bttabhtmldialog.h deleted file mode 100644 index 6e5ed20..0000000 --- a/src/frontend/htmldialogs/bttabhtmldialog.h +++ /dev/null @@ -1,87 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BTTABDIALOG_H -#define BTTABDIALOG_H - -#include - -#include -#include -#include - - -class QTabWidget; -class QMenu; - -// This class creates a dialog with zero or more tabs. For zero tabs it is -// just a single QWebView inside the dialog. For 1 or more tabs, each tab -// contains a separate QWebView. Each QWebView can have either plain text or -// html text. The class will automatically delete itself when closed. -// The class can either be directly called or subclassed. The dialog is not modal. - -// Typical direct usage: -// -// Zero tabs -// BtTabHtmlDialog* dlg = new BtTabHtmlDialog("My Title", 0, parent); -// dlg->setHtml(htmlText); -// dlg->show(); -// -// or -// -// Two tabs -// BtTabHtmlDialog* dlg = new BtTabHtmlDialog("My Title", 2, parent); -// dlg->selectTab(0); -// dlg->setTabText(nameOfTab0); -// dlg->setHtml(htmlText0); -// dlg->selectTab(1); -// dlg->setTabText(nameOfTab1); -// dlg->setHtml(htmlText1); -// dlg->show(); - - -class BtTabHtmlDialog : public QDialog { - Q_OBJECT - public: - BtTabHtmlDialog(const QString& title, int numberTabs, QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); - ~BtTabHtmlDialog(); - void selectTab(int tab); - void setTabText(const QString& tabName); - -// See QWebView::setHtml() - void setHtml(const QString& html, const QUrl& baseUrl = QUrl()); - -// See QWebView::setUrl() - void setUrl(const QUrl& url); - - private slots: - void linkClicked(const QUrl url); - - private: - void init_connections(QWebView* webView); - QWebView* webView(); - - QWebView* m_webView; - QTabWidget* m_tabWidget; - int m_tabs; -}; - - -class BtWebView : public QWebView { - public: - BtWebView(QWidget* parent = 0); - - protected: - void contextMenuEvent(QContextMenuEvent* event); - - private: - QMenu* m_popup; -}; - -#endif diff --git a/src/frontend/keychooser/bthistory.cpp b/src/frontend/keychooser/bthistory.cpp index 60d2a7b..329ce78 100644 --- a/src/frontend/keychooser/bthistory.cpp +++ b/src/frontend/keychooser/bthistory.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -28,7 +28,7 @@ void BTHistory::add(CSwordKey* newKey) { Q_ASSERT(newKey); // Add new key Action after current index if we were not using the history functions, // if it's not a duplicate and if it's not empty. - if (!m_inHistoryFunction && ((m_index < 0) || (newKey->key() != m_historyList.at(m_index)->text()) )) { + if (!m_inHistoryFunction && ((m_index < 0) || (newKey->key() != m_historyList.at(m_index)->text()) )) { if (!newKey->key().isEmpty()) { m_historyList.insert(++m_index, new QAction(newKey->key(), this)); } diff --git a/src/frontend/keychooser/bthistory.h b/src/frontend/keychooser/bthistory.h index df674d0..2a374b6 100644 --- a/src/frontend/keychooser/bthistory.h +++ b/src/frontend/keychooser/bthistory.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/keychooser/cbookkeychooser.cpp b/src/frontend/keychooser/cbookkeychooser.cpp index 21216e4..1c7fccb 100644 --- a/src/frontend/keychooser/cbookkeychooser.cpp +++ b/src/frontend/keychooser/cbookkeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,8 +21,11 @@ QMap boxes; -CBookKeyChooser::CBookKeyChooser(QList modules, CSwordKey *key, QWidget *parent) - : CKeyChooser(modules, key, parent), m_layout(0) { +CBookKeyChooser::CBookKeyChooser(const QList &modules, + BTHistory *historyPtr, CSwordKey *key, + QWidget *parent) + : CKeyChooser(modules, historyPtr, key, parent), m_layout(0) +{ setModules(modules, false); m_key = dynamic_cast(key); @@ -37,8 +40,6 @@ CBookKeyChooser::CBookKeyChooser(QList modules, CSwordKey *ke connect(this, SIGNAL(keyChanged(CSwordKey*)), history(), SLOT(add(CSwordKey*)) ); } -CBookKeyChooser::~CBookKeyChooser() {} - void CBookKeyChooser::setKey(CSwordKey* newKey) { setKey(newKey, true); } @@ -83,7 +84,7 @@ void CBookKeyChooser::setKey(CSwordKey* newKey, const bool emitSignal) { if (found) key = m_key->key(); //found: change key to this level else - m_key->key(key); //not found: restore old key + m_key->setKey(key); //not found: restore old key setupCombo(key, depth, index); @@ -119,14 +120,17 @@ CSwordKey* CBookKeyChooser::key() { } /** Sets another module to this keychooser */ -void CBookKeyChooser::setModules(const QList& modules, const bool refresh) { +void CBookKeyChooser::setModules(const QList &modules, + bool refresh) +{ + typedef CSwordBookModuleInfo CSBMI; m_modules.clear(); // for (modules.first(); modules.current(); modules.next()) { - QList::const_iterator end_it = modules.end(); - for (QList::const_iterator it(modules.begin()); it != end_it; ++it) { - if ( (*it)->type() == CSwordModuleInfo::GenericBook ) { - if (CSwordBookModuleInfo* book = dynamic_cast(*it)) { + Q_FOREACH(const CSwordModuleInfo *m, modules) { + if (m->type() == CSwordModuleInfo::GenericBook ) { + const CSBMI *book = dynamic_cast(m); + if (book != 0) { m_modules.append(book); } } @@ -214,8 +218,8 @@ void CBookKeyChooser::setupCombo(const QString key, const int depth, const int c CKeyChooserWidget* chooserWidget = m_chooserWidgets.at(depth); CSwordTreeKey tmpKey(*m_key); - tmpKey.key(key); - tmpKey.parent(); + tmpKey.setKey(key); + tmpKey.sword::TreeKeyIdx::parent(); tmpKey.firstChild(); QStringList items; @@ -250,7 +254,7 @@ void CBookKeyChooser::keyChooserChanged(int /*newIndex*/) { QString newKey("/"); newKey.append(items.join("/")); - m_key->key(newKey); + m_key->setKey(newKey); setKey(m_key); } @@ -260,6 +264,6 @@ void CBookKeyChooser::updateKey(CSwordKey* key) { } void CBookKeyChooser::setKey(QString& newKey) { - m_key->key(newKey); + m_key->setKey(newKey); setKey(m_key); } diff --git a/src/frontend/keychooser/cbookkeychooser.h b/src/frontend/keychooser/cbookkeychooser.h index f1ac69f..3b32d48 100644 --- a/src/frontend/keychooser/cbookkeychooser.h +++ b/src/frontend/keychooser/cbookkeychooser.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -30,16 +30,20 @@ class TreeKeyIdx; class CBookKeyChooser : public CKeyChooser { Q_OBJECT public: - CBookKeyChooser(QList modules, CSwordKey *key = 0, QWidget *parent = 0); - ~CBookKeyChooser(); + CBookKeyChooser(const QList &modules, + BTHistory *history, CSwordKey *key = 0, + QWidget *parent = 0); + /** - * Refreshes the content. + Reimplemented from CKeyChooser. */ virtual void refreshContent(); + /** * Sets another module to this keychooser */ - virtual void setModules(const QList& modules, const bool refresh = false); + virtual void setModules(const QList &modules, + bool refresh = false); /** * Returns the key of this keychooser */ @@ -78,7 +82,7 @@ class CBookKeyChooser : public CKeyChooser { private: QList m_chooserWidgets; - QList m_modules; + QList m_modules; CSwordTreeKey *m_key; QHBoxLayout* m_layout; }; diff --git a/src/frontend/keychooser/cbooktreechooser.cpp b/src/frontend/keychooser/cbooktreechooser.cpp index db55dca..1b0edd4 100644 --- a/src/frontend/keychooser/cbooktreechooser.cpp +++ b/src/frontend/keychooser/cbooktreechooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include "backend/config/cbtconfig.h" @@ -21,8 +20,9 @@ #include "frontend/keychooser/bthistory.h" -CBookTreeChooser::CBookTreeChooser(QList modules, CSwordKey *key, QWidget *parent) - : CKeyChooser(modules, key, parent), +CBookTreeChooser::CBookTreeChooser(const QList &modules, + BTHistory* historyPtr, CSwordKey *key, QWidget *parent) + : CKeyChooser(modules, historyPtr, key, parent), m_key( dynamic_cast(key) ) { setModules(modules, false); @@ -40,7 +40,7 @@ CBookTreeChooser::CBookTreeChooser(QList modules, CSwordKey * layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_treeView); - m_treeView->header()->hide(); + m_treeView->setHeaderHidden(true); //when user selects the item whe must react connect(m_treeView, SIGNAL(currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem*)), SLOT(itemActivated(QTreeWidgetItem*))); @@ -50,8 +50,6 @@ CBookTreeChooser::CBookTreeChooser(QList modules, CSwordKey * connect(this, SIGNAL(keyChanged(CSwordKey*)), history(), SLOT(add(CSwordKey*)) ); } -CBookTreeChooser::~CBookTreeChooser() {} - /** Sets a new key to this keychooser. Inherited from ckeychooser. */ void CBookTreeChooser::setKey(CSwordKey* key) { setKey(key, false); @@ -86,20 +84,16 @@ void CBookTreeChooser::setKey(CSwordKey* newKey, const bool emitSignal) { } } -/** Returns the key of this keychooser. Inherited from ckeychooser.*/ -CSwordKey* CBookTreeChooser::key() { - return m_key; -} - -/** Sets another module to this keychooser. Inherited from ckeychooser (therefore -the list of modules instead of one). */ -void CBookTreeChooser::setModules(const QList& modules, const bool refresh) { +void CBookTreeChooser::setModules(const QList &modules, + bool refresh) +{ + typedef CSwordBookModuleInfo CSBMI; //Add given modules into private list m_modules.clear(); - QList::const_iterator end_it = modules.end(); - for (QList::const_iterator it(modules.begin()); it != end_it; ++it) { - if (CSwordBookModuleInfo* book = dynamic_cast(*it)) { + Q_FOREACH (const CSwordModuleInfo *m, modules) { + const CSBMI *book = dynamic_cast(m); + if (book != 0) { m_modules.append(book); } } @@ -139,7 +133,7 @@ void CBookTreeChooser::itemActivated( QTreeWidgetItem* item ) { qDebug() << "CBookTreeChooser::itemActivated"; //Sometimes Qt calls this function with a null pointer. if (item) { - m_key->key(item->text(1)); + m_key->setKey(item->text(1)); //tell possible listeners about the change emit keyChanged(m_key); } @@ -193,6 +187,6 @@ void CBookTreeChooser::addKeyChildren(CSwordTreeKey* key, QTreeWidgetItem* item) } void CBookTreeChooser::setKey(QString& newKey) { - m_key->key(newKey); + m_key->setKey(newKey); setKey(m_key); } diff --git a/src/frontend/keychooser/cbooktreechooser.h b/src/frontend/keychooser/cbooktreechooser.h index 01fd369..409038e 100644 --- a/src/frontend/keychooser/cbooktreechooser.h +++ b/src/frontend/keychooser/cbooktreechooser.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,6 +12,7 @@ #include "frontend/keychooser/ckeychooser.h" +#include "backend/keys/cswordtreekey.h" #include "frontend/keychooser/ckeychooserwidget.h" @@ -20,9 +21,9 @@ class TreeKeyIdx; } class CSwordBookModuleInfo; class CSwordKey; -class CSwordTreeKey; class QTreeWidget; class QTreeWidgetItem; +class BTHistory; /** The keychooser implementation for books. * @author The BibleTime team @@ -30,24 +31,34 @@ class QTreeWidgetItem; class CBookTreeChooser : public CKeyChooser { Q_OBJECT public: - CBookTreeChooser(QList modules, CSwordKey *key = 0, QWidget *parent = 0); - ~CBookTreeChooser(); + CBookTreeChooser(const QList &modules, + BTHistory *history, CSwordKey *key = 0, + QWidget *parent = 0); + /** - * Refreshes the content. + Reimplemented from CKeyChooser::refreshContent(). */ virtual void refreshContent(); + /** - * Sets another module to this keychooser + Reimplemented from CKeyChooser::setModules(). */ - virtual void setModules(const QList& modules, const bool refresh = true); + virtual void setModules(const QList &modules, + bool refresh = true); + /** - * Returns the key of this keychooser. + Reimplemented from CKeyChooser::key(). */ - virtual CSwordKey* key(); + virtual inline CSwordKey *key() { + return m_key; + } + /** - * Sets a new key to this keychooser + Reimplemented from CKeyChooser::setKey(). */ - virtual void setKey(CSwordKey*); + virtual void setKey(CSwordKey *key); + + void setKey(CSwordKey*, const bool emitSinal); public slots: // Public slots @@ -71,7 +82,7 @@ class CBookTreeChooser : public CKeyChooser { void setKey(QString& newKey); private: - QList m_modules; + QList m_modules; CSwordTreeKey* m_key; QTreeWidget* m_treeView; }; diff --git a/src/frontend/keychooser/ckeychooser.cpp b/src/frontend/keychooser/ckeychooser.cpp index 905e125..4d58298 100644 --- a/src/frontend/keychooser/ckeychooser.cpp +++ b/src/frontend/keychooser/ckeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,37 +22,49 @@ #include "frontend/keychooser/versekeychooser/cbiblekeychooser.h" -CKeyChooser::CKeyChooser(QList, CSwordKey *, QWidget *parent) +CKeyChooser::CKeyChooser(const QList &, BTHistory* historyPtr, + CSwordKey *, QWidget *parent) : QWidget(parent), - m_history(0) { + m_history(historyPtr) { //qDebug() << "CKeyChooser::CKeyChooser"; - m_history = new BTHistory(this); - QObject::connect(history(), SIGNAL(historyMoved(QString&)), this, SLOT(setKey(QString&))); + bool ok = QObject::connect(history(), SIGNAL(historyMoved(QString&)), this, SLOT(setKey(QString&))); + Q_ASSERT(ok); } -CKeyChooser::~CKeyChooser() {} - -CKeyChooser* CKeyChooser::createInstance(QList modules, CSwordKey *key, QWidget *parent) { +CKeyChooser* CKeyChooser::createInstance( + const QList &modules, BTHistory *historyPtr, + CSwordKey *key, QWidget *parent) +{ if (!modules.count()) { + /** + \todo Verify and document that we need to return 0 here rather than + fail with an assertion. + */ return 0; } - switch ( modules.first()->type() ) { - case CSwordModuleInfo::Commentary: //Bibles and commentaries use the same key chooser + CSwordModuleInfo::ModuleType typeOfModules = modules.first()->type(); + +#ifdef BT_DEBUG + Q_FOREACH (const CSwordModuleInfo *module, modules) { + Q_ASSERT(module->type() == typeOfModules); + } +#endif + + switch (typeOfModules) { + case CSwordModuleInfo::Commentary: + /* Fall thru - Bibles and commentaries use the same key chooser */ case CSwordModuleInfo::Bible: - return new CBibleKeyChooser(modules, key, parent); - break; + return new CBibleKeyChooser(modules, historyPtr, key, parent); case CSwordModuleInfo::Lexicon: - return new CLexiconKeyChooser(modules, key, parent); + return new CLexiconKeyChooser(modules, historyPtr, key, parent); case CSwordModuleInfo::GenericBook: - return new CBookKeyChooser(modules, key, parent); + return new CBookKeyChooser(modules, historyPtr, key, parent); default: + /** + \todo Verify and document that we need to return 0 here rather + than fail with an assertion. + */ return 0; } } - - -BTHistory* CKeyChooser::history() { - return m_history; -} - diff --git a/src/frontend/keychooser/ckeychooser.h b/src/frontend/keychooser/ckeychooser.h index 4441df0..2a52de3 100644 --- a/src/frontend/keychooser/ckeychooser.h +++ b/src/frontend/keychooser/ckeychooser.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -32,46 +32,50 @@ class CKeyChooser : public QWidget { /** * Creates a proper Instance, either - * - @ref CLexiconKeyChooser or + * @ref CLexiconKeyChooser or * @ref CBibleKeyChooser * @param info the @ref CModuleInfo to be represented by the KeyChooser * @param key if not NULL, the @ref CKey the KeyChooser should be set to * @param parent the parent of the widget to create */ - static CKeyChooser* createInstance(QList modules, CSwordKey *key, QWidget *parent); + static CKeyChooser *createInstance( + const QList &modules, + BTHistory *history, CSwordKey *key, QWidget *parent); public slots: /** - * sets the @ref CKey - * @param key the key which the widget should be set to + Sets the CKey + \param key the key which the widget should be set to. */ virtual void setKey(CSwordKey* key) = 0; + /** - * sets the @ref CKey - * @param key the key which the widget should be set to + Updates the CKey. + \param key the key which the widget should be set to. */ - virtual void updateKey(CSwordKey* key) = 0; + virtual void updateKey(CSwordKey *key) = 0; + /** - * gets the current @ref CKey - * - * @return the current @ref CKey + \returns the current CKey. */ - virtual CSwordKey* key() = 0; + virtual CSwordKey *key() = 0; + /** - * Sets the module of this keychooser and refreshes the comboboxes + Sets the module of this keychooser and refreshes the comboboxes */ - virtual void setModules( const QList& modules, const bool refresh = true ) = 0; + virtual void setModules(const QList &modules, + bool refresh = true) = 0; + /** - * Freshes the content of the different key chooser parts. + Refreshes the content of the different key chooser parts. */ virtual void refreshContent() = 0; /** - * Returns the history object of this keychooser. + \returns the history object of this keychooser. */ - BTHistory* history(); + inline BTHistory *history() const { return m_history; } signals: @@ -86,21 +90,22 @@ class CKeyChooser : public QWidget { protected: + CKeyChooser(const QList &info, + BTHistory *history, CSwordKey *key = 0, + QWidget *parent = 0); + + virtual inline ~CKeyChooser() {} + /** - * the constructor - DO NOT USE! -- use @ref #createInstance instead! - */ - CKeyChooser(QList info, CSwordKey *key = 0, QWidget *parent = 0); - virtual ~CKeyChooser(); - /** - * Set the appropriate font do display the modules + Resets the appropriate font to for the modules. */ virtual void adjustFont() = 0; protected slots: - virtual void setKey(QString& newKey) = 0; + virtual void setKey(QString &newKey) = 0; private: - BTHistory* m_history; + BTHistory *m_history; }; diff --git a/src/frontend/keychooser/ckeychooserwidget.cpp b/src/frontend/keychooser/ckeychooserwidget.cpp index a11bd6f..1c8cc4d 100644 --- a/src/frontend/keychooser/ckeychooserwidget.cpp +++ b/src/frontend/keychooser/ckeychooserwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -127,7 +127,7 @@ void CKeyChooserWidget::reset(const int count, int index, bool do_emit) { //This prevents the widget from resetting during application load, which //produces undesirable behavior. //if (!updatesEnabled()) - // return; + // return; m_list.clear(); for (int i = 1; i <= count; i++) { /// \todo CHECK @@ -137,18 +137,18 @@ void CKeyChooserWidget::reset(const int count, int index, bool do_emit) { reset(&m_list, index, do_emit); } -void CKeyChooserWidget::reset(QStringList& list, int index, bool do_emit) { +void CKeyChooserWidget::reset(const QStringList &list, int index, bool do_emit) { //This prevents the widget from resetting during application load, which //produces undesirable behavior. //if (!updatesEnabled()) - // return; + // return; m_list = list; reset(&m_list, index, do_emit); } -void CKeyChooserWidget::reset(QStringList *list, int index, bool do_emit) { +void CKeyChooserWidget::reset(const QStringList *list, int index, bool do_emit) { //if (isResetting || !updatesEnabled()) if (isResetting) return; @@ -239,7 +239,7 @@ void CKeyChooserWidget::slotReturnPressed( /*const QString& text*/) { QString text = comboBox()->lineEdit()->text(); for (int index = 0; index < comboBox()->count(); ++index) { if (comboBox()->itemText(index) == text) { -// emit changed(index); +// emit changed(index); emit focusOut(index); // a workaround because focusOut is not checked, the slot connected to changed to check break; } diff --git a/src/frontend/keychooser/ckeychooserwidget.h b/src/frontend/keychooser/ckeychooserwidget.h index 1dab8b3..384b19a 100644 --- a/src/frontend/keychooser/ckeychooserwidget.h +++ b/src/frontend/keychooser/ckeychooserwidget.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -63,15 +63,15 @@ class CKCComboBox : public QComboBox { */ class CKeyChooserWidget : public QWidget { Q_OBJECT + public: - /** - * the constructor - */ - CKeyChooserWidget(QStringList *list = 0, const bool useNextPrevSignals = false, QWidget *parent = 0 ); - /** - * the constructor - */ - CKeyChooserWidget(int count = 0, const bool useNextPrevSignals = false, QWidget *parent = 0 ); + CKeyChooserWidget(QStringList *list = 0, + const bool useNextPrevSignals = false, + QWidget *parent = 0); + + CKeyChooserWidget(int count = 0, const bool useNextPrevSignals = false, + QWidget *parent = 0); + /** * This function does clear the combobox, then fill in * the StringList, set the ComboBox' current item to index @@ -82,8 +82,9 @@ class CKeyChooserWidget : public QWidget { * @param do_emit should we emit @ref #changed(int) */ void reset(const int count, int index, bool do_emit); - void reset(QStringList& list, int index, bool do_emit); - void reset(QStringList *list, int index, bool do_emit); + void reset(const QStringList &list, int index, bool do_emit); + void reset(const QStringList *list, int index, bool do_emit); + /** * Initializes this widget. We need this function because * we have more than one constructor. diff --git a/src/frontend/keychooser/clexiconkeychooser.cpp b/src/frontend/keychooser/clexiconkeychooser.cpp index eca19d4..e09efb1 100644 --- a/src/frontend/keychooser/clexiconkeychooser.cpp +++ b/src/frontend/keychooser/clexiconkeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,8 +10,6 @@ #include "frontend/keychooser/clexiconkeychooser.h" #include -#include -#include #include #include #include "backend/config/cbtconfig.h" @@ -23,9 +21,12 @@ #include "util/cresmgr.h" -CLexiconKeyChooser::CLexiconKeyChooser(QList modules, CSwordKey *key, QWidget *parent) - : CKeyChooser(modules, key, parent), - m_key(dynamic_cast(key)) { +CLexiconKeyChooser::CLexiconKeyChooser( + const QList &modules, + BTHistory *historyPtr, CSwordKey *key, QWidget *parent) + : CKeyChooser(modules, historyPtr, key, parent), + m_key(dynamic_cast(key)) +{ setModules(modules, false); //we use a layout because the key chooser should be resized to full size @@ -64,9 +65,8 @@ CSwordKey* CLexiconKeyChooser::key() { return m_key; } -void CLexiconKeyChooser::setKey(CSwordKey* key) { - qDebug() << "CLexiconKeyChooser::setKey"; - +/** Update key display without emiting a signal */ +void CLexiconKeyChooser::updateKey(CSwordKey* key) { if (!(m_key = dynamic_cast(key))) { return; } @@ -74,6 +74,16 @@ void CLexiconKeyChooser::setKey(CSwordKey* key) { QString newKey = m_key->key(); const int index = m_widget->comboBox()->findText(newKey); m_widget->comboBox()->setCurrentIndex(index); +} + +void CLexiconKeyChooser::setKey(CSwordKey* key) { + qDebug() << "CLexiconKeyChooser::setKey"; + + if (!(m_key = dynamic_cast(key))) { + return; + } + + updateKey(key); // qWarning("setKey end"); emit keyChanged( m_key); @@ -85,7 +95,7 @@ void CLexiconKeyChooser::activated(int index) { // To prevent from eternal loop, because activated() is emitted again if (m_key && m_key->key() != text) { - m_key->key(text); + m_key->setKey(text); setKey(m_key); } // qWarning("activated end"); @@ -98,24 +108,24 @@ inline bool my_cmpEntries(const QString& a, const QString& b) { /** Reimplementation. */ void CLexiconKeyChooser::refreshContent() { if (m_modules.count() == 1) { - m_widget->reset(m_modules.first()->entries(), 0, true); + m_widget->reset(&m_modules.first()->entries(), 0, true); // qWarning("resetted"); } else { - typedef std::multimap EntryMap; + typedef std::multimap EntryMap; EntryMap entryMap; - QStringList* entries = 0; - QListIterator mit(m_modules); + + QListIterator mit(m_modules); while (mit.hasNext()) { - entries = mit.next()->entries(); - entryMap.insert( std::make_pair(entries->count(), entries) ); + const QStringList &entries = mit.next()->entries(); + entryMap.insert( std::make_pair(entries.count(), &entries) ); } QStringList goodEntries; //The string list which contains the entries which are available in all modules EntryMap::iterator it = entryMap.begin(); //iterator to go thoigh all selected modules QStringList refEntries = *(it->second); //copy the items for the first time - QStringList* cmpEntries = ( ++it )->second; //list for comparision, starts with the second module in the map + const QStringList *cmpEntries = (++it)->second; //list for comparision, starts with the second module in the map // Testing for refEntries being empty is not needed for the set union // of all keys, but is a good idea since it is being updated in the @@ -142,21 +152,17 @@ void CLexiconKeyChooser::refreshContent() { } -/** No descriptions */ -void CLexiconKeyChooser::adjustFont() { - -} - -/** Sets the module and refreshes the combo boxes */ -void CLexiconKeyChooser::setModules( const QList& modules, const bool refresh ) { +void CLexiconKeyChooser::setModules(const QList &modules, + bool refresh) +{ + typedef CSwordLexiconModuleInfo CSLMI; while (!m_modules.isEmpty()) m_modules.takeFirst(); // not deleting the pointer - QList::const_iterator end_it = modules.end(); - for (QList::const_iterator it(modules.begin()); it != end_it; ++it) { - CSwordLexiconModuleInfo* lexicon = dynamic_cast(*it); - if (lexicon) { + Q_FOREACH(const CSwordModuleInfo *m, modules) { + const CSLMI *lexicon = dynamic_cast(m); + if (lexicon != 0) { m_modules.append(lexicon); } } @@ -167,10 +173,7 @@ void CLexiconKeyChooser::setModules( const QList& modules, co } } -/** No descriptions */ -void CLexiconKeyChooser::updateKey(CSwordKey*) {} - void CLexiconKeyChooser::setKey(QString& newKey) { - m_key->key(newKey); + m_key->setKey(newKey); setKey(m_key); } diff --git a/src/frontend/keychooser/clexiconkeychooser.h b/src/frontend/keychooser/clexiconkeychooser.h index f93a148..e014448 100644 --- a/src/frontend/keychooser/clexiconkeychooser.h +++ b/src/frontend/keychooser/clexiconkeychooser.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -30,46 +30,48 @@ class QWidget; */ class CLexiconKeyChooser : public CKeyChooser { Q_OBJECT + public: - /** - * The constructor - * - * you should not need to use this, use @ref CKeyChooser::createInstance instead - */ - CLexiconKeyChooser(QList modules, CSwordKey *key = 0, QWidget *parent = 0); + CLexiconKeyChooser(const QList &modules, + BTHistory *history, CSwordKey *key = 0, + QWidget *parent = 0); public slots: /** - * see @ref CKeyChooser::getKey - * @return Return the key object we use. + Reimplemented from CKeyChooser::key(). */ - virtual CSwordKey* key(); + virtual CSwordKey *key(); + /** - * see @ref CKeyChooser::setKey + Reimplemented from CKeyChooser::setKey(). */ virtual void setKey(CSwordKey* key); + /** * used to react to changes in the @ref CKeyChooserWidget * * @param index not used **/ virtual void activated(int index); + /** - * Reimplementation. + Reimplemented from CKeyChooser::refreshContent(). */ virtual void refreshContent(); + /** - * Sets the module and refreshes the combo boxes of this keychooser. + Reimplemented from CKeyChooser::setModules(). */ - virtual void setModules( const QList& modules, const bool refresh = true ); + virtual void setModules(const QList &modules, + bool refresh = true); protected: CKeyChooserWidget *m_widget; CSwordLDKey* m_key; - QList m_modules; + QList m_modules; QHBoxLayout *m_layout; - virtual void adjustFont(); + virtual inline void adjustFont() {} public slots: // Public slots virtual void updateKey(CSwordKey* key); diff --git a/src/frontend/keychooser/cscrollbutton.cpp b/src/frontend/keychooser/cscrollbutton.cpp index 5154241..df1c35d 100644 --- a/src/frontend/keychooser/cscrollbutton.cpp +++ b/src/frontend/keychooser/cscrollbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/keychooser/cscrollbutton.h b/src/frontend/keychooser/cscrollbutton.h index f795b24..2c298b3 100644 --- a/src/frontend/keychooser/cscrollbutton.h +++ b/src/frontend/keychooser/cscrollbutton.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -61,8 +61,8 @@ class CScrollButton: public QToolButton { virtual void mouseReleaseEvent(QMouseEvent *e); /** - * \brief Reimplementation from \ref QWidget#mouseMoveEvent - processes - * the mouse move events + * \brief Reimplementation of QWidget::mouseMoveEvent() to process mouse + move events. */ virtual void mouseMoveEvent(QMouseEvent *e); @@ -72,7 +72,7 @@ class CScrollButton: public QToolButton { * * If the button is in the locked state, this means the mouse is grabbed * and any mouse move events invoke calculation about whether to emit the - * \ref CScrollButton#change_requested signal. + * change_requested() signal. */ bool m_isLocked; }; diff --git a/src/frontend/keychooser/cscrollerwidgetset.cpp b/src/frontend/keychooser/cscrollerwidgetset.cpp index 7c987cc..4ad8750 100644 --- a/src/frontend/keychooser/cscrollerwidgetset.cpp +++ b/src/frontend/keychooser/cscrollerwidgetset.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/keychooser/cscrollerwidgetset.h b/src/frontend/keychooser/cscrollerwidgetset.h index ae81636..8645efc 100644 --- a/src/frontend/keychooser/cscrollerwidgetset.h +++ b/src/frontend/keychooser/cscrollerwidgetset.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,11 +26,10 @@ class QVBoxLayout; */ class CScrollerWidgetSet : public QWidget { Q_OBJECT + public: - /** - * the constructor - */ CScrollerWidgetSet(QWidget *parent = 0); + /** * Sets the tooltips for the given entries using the parameters as text. */ diff --git a/src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp new file mode 100644 index 0000000..b74752e --- /dev/null +++ b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.cpp @@ -0,0 +1,293 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/keychooser/versekeychooser/btbiblekeywidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "backend/config/cbtconfig.h" +#include "backend/keys/cswordversekey.h" +#include "frontend/keychooser/cscrollerwidgetset.h" +#include "frontend/keychooser/versekeychooser/btdropdownchooserbutton.h" +#include "util/btsignal.h" +#include "util/cresmgr.h" +#include "util/directory.h" + + +class BtLineEdit : public QLineEdit { + public: + BtLineEdit(QWidget* parent) + : QLineEdit(parent) { + } + protected: + void focusInEvent(QFocusEvent* event) { + Qt::FocusReason reason = event->reason(); + if (reason == Qt::OtherFocusReason) { + selectAll(); + } + + QWidget::focusInEvent(event); + } +}; + + +BtBibleKeyWidget::BtBibleKeyWidget(const CSwordBibleModuleInfo *mod, + CSwordVerseKey *key, QWidget *parent, + const char *name) + : QWidget(parent), m_key(key), m_dropDownHoverTimer(this) +{ + Q_UNUSED(name); + + namespace DU = util::directory; + + + updatelock = false; + m_module = mod; + + setFocusPolicy(Qt::WheelFocus); + + QToolButton* clearRef = new QToolButton(this); + clearRef->setIcon(DU::getIcon("edit_clear_locationbar")); + clearRef->setAutoRaise(true); + clearRef->setStyleSheet("QToolButton{margin:0px;}"); + connect(clearRef, SIGNAL(clicked()), SLOT(slotClearRef()) ); + + m_bookScroller = new CScrollerWidgetSet(this); + + m_textbox = new BtLineEdit( this ); + setFocusProxy(m_textbox); + m_textbox->setContentsMargins(0, 0, 0, 0); + + m_chapterScroller = new CScrollerWidgetSet(this); + m_verseScroller = new CScrollerWidgetSet(this); + + QHBoxLayout* m_mainLayout = new QHBoxLayout( this ); + m_mainLayout->setContentsMargins(0, 0, 0, 0); + m_mainLayout->setSpacing(0); + m_mainLayout->addWidget(clearRef); + m_mainLayout->addWidget(m_bookScroller); + m_mainLayout->addWidget(m_textbox); + m_mainLayout->addWidget(m_chapterScroller); + m_mainLayout->addWidget(m_verseScroller); + + + setTabOrder(m_textbox, 0); + m_dropDownButtons = new QWidget(0); + m_dropDownButtons->setWindowFlags(Qt::Popup); + m_dropDownButtons->setAttribute(Qt::WA_WindowPropagation); + m_dropDownButtons->setCursor(Qt::ArrowCursor); + QHBoxLayout *dropDownButtonsLayout(new QHBoxLayout(m_dropDownButtons)); + m_bookDropdownButton = new BtBookDropdownChooserButton(this); + dropDownButtonsLayout->addWidget(m_bookDropdownButton, 2); + m_chapterDropdownButton = new BtChapterDropdownChooserButton(this); + dropDownButtonsLayout->addWidget(m_chapterDropdownButton, 1); + m_verseDropdownButton = new BtVerseDropdownChooserButton(this); + dropDownButtonsLayout->addWidget(m_verseDropdownButton, 1); + dropDownButtonsLayout->setContentsMargins(0, 0, 0, 0); + dropDownButtonsLayout->setSpacing(0); + m_dropDownButtons->setLayout(dropDownButtonsLayout); + m_dropDownButtons->hide(); + + m_dropDownButtons->installEventFilter(this); + + m_dropDownHoverTimer.setInterval(500); + m_dropDownHoverTimer.setSingleShot(true); + connect(&m_dropDownHoverTimer, SIGNAL(timeout()), + m_dropDownButtons, SLOT(hide())); + + QString scrollButtonToolTip(tr("Scroll through the entries of the list. Press the button and move the mouse to increase or decrease the item.")); + m_bookScroller->setToolTips( + tr("Next book"), + scrollButtonToolTip, + tr("Previous book") + ); + m_chapterScroller->setToolTips( + tr("Next chapter"), + scrollButtonToolTip, + tr("Previous chapter") + ); + m_verseScroller->setToolTips( + tr("Next verse"), + scrollButtonToolTip, + tr("Previous verse") + ); + + // signals and slots connections + + connect(m_bookScroller, SIGNAL(change(int)), SLOT(slotStepBook(int))); + connect(m_bookScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); + connect(m_bookScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); + connect(m_textbox, SIGNAL(returnPressed()), SLOT(slotReturnPressed())); + connect(m_chapterScroller, SIGNAL(change(int)), SLOT(slotStepChapter(int))); + connect(m_chapterScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); + connect(m_chapterScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); + connect(m_verseScroller, SIGNAL(change(int)), SLOT(slotStepVerse(int))); + connect(m_verseScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); + connect(m_verseScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); + bool ok = connect(m_key->signaler(), SIGNAL(changed()), this, SLOT(updateText())); + Q_ASSERT(ok); + + setKey(key); // The order of these two functions is important. + setModule(); +} + +BtBibleKeyWidget::~BtBibleKeyWidget() { + delete m_dropDownButtons; +} + +void BtBibleKeyWidget::setModule(const CSwordBibleModuleInfo *m) { + if (m) { //can be null + m_module = m; + m_key->setModule(m); + } +} + +bool BtBibleKeyWidget::eventFilter(QObject *o, QEvent *e) { + if (o != m_dropDownButtons) return false; + switch (e->type()) { + case QEvent::Enter: + m_dropDownHoverTimer.stop(); + return true; + case QEvent::Leave: + m_dropDownHoverTimer.start(); + return true; + default: + return false; + } +} + +void BtBibleKeyWidget::enterEvent(QEvent *) { + m_dropDownHoverTimer.stop(); + + resetDropDownButtons(); + + m_dropDownButtons->raise(); + m_dropDownButtons->show(); +} + +void BtBibleKeyWidget::leaveEvent(QEvent *) { + m_dropDownHoverTimer.start(); +} + +void BtBibleKeyWidget::resizeEvent(QResizeEvent *event) { + if (m_dropDownButtons->isVisible()) { + resetDropDownButtons(); + } + QWidget::resizeEvent(event); +} + +void BtBibleKeyWidget::resetDropDownButtons() { + m_dropDownButtons->setParent(window()); + int h(m_dropDownButtons->layout()->minimumSize().height()); + QPoint topLeft(mapTo(window(), + QPoint(m_textbox->x(), m_textbox->y() + m_textbox->height()))); + m_dropDownButtons->setGeometry(topLeft.x(), topLeft.y(), + m_textbox->width(), h); +} + +void BtBibleKeyWidget::slotClearRef( ) { + m_textbox->setText(""); + m_textbox->setFocus(); +} + +void BtBibleKeyWidget::updateText() { + QString text(m_key->key()); + m_textbox->setText(text); + QFontMetrics fm(m_textbox->font()); + int nw(m_textbox->minimumSizeHint().width() + fm.width(text)); + if (nw > m_textbox->minimumWidth()) { + m_textbox->setMinimumWidth(nw); + m_textbox->updateGeometry(); + } +} + +bool BtBibleKeyWidget::setKey(CSwordVerseKey *key) { + if (!key) return false; + + m_key->setKey(key->key()); + return true; +} + +void BtBibleKeyWidget::slotReturnPressed() { + m_key->setKey(m_textbox->text()); + emit changed(m_key); +} + +/* Handlers for the various scroller widgetsets. Do we really want a verse scroller? */ +void BtBibleKeyWidget::slotUpdateLock() { + updatelock = true; + oldKey = m_key->key(); +} + +void BtBibleKeyWidget::slotUpdateUnlock() { + updatelock = false; + if (oldKey != m_key->key()) + emit changed(m_key); +} + +void BtBibleKeyWidget::slotStepBook(int n) { + emit beforeChange(m_key); + n > 0 ? m_key->next( CSwordVerseKey::UseBook ) : m_key->previous( CSwordVerseKey::UseBook ); + if (!updatelock) + emit changed(m_key); +} + +void BtBibleKeyWidget::slotStepChapter(int n) { + emit beforeChange(m_key); + n > 0 ? m_key->next( CSwordVerseKey::UseChapter ) : m_key->previous( CSwordVerseKey::UseChapter ); + if (!updatelock) + emit changed(m_key); +} + +void BtBibleKeyWidget::slotStepVerse(int n) { + emit beforeChange(m_key); + n > 0 ? m_key->next( CSwordVerseKey::UseVerse ) : m_key->previous( CSwordVerseKey::UseVerse ); + if (!updatelock) + emit changed(m_key); +} + + +void BtBibleKeyWidget::slotChangeVerse(int n) { + if (m_key->Verse() != n) { + emit beforeChange(m_key); + m_key->Verse( n ); + setKey( m_key ); + } + if (!updatelock) emit changed(m_key); +} + +void BtBibleKeyWidget::slotChangeChapter(int n) { + if (m_key->Chapter() != n) { + emit beforeChange(m_key); + m_key->Chapter( n ); + setKey( m_key ); + } + if (!updatelock) + emit changed(m_key); +} + +void BtBibleKeyWidget::slotChangeBook(QString bookname) { + if (m_key->book() != bookname) { + emit beforeChange(m_key); + m_key->book( bookname ); + setKey( m_key ); + } + if (!updatelock) + emit changed(m_key); +} + diff --git a/src/frontend/keychooser/versekeychooser/btbiblekeywidget.h b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.h new file mode 100644 index 0000000..29633fd --- /dev/null +++ b/src/frontend/keychooser/versekeychooser/btbiblekeywidget.h @@ -0,0 +1,94 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTBIBLEKEYWIDGET_H +#define BTBIBLEKEYWIDGET_H + +#include + +#include +#include "backend/drivers/cswordbiblemoduleinfo.h" +#include "frontend/keychooser/cscrollerwidgetset.h" + + +class BtDropdownChooserButton; +class CLexiconKeyChooser; +class CSwordVerseKey; +class QLineEdit; + +class BtBibleKeyWidget : public QWidget { + Q_OBJECT + + public: + BtBibleKeyWidget(const CSwordBibleModuleInfo *module, + CSwordVerseKey *key, QWidget *parent = 0, + const char *name = 0); + + ~BtBibleKeyWidget(); + bool setKey(CSwordVerseKey* key); + void setModule(const CSwordBibleModuleInfo *m = 0); + bool eventFilter(QObject *o, QEvent *e); + + signals: + void beforeChange(CSwordVerseKey* key); + void changed(CSwordVerseKey* key); + + protected: + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void resizeEvent(QResizeEvent *event); + void resetDropDownButtons(); + + protected slots: // Protected slots + /** + * Is called when the return key was presed in the textbox. + */ + void slotReturnPressed(); + + void slotClearRef(); + + void slotUpdateLock(); + void slotUpdateUnlock(); + void slotStepBook(int); + void slotStepChapter(int); + void slotStepVerse(int); + void slotChangeBook(QString bookname); + void slotChangeChapter(int chapter); + void slotChangeVerse(int verse); + + public slots: + void updateText(); + + private: + friend class CLexiconKeyChooser; + friend class BtDropdownChooserButton; + friend class BtBookDropdownChooserButton; + friend class BtChapterDropdownChooserButton; + friend class BtVerseDropdownChooserButton; + + CSwordVerseKey *m_key; + + QLineEdit* m_textbox; + + CScrollerWidgetSet *m_bookScroller; + CScrollerWidgetSet *m_chapterScroller; + CScrollerWidgetSet *m_verseScroller; + + QWidget *m_dropDownButtons; + QTimer m_dropDownHoverTimer; + BtDropdownChooserButton* m_bookDropdownButton; + BtDropdownChooserButton* m_chapterDropdownButton; + BtDropdownChooserButton* m_verseDropdownButton; + + bool updatelock; + QString oldKey; + const CSwordBibleModuleInfo *m_module; +}; + +#endif diff --git a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp index 1e8c292..512a0f3 100644 --- a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp +++ b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,12 +12,12 @@ #include #include #include "frontend/keychooser/versekeychooser/btversekeymenu.h" -#include "frontend/keychooser/versekeychooser/ckeyreferencewidget.h" +#include "frontend/keychooser/versekeychooser/btbiblekeywidget.h" const unsigned int ARROW_HEIGHT = 15; -BtDropdownChooserButton::BtDropdownChooserButton(CKeyReferenceWidget* ref) +BtDropdownChooserButton::BtDropdownChooserButton(BtBibleKeyWidget* ref) : QToolButton(), m_ref(ref) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); @@ -30,7 +30,7 @@ BtDropdownChooserButton::BtDropdownChooserButton(CKeyReferenceWidget* ref) setStyleSheet("QToolButton{margin:0px;}QToolButton::menu-indicator{subcontrol-position: center center;}"); BtVerseKeyMenu* m = new BtVerseKeyMenu(this); -// KAcceleratorManager::setNoAccel(m); +// KAcceleratorManager::setNoAccel(m); setMenu(m); QObject::connect(m, SIGNAL(triggered(QAction*)), this, SLOT(slotMenuTriggered(QAction*))); } @@ -61,7 +61,7 @@ void BtDropdownChooserButton::wheelEvent(QWheelEvent* e) { //******************Book dropdown button*************************************/ -BtBookDropdownChooserButton::BtBookDropdownChooserButton(CKeyReferenceWidget* ref) +BtBookDropdownChooserButton::BtBookDropdownChooserButton(BtBibleKeyWidget* ref) : BtDropdownChooserButton(ref) { setToolTip(tr("Select book")); QObject::connect(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepBook(int))); @@ -83,7 +83,7 @@ void BtBookDropdownChooserButton::slotMenuTriggered(QAction* action) { //****************** Chapter dropdown button *************************************/ -BtChapterDropdownChooserButton::BtChapterDropdownChooserButton(CKeyReferenceWidget* ref) +BtChapterDropdownChooserButton::BtChapterDropdownChooserButton(BtBibleKeyWidget* ref) : BtDropdownChooserButton(ref) { setToolTip(tr("Select chapter")); QObject::connect(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepChapter(int))); @@ -104,7 +104,7 @@ void BtChapterDropdownChooserButton::slotMenuTriggered(QAction* action) { //****************** Verse dropdown button *************************************/ -BtVerseDropdownChooserButton::BtVerseDropdownChooserButton(CKeyReferenceWidget* ref) +BtVerseDropdownChooserButton::BtVerseDropdownChooserButton(BtBibleKeyWidget* ref) : BtDropdownChooserButton(ref) { setToolTip(tr("Select verse")); QObject::connect(this, SIGNAL(stepItem(int)), m_ref, SLOT(slotStepVerse(int))); diff --git a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h index e9dbdc2..04b7000 100644 --- a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h +++ b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,7 +13,7 @@ #include -class CKeyReferenceWidget; +class BtBibleKeyWidget; /** * Base class for book/ch/v dropdown list chooser buttons. @@ -21,7 +21,7 @@ class CKeyReferenceWidget; class BtDropdownChooserButton : public QToolButton { Q_OBJECT public: - BtDropdownChooserButton(CKeyReferenceWidget* ref); + BtDropdownChooserButton(BtBibleKeyWidget* ref); virtual ~BtDropdownChooserButton() {} /** The item list is constructed here just before the menu is shown.*/ @@ -29,14 +29,14 @@ class BtDropdownChooserButton : public QToolButton { /** Recreates the menu list.*/ virtual void newList() = 0; /** Returns the verse reference widget which this button belongs to.*/ - CKeyReferenceWidget* ref() { + BtBibleKeyWidget* ref() { return m_ref; } public slots: /** When a menu item is selected the key will be changed.*/ virtual void slotMenuTriggered(QAction* action) = 0; protected: - CKeyReferenceWidget* m_ref; + BtBibleKeyWidget* m_ref; void wheelEvent(QWheelEvent* event); signals: void stepItem(int step); @@ -46,7 +46,7 @@ class BtDropdownChooserButton : public QToolButton { class BtBookDropdownChooserButton : public BtDropdownChooserButton { Q_OBJECT public: - BtBookDropdownChooserButton(CKeyReferenceWidget* ref); + BtBookDropdownChooserButton(BtBibleKeyWidget* ref); ~BtBookDropdownChooserButton() {} virtual void newList(); public slots: @@ -57,7 +57,7 @@ class BtBookDropdownChooserButton : public BtDropdownChooserButton { class BtChapterDropdownChooserButton : public BtDropdownChooserButton { Q_OBJECT public: - BtChapterDropdownChooserButton(CKeyReferenceWidget* ref); + BtChapterDropdownChooserButton(BtBibleKeyWidget* ref); ~BtChapterDropdownChooserButton() {} virtual void newList(); public slots: @@ -68,7 +68,7 @@ class BtChapterDropdownChooserButton : public BtDropdownChooserButton { class BtVerseDropdownChooserButton : public BtDropdownChooserButton { Q_OBJECT public: - BtVerseDropdownChooserButton(CKeyReferenceWidget* ref); + BtVerseDropdownChooserButton(BtBibleKeyWidget* ref); ~BtVerseDropdownChooserButton() {} virtual void newList(); public slots: diff --git a/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp b/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp index c06a18d..9c6e77f 100644 --- a/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp +++ b/src/frontend/keychooser/versekeychooser/btversekeymenu.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/keychooser/versekeychooser/btversekeymenu.h b/src/frontend/keychooser/versekeychooser/btversekeymenu.h index f47d0f5..7f5b333 100644 --- a/src/frontend/keychooser/versekeychooser/btversekeymenu.h +++ b/src/frontend/keychooser/versekeychooser/btversekeymenu.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp index 2488668..6a16d8d 100644 --- a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp +++ b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,13 +16,18 @@ #include "backend/keys/cswordversekey.h" #include "frontend/keychooser/bthistory.h" #include "frontend/keychooser/cscrollbutton.h" -#include "frontend/keychooser/versekeychooser/ckeyreferencewidget.h" +#include "frontend/keychooser/versekeychooser/btbiblekeywidget.h" #include "util/cresmgr.h" -CBibleKeyChooser::CBibleKeyChooser(QList modules, CSwordKey *key, QWidget *parent) : - CKeyChooser(modules, key, parent), - m_key(dynamic_cast(key)) { +CBibleKeyChooser::CBibleKeyChooser( + const QList &modules, + BTHistory *historyPtr, CSwordKey *key, QWidget *parent) + : CKeyChooser(modules, historyPtr, key, parent), + m_key(dynamic_cast(key)) +{ + typedef CSwordBibleModuleInfo CSBMI; + w_ref = 0; setModules(modules, false); if (!m_modules.count()) { @@ -35,16 +40,19 @@ CBibleKeyChooser::CBibleKeyChooser(QList modules, CSwordKey * layout->setContentsMargins(0, 0, 0, 0); layout->setDirection( QBoxLayout::LeftToRight ); - w_ref = new CKeyReferenceWidget(dynamic_cast(m_modules.first()), m_key, this); + w_ref = new BtBibleKeyWidget(dynamic_cast(m_modules.first()), + m_key, this); setFocusProxy(w_ref); layout->addWidget(w_ref); - connect(w_ref, SIGNAL(beforeChange(CSwordVerseKey *)), SLOT(beforeRefChange(CSwordVerseKey *))); + bool ok = connect(w_ref, SIGNAL(beforeChange(CSwordVerseKey *)), SLOT(beforeRefChange(CSwordVerseKey *))); connect(w_ref, SIGNAL(changed(CSwordVerseKey *)), SLOT(refChanged(CSwordVerseKey *))); + Q_ASSERT(ok); setKey(m_key); //set the key without changing it, setKey(key()) would change it - connect(this, SIGNAL(keyChanged(CSwordKey*)), history(), SLOT(add(CSwordKey*)) ); + ok = connect(this, SIGNAL(keyChanged(CSwordKey*)), history(), SLOT(add(CSwordKey*)) ); + Q_ASSERT(ok); } CSwordKey* CBibleKeyChooser::key() { @@ -62,7 +70,7 @@ void CBibleKeyChooser::setKey(CSwordKey* key) { } void CBibleKeyChooser::beforeRefChange(CSwordVerseKey* key) { - Q_UNUSED(key); /// \todo Is this correct? + Q_UNUSED(key); Q_ASSERT(m_key); @@ -88,17 +96,26 @@ void CBibleKeyChooser::refChanged(CSwordVerseKey* key) { setUpdatesEnabled(true); } -void CBibleKeyChooser::setModules(const QList& modules, const bool refresh) { +void CBibleKeyChooser::setModules(const QList &modules, + bool refresh) +{ + typedef CSwordBibleModuleInfo CSBMI; + m_modules.clear(); - foreach (CSwordModuleInfo* mod, modules) { - if (mod->type() == CSwordModuleInfo::Bible || mod->type() == CSwordModuleInfo::Commentary) { - if (CSwordBibleModuleInfo* bible = dynamic_cast(mod)) m_modules.append(bible); + Q_FOREACH (const CSwordModuleInfo *mod, modules) { + if (mod->type() == CSwordModuleInfo::Bible + || mod->type() == CSwordModuleInfo::Commentary) + { + const CSBMI* bible = dynamic_cast(mod); + if (bible != 0) { + m_modules.append(bible); + } } } // First time this is called we havnt set up w_ref. - if (w_ref) w_ref->setModule(dynamic_cast(m_modules.first())); + if (w_ref) w_ref->setModule(dynamic_cast(m_modules.first())); if (refresh) refreshContent(); } @@ -106,11 +123,13 @@ void CBibleKeyChooser::refreshContent() { setKey(m_key); } -void CBibleKeyChooser::updateKey(CSwordKey* /*key*/) {} +void CBibleKeyChooser::updateKey(CSwordKey* /*key*/) { + w_ref->updateText(); +} void CBibleKeyChooser::adjustFont() {} void CBibleKeyChooser::setKey(QString& newKey) { - m_key->key(newKey); + m_key->setKey(newKey); setKey(m_key); } diff --git a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h index 9501099..d2c5363 100644 --- a/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h +++ b/src/frontend/keychooser/versekeychooser/cbiblekeychooser.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -18,7 +18,7 @@ class QWidget; -class CKeyReferenceWidget; +class BtBibleKeyWidget; class CSwordVerseKey; class CSwordBibleModuleInfo; @@ -26,7 +26,7 @@ class CSwordBibleModuleInfo; * * it inhertits @ref CKeyChooser * - * it uses a CKeyReferenceWidget 's to represent the bible keys + * it uses a BtBibleKeyWidget to represent the bible keys * * @author The BibleTime team */ @@ -35,25 +35,27 @@ class CBibleKeyChooser : public CKeyChooser { Q_OBJECT public: - /** - * the constructor - * you should not need to use this, use @ref CKeyChooser::createInstance instead - */ - CBibleKeyChooser(QList modules, CSwordKey *key = 0, QWidget *parent = 0); + CBibleKeyChooser(const QList &modules, + BTHistory *history, CSwordKey *key = 0, + QWidget *parent = 0); public slots: /** - * see @ref CKeyChooser::getKey + Reimplemented from CKeyChooser::key(). */ CSwordKey* key(); + /** - * see @ref CKeyChooser::setKey + Reimplemented from CKeyChooser::setKey(). */ virtual void setKey(CSwordKey *key); + /** - * Sets the module + Reimplemented from CKeyChooser::setModules(). */ - virtual void setModules(const QList& modules, const bool refresh = true); + virtual void setModules(const QList &modules, + bool refresh = true); + /** * used to do actions before key changes */ @@ -68,11 +70,14 @@ class CBibleKeyChooser : public CKeyChooser { void refreshContent(); protected slots: + /** + Reimplemented from CKeyChooser::setModules(). + */ virtual void setKey(QString& newKey); private: - CKeyReferenceWidget* w_ref; - QList m_modules; + BtBibleKeyWidget* w_ref; + QList m_modules; CSwordVerseKey *m_key; }; diff --git a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp deleted file mode 100644 index e5cf4ff..0000000 --- a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/keychooser/versekeychooser/ckeyreferencewidget.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend/config/cbtconfig.h" -#include "backend/keys/cswordversekey.h" -#include "frontend/keychooser/cscrollerwidgetset.h" -#include "frontend/keychooser/versekeychooser/btdropdownchooserbutton.h" -#include "util/cresmgr.h" -#include "util/directory.h" - - -class BtLineEdit : public QLineEdit { - public: - BtLineEdit(QWidget* parent) - : QLineEdit(parent) { - } - protected: - void focusInEvent(QFocusEvent* event) { - Qt::FocusReason reason = event->reason(); - if (reason == Qt::OtherFocusReason) { - selectAll(); - } - - QWidget::focusInEvent(event); - } -}; - - -CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVerseKey *key, QWidget *parent, const char* /*name*/) : - QWidget(parent), - m_key(key), - m_dropDownHoverTimer(this) { - namespace DU = util::directory; - - updatelock = false; - m_module = mod; - - setFocusPolicy(Qt::WheelFocus); - - QToolButton* clearRef = new QToolButton(this); - clearRef->setIcon(DU::getIcon("edit_clear_locationbar")); - clearRef->setAutoRaise(true); - clearRef->setStyleSheet("QToolButton{margin:0px;}"); - connect(clearRef, SIGNAL(clicked()), SLOT(slotClearRef()) ); - - m_bookScroller = new CScrollerWidgetSet(this); - - m_textbox = new BtLineEdit( this ); - setFocusProxy(m_textbox); - m_textbox->setContentsMargins(0, 0, 0, 0); - - setKey(key); // The order of these two functions is important. - setModule(); - - m_chapterScroller = new CScrollerWidgetSet(this); - m_verseScroller = new CScrollerWidgetSet(this); - - QHBoxLayout* m_mainLayout = new QHBoxLayout( this ); - m_mainLayout->setContentsMargins(0, 0, 0, 0); - m_mainLayout->setSpacing(0); - m_mainLayout->addWidget(clearRef); - m_mainLayout->addWidget(m_bookScroller); - m_mainLayout->addWidget(m_textbox); - m_mainLayout->addWidget(m_chapterScroller); - m_mainLayout->addWidget(m_verseScroller); - - - setTabOrder(m_textbox, 0); - m_dropDownButtons = new QWidget(0); - m_dropDownButtons->setWindowFlags(Qt::Popup); - m_dropDownButtons->setAttribute(Qt::WA_WindowPropagation); - m_dropDownButtons->setCursor(Qt::ArrowCursor); - QHBoxLayout *dropDownButtonsLayout(new QHBoxLayout(m_dropDownButtons)); - m_bookDropdownButton = new BtBookDropdownChooserButton(this); - dropDownButtonsLayout->addWidget(m_bookDropdownButton, 2); - m_chapterDropdownButton = new BtChapterDropdownChooserButton(this); - dropDownButtonsLayout->addWidget(m_chapterDropdownButton, 1); - m_verseDropdownButton = new BtVerseDropdownChooserButton(this); - dropDownButtonsLayout->addWidget(m_verseDropdownButton, 1); - dropDownButtonsLayout->setContentsMargins(0, 0, 0, 0); - dropDownButtonsLayout->setSpacing(0); - m_dropDownButtons->setLayout(dropDownButtonsLayout); - m_dropDownButtons->hide(); - - m_dropDownButtons->installEventFilter(this); - - m_dropDownHoverTimer.setInterval(500); - m_dropDownHoverTimer.setSingleShot(true); - connect(&m_dropDownHoverTimer, SIGNAL(timeout()), - m_dropDownButtons, SLOT(hide())); - - QString scrollButtonToolTip(tr("Scroll through the entries of the list. Press the button and move the mouse to increase or decrease the item.")); - m_bookScroller->setToolTips( - tr("Next book"), - scrollButtonToolTip, - tr("Previous book") - ); - m_chapterScroller->setToolTips( - tr("Next chapter"), - scrollButtonToolTip, - tr("Previous chapter") - ); - m_verseScroller->setToolTips( - tr("Next verse"), - scrollButtonToolTip, - tr("Previous verse") - ); - - // signals and slots connections - - connect(m_bookScroller, SIGNAL(change(int)), SLOT(slotStepBook(int))); - connect(m_bookScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); - connect(m_bookScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); - connect(m_textbox, SIGNAL(returnPressed()), SLOT(slotReturnPressed())); - connect(m_chapterScroller, SIGNAL(change(int)), SLOT(slotStepChapter(int))); - connect(m_chapterScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); - connect(m_chapterScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); - connect(m_verseScroller, SIGNAL(change(int)), SLOT(slotStepVerse(int))); - connect(m_verseScroller, SIGNAL(scroller_pressed()), SLOT(slotUpdateLock())); - connect(m_verseScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); -} - -CKeyReferenceWidget::~CKeyReferenceWidget() { - delete m_dropDownButtons; -} - -void CKeyReferenceWidget::setModule(CSwordBibleModuleInfo *m) { - if (m) { //can be null - m_module = m; - m_key->module(m); - } -} - -bool CKeyReferenceWidget::eventFilter(QObject *o, QEvent *e) { - if (o != m_dropDownButtons) return false; - switch (e->type()) { - case QEvent::Enter: - m_dropDownHoverTimer.stop(); - return true; - case QEvent::Leave: - m_dropDownHoverTimer.start(); - return true; - default: - return false; - } -} - -void CKeyReferenceWidget::enterEvent(QEvent *) { - m_dropDownHoverTimer.stop(); - - resetDropDownButtons(); - - m_dropDownButtons->raise(); - m_dropDownButtons->show(); -} - -void CKeyReferenceWidget::leaveEvent(QEvent *) { - m_dropDownHoverTimer.start(); -} - -void CKeyReferenceWidget::resizeEvent(QResizeEvent *event) { - if (m_dropDownButtons->isVisible()) { - resetDropDownButtons(); - } - QWidget::resizeEvent(event); -} - -void CKeyReferenceWidget::resetDropDownButtons() { - m_dropDownButtons->setParent(window()); - int h(m_dropDownButtons->layout()->minimumSize().height()); - QPoint topLeft(mapTo(window(), QPoint(m_textbox->x(), height()))); - m_dropDownButtons->setGeometry(topLeft.x(), topLeft.y(), - m_textbox->width(), h); -} - -void CKeyReferenceWidget::slotClearRef( ) { - m_textbox->setText(""); - m_textbox->setFocus(); -} - -void CKeyReferenceWidget::updateText() { - QString text(m_key->key()); - m_textbox->setText(text); - QFontMetrics fm(m_textbox->font()); - int nw(m_textbox->minimumSizeHint().width() + fm.width(text)); - if (nw > m_textbox->minimumWidth()) { - m_textbox->setMinimumWidth(nw); - m_textbox->updateGeometry(); - } -} - -bool CKeyReferenceWidget::setKey(CSwordVerseKey *key) { - if (!key) return false; - - m_key->key(key->key()); - updateText(); - return true; -} - -QLineEdit* CKeyReferenceWidget::textbox() { - return m_textbox; -} - -void CKeyReferenceWidget::slotReturnPressed() { - m_key->key(m_textbox->text()); - updateText(); - emit changed(m_key); -} - -/* Handlers for the various scroller widgetsets. Do we really want a verse scroller? */ -void CKeyReferenceWidget::slotUpdateLock() { - updatelock = true; - oldKey = m_key->key(); -} - -void CKeyReferenceWidget::slotUpdateUnlock() { - updatelock = false; - if (oldKey != m_key->key()) - emit changed(m_key); -} - -void CKeyReferenceWidget::slotStepBook(int n) { - emit beforeChange(m_key); - n > 0 ? m_key->next( CSwordVerseKey::UseBook ) : m_key->previous( CSwordVerseKey::UseBook ); - if (!updatelock) - emit changed(m_key); - updateText(); -} - -void CKeyReferenceWidget::slotStepChapter(int n) { - emit beforeChange(m_key); - n > 0 ? m_key->next( CSwordVerseKey::UseChapter ) : m_key->previous( CSwordVerseKey::UseChapter ); - if (!updatelock) - emit changed(m_key); - updateText(); -} - -void CKeyReferenceWidget::slotStepVerse(int n) { - emit beforeChange(m_key); - n > 0 ? m_key->next( CSwordVerseKey::UseVerse ) : m_key->previous( CSwordVerseKey::UseVerse ); - if (!updatelock) - emit changed(m_key); - updateText(); -} - - -void CKeyReferenceWidget::slotChangeVerse(int n) { - if (m_key->Verse() != n) { - emit beforeChange(m_key); - m_key->Verse( n ); - setKey( m_key ); - } - updateText(); - if (!updatelock) emit changed(m_key); -} - -void CKeyReferenceWidget::slotChangeChapter(int n) { - if (m_key->Chapter() != n) { - emit beforeChange(m_key); - m_key->Chapter( n ); - setKey( m_key ); - } - updateText(); - if (!updatelock) - emit changed(m_key); -} - -void CKeyReferenceWidget::slotChangeBook(QString bookname) { - if (m_key->book() != bookname) { - emit beforeChange(m_key); - m_key->book( bookname ); - setKey( m_key ); - } - updateText(); - if (!updatelock) - emit changed(m_key); -} - diff --git a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h deleted file mode 100644 index df2c9d2..0000000 --- a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h +++ /dev/null @@ -1,92 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CKEYREFERENCEWIDGET_H -#define CKEYREFERENCEWIDGET_H - -#include - -#include -#include "backend/drivers/cswordbiblemoduleinfo.h" -#include "frontend/keychooser/cscrollerwidgetset.h" - - -class BtDropdownChooserButton; -class CLexiconKeyChooser; -class CSwordVerseKey; -class QLineEdit; - -class CKeyReferenceWidget : public QWidget { - Q_OBJECT - public: - /** - * the constructor - */ - CKeyReferenceWidget(CSwordBibleModuleInfo *, CSwordVerseKey*, QWidget *parent = 0, const char *name = 0); - ~CKeyReferenceWidget(); - bool setKey(CSwordVerseKey* key); - QLineEdit* textbox(); - void setModule(CSwordBibleModuleInfo *m = 0); - bool eventFilter(QObject *o, QEvent *e); - - signals: - void beforeChange(CSwordVerseKey* key); - void changed(CSwordVerseKey* key); - - protected: - void enterEvent(QEvent *event); - void leaveEvent(QEvent *event); - void resizeEvent(QResizeEvent *event); - void resetDropDownButtons(); - void updateText(); - - protected slots: // Protected slots - /** - * Is called when the return key was presed in the textbox. - */ - void slotReturnPressed(); - - void slotClearRef(); - - void slotUpdateLock(); - void slotUpdateUnlock(); - void slotStepBook(int); - void slotStepChapter(int); - void slotStepVerse(int); - void slotChangeBook(QString bookname); - void slotChangeChapter(int chapter); - void slotChangeVerse(int verse); - - private: - friend class CLexiconKeyChooser; - friend class BtDropdownChooserButton; - friend class BtBookDropdownChooserButton; - friend class BtChapterDropdownChooserButton; - friend class BtVerseDropdownChooserButton; - - CSwordVerseKey *m_key; - - QLineEdit* m_textbox; - - CScrollerWidgetSet *m_bookScroller; - CScrollerWidgetSet *m_chapterScroller; - CScrollerWidgetSet *m_verseScroller; - - QWidget *m_dropDownButtons; - QTimer m_dropDownHoverTimer; - BtDropdownChooserButton* m_bookDropdownButton; - BtDropdownChooserButton* m_chapterDropdownButton; - BtDropdownChooserButton* m_verseDropdownButton; - - bool updatelock; - QString oldKey; - CSwordBibleModuleInfo *m_module; -}; - -#endif diff --git a/src/frontend/mainindex/bookmarks/btbookmarkfolder.cpp b/src/frontend/mainindex/bookmarks/btbookmarkfolder.cpp deleted file mode 100644 index 2091a54..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkfolder.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/mainindex/bookmarks/btbookmarkfolder.h" - -#include -#include -#include "frontend/mainindex/bookmarks/btbookmarkitembase.h" -#include "frontend/mainindex/bookmarks/btbookmarkitem.h" -#include "frontend/mainindex/bookmarks/btbookmarkloader.h" -#include "util/cresmgr.h" -#include "util/directory.h" - - -BtBookmarkFolder::BtBookmarkFolder(QTreeWidgetItem* parent, QString name) - : BtBookmarkItemBase(parent) { - setText(0, name); - setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); -} - -bool BtBookmarkFolder::enableAction(MenuAction action) { - if (action == ChangeFolder || action == NewFolder || action == DeleteEntries || action == ImportBookmarks ) - return true; - if (action == ExportBookmarks || action == ImportBookmarks ) - return true; - if ((action == PrintBookmarks) && childCount()) - return true; - return false; -} - -void BtBookmarkFolder::exportBookmarks() { - QString filter = QObject::tr("BibleTime bookmark files") + QString(" (*.btb);;") + QObject::tr("All files") + QString(" (*.*)"); - QString fileName = QFileDialog::getSaveFileName(0, QObject::tr("Export Bookmarks"), "", filter); - - if (!fileName.isEmpty()) { - qDebug() << "exportBookmarks()"; - BtBookmarkLoader loader; - loader.saveTreeFromRootItem(this, fileName, false ); //false: don't overwrite without asking - }; - -} - -void BtBookmarkFolder::importBookmarks() { - QString filter = QObject::tr("BibleTime bookmark files") + QString(" (*.btb);;") + QObject::tr("All files") + QString(" (*.*)"); - QString fileName = QFileDialog::getOpenFileName(0, QObject::tr("Import bookmarks"), "", filter); - if (!fileName.isEmpty()) { - qDebug() << "import bookmarks"; - BtBookmarkLoader loader; - QList itemList = loader.loadTree(fileName); - this->insertChildren(0, itemList); - }; -} - -QString BtBookmarkFolder::toolTip() { - return QString(); -} - -void BtBookmarkFolder::newSubFolder() { - if (dynamic_cast(this)) { - BtBookmarkFolder* f = new BtBookmarkFolder(this, QObject::tr("New folder")); - - treeWidget()->setCurrentItem(f); - f->update(); - f->rename(); - } -} - -QList BtBookmarkFolder::getChildList() const { - QList list; - for (int i = 0; i < childCount(); i++) { - list.append(child(i)); - } - return list; -} - -void BtBookmarkFolder::rename() { - treeWidget()->editItem(this); -} - -void BtBookmarkFolder::update() { - namespace DU = util::directory; - - qDebug() << "BtBookmarkFolder::update()"; - BtBookmarkItemBase::update(); - if (isExpanded() && childCount()) - setIcon(0, DU::getIcon(CResMgr::mainIndex::openedFolder::icon)); - else - setIcon(0, DU::getIcon(CResMgr::mainIndex::closedFolder::icon)); -} - -bool BtBookmarkFolder::hasDescendant(QTreeWidgetItem* item) const { - qDebug() << "BtBookmarkFolder::hasDescendant, this:" << this << "possible descendant:" << item; - - if (this == item) { - qDebug() << "it's this, return true"; - return true; - } - if (getChildList().indexOf(item) > -1) { - qDebug() << "direct child, return true"; - return true; - } - foreach(QTreeWidgetItem* childItem, getChildList()) { - bool subresult = false; - BtBookmarkFolder* folder = 0; - if ( (folder = dynamic_cast(childItem)) ) { - subresult = folder->hasDescendant(childItem); - } - - if (subresult == true) { - qDebug() << "descendand child, return true"; - return true; - } - } - qDebug() << "no child, return false"; - return false; -} - -BtBookmarkFolder* BtBookmarkFolder::deepCopy() { - qDebug() << "BtBookmarkFolder::deepCopy"; - BtBookmarkFolder* newFolder = new BtBookmarkFolder(0, this->text(0)); - foreach(QTreeWidgetItem* subitem, getChildList()) { - if (BtBookmarkItem* bmItem = dynamic_cast(subitem)) { - newFolder->addChild(new BtBookmarkItem(*bmItem)); - } - else { - if (BtBookmarkFolder* bmFolder = dynamic_cast(subitem)) { - newFolder->addChild(bmFolder->deepCopy()); - } - } - } - newFolder->update(); - return newFolder; -} - diff --git a/src/frontend/mainindex/bookmarks/btbookmarkfolder.h b/src/frontend/mainindex/bookmarks/btbookmarkfolder.h deleted file mode 100644 index 9f065f4..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkfolder.h +++ /dev/null @@ -1,50 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BTBOOKMARKFOLDER_H -#define BTBOOKMARKFOLDER_H - -#include "frontend/mainindex/bookmarks/btbookmarkitembase.h" - - -#define CURRENT_SYNTAX_VERSION 1 - -class BtBookmarkFolder : public BtBookmarkItemBase { - public: - friend class BtBookmarkLoader; - BtBookmarkFolder(QTreeWidgetItem* parent, QString name); - ~BtBookmarkFolder() {} - - /** See the base class. */ - virtual bool enableAction(const MenuAction action); - - /** User gives a file from which to load items into this folder. */ - virtual void exportBookmarks(); - /** User gives a file to which items from this folder are saved. */ - virtual void importBookmarks(); - - /** Creates a new folder under this. */ - void newSubFolder(); - - /** Returns a list of direct childs of this item. */ - QList getChildList() const; - - /** Returns true if the given item is this or a direct or indirect subitem of this. */ - bool hasDescendant(QTreeWidgetItem* item) const; - - /** Creates a deep copy of this item. */ - BtBookmarkFolder* deepCopy(); - - void rename(); - void update(); - - QString toolTip(); -}; - -#endif diff --git a/src/frontend/mainindex/bookmarks/btbookmarkitem.cpp b/src/frontend/mainindex/bookmarks/btbookmarkitem.cpp deleted file mode 100644 index 40dc79e..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkitem.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/mainindex/bookmarks/btbookmarkitem.h" - -#include -#include -#include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/keys/cswordversekey.h" -#include "frontend/cinputdialog.h" -#include "frontend/mainindex/bookmarks/btbookmarkfolder.h" -#include "util/cpointers.h" -#include "util/cresmgr.h" -#include "util/directory.h" - - -BtBookmarkItem::BtBookmarkItem(CSwordModuleInfo* module, QString key, QString& description) - : m_description(description), - m_moduleName(module ? module->name() : QString::null) { - if (((module && (module->type() == CSwordModuleInfo::Bible)) || (module->type() == CSwordModuleInfo::Commentary)) ) { - CSwordVerseKey vk(0); - vk.key(key); - vk.setLocale("en"); - m_key = vk.key(); //the m_key member is always the english key! - } - else { - m_key = key; - }; - - update(); -} - -BtBookmarkItem::BtBookmarkItem(QTreeWidgetItem* parent) - : BtBookmarkItemBase(parent) {} - -BtBookmarkItem::BtBookmarkItem(const BtBookmarkItem& other) - : BtBookmarkItemBase(0), - m_key(other.m_key), - m_description(other.m_description), - m_moduleName(other.m_moduleName) { - update(); -} - -CSwordModuleInfo* BtBookmarkItem::module() { - CSwordModuleInfo* const m = CPointers::backend()->findModuleByName(m_moduleName); - return m; -} - -QString BtBookmarkItem::key() { - const QString englishKeyName = englishKey(); - if (!module()) { - return englishKeyName; - } - - QString returnKeyName = englishKeyName; - if ((module()->type() == CSwordModuleInfo::Bible) || (module()->type() == CSwordModuleInfo::Commentary)) { - CSwordVerseKey vk(0); - vk.key(englishKeyName); - vk.setLocale(CPointers::backend()->booknameLanguage().toLatin1() ); - - returnKeyName = vk.key(); //the returned key is always in the currently set bookname language - } - - return returnKeyName; -} - -const QString& BtBookmarkItem::description() { - return m_description; -} - -void BtBookmarkItem::setDescription(QString text) { - m_description = text; -} - -QString BtBookmarkItem::toolTip() { - if (!module()) { - return QString::null; - } - - CSwordBackend::FilterOptions filterOptions = CBTConfig::getFilterOptionDefaults(); - filterOptions.footnotes = false; - filterOptions.scriptureReferences = false; - CPointers::backend()->setFilterOptions(filterOptions); - - QString ret; - boost::scoped_ptr k( CSwordKey::createInstance(module()) ); - k->key(this->key()); - - const CLanguageMgr::Language* lang = module()->language(); - CBTConfig::FontSettingsPair fontPair = CBTConfig::get - (lang); - - Q_ASSERT(k.get()); - if (fontPair.first) { //use a special font - ret = QString::fromLatin1("%1 (%2)
    %3") - .arg(key()) - .arg(module()->name()) - .arg(description()) - ; - } - else { - ret = QString::fromLatin1("%1 (%2)
    %3") - .arg(key()) - .arg(module()->name()) - .arg(description()) - ; - } - - return ret; -} - -bool BtBookmarkItem::enableAction(MenuAction action) { - if (action == ChangeBookmark || (module() && (action == PrintBookmarks)) || action == DeleteEntries) - return true; - - return false; -} - -void BtBookmarkItem::rename() { - bool ok = false; - const QString newDescription = CInputDialog::getText(QObject::tr("Change description ..."), QObject::tr("Enter a new description for the chosen bookmark."), description(), &ok, treeWidget()); - - if (ok) { - m_description = newDescription; - update(); - } -} - -QString BtBookmarkItem::englishKey() const { - return m_key; -} - -void BtBookmarkItem::update() { - namespace DU = util::directory; - - qDebug() << "BtBookmarkItem::update"; - setIcon(0, DU::getIcon(CResMgr::mainIndex::bookmark::icon)); - - const QString title = QString::fromLatin1("%1 (%2)").arg(key()).arg(module() ? module()->name() : QObject::tr("unknown")); - setText(0, title); - setToolTip(0, toolTip()); -} - diff --git a/src/frontend/mainindex/bookmarks/btbookmarkitem.h b/src/frontend/mainindex/bookmarks/btbookmarkitem.h deleted file mode 100644 index 6677f61..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkitem.h +++ /dev/null @@ -1,66 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BTBOOKMARKITEM_H -#define BTBOOKMARKITEM_H - -#include "frontend/mainindex/bookmarks/btbookmarkitembase.h" - -#include - - -class BtBookmarkFolder; -class CSwordModuleInfo; - -class BtBookmarkItem : public BtBookmarkItemBase { - public: - friend class BtBookmarkLoader; - - BtBookmarkItem(QTreeWidgetItem* parent); - - /** Creates a bookmark with module, key and description. */ - BtBookmarkItem(CSwordModuleInfo* module, QString key, QString& description); - - /** Creates a copy. */ - BtBookmarkItem(const BtBookmarkItem& other); - - ~BtBookmarkItem() {} - - /** Returns the used module, 0 if there is no such module. */ - CSwordModuleInfo* module(); - - /** Returns the used key. */ - QString key(); - - /** Returns the used description. */ - const QString& description(); - /** Sets the description text for this bookmark. */ - virtual void setDescription(QString text); - - /** Returns a tooltip for this bookmark. */ - virtual QString toolTip(); - - /** Returns whether the action is supported by this item. */ - virtual bool enableAction(MenuAction action); - - /** Changes this bookmark. */ - virtual void rename(); - - void update(); - - private: - /** Returns the english key.*/ - QString englishKey() const; - - QString m_key; - QString m_description; - QString m_moduleName; -}; - -#endif diff --git a/src/frontend/mainindex/bookmarks/btbookmarkitembase.cpp b/src/frontend/mainindex/bookmarks/btbookmarkitembase.cpp deleted file mode 100644 index 82241ce..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkitembase.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/mainindex/bookmarks/btbookmarkitembase.h" - -#include -#include -#include "frontend/mainindex/bookmarks/cbookmarkindex.h" - - -BtBookmarkItemBase::BtBookmarkItemBase() {} - -BtBookmarkItemBase::BtBookmarkItemBase(QTreeWidgetItem* parent) - : QTreeWidgetItem(parent) {} - -CBookmarkIndex* BtBookmarkItemBase::bookmarkWidget() const { - return dynamic_cast(treeWidget()); -} - -// void BtBookmarkItemBase::dropped(QDropEvent* e) -// { -// -// } -// -// void BtBookmarkItemBase::addPreviousSibling(BtBookmarkItemBase* item) -// { -// -// } -// -// void BtBookmarkItemBase::addNextSibling(BtBookmarkItemBase* item) -// { -// -// } diff --git a/src/frontend/mainindex/bookmarks/btbookmarkitembase.h b/src/frontend/mainindex/bookmarks/btbookmarkitembase.h deleted file mode 100644 index 78754f7..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkitembase.h +++ /dev/null @@ -1,61 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BTBOOKMARKITEMBASE_H -#define BTBOOKMARKITEMBASE_H - -#include - -#include -#include -#include - - -class CBookmarkIndex; - -class BtBookmarkItemBase : public QTreeWidgetItem { - public: - enum MenuAction { - NewFolder = 0, - ChangeFolder, - - ChangeBookmark, - ImportBookmarks, - ExportBookmarks, - PrintBookmarks, - - DeleteEntries, - - ActionBegin = NewFolder, - ActionEnd = DeleteEntries - }; - - /** Where to drop/create item(s): above, below or inside an item.*/ - enum Location {Above, Below, Inside}; - - BtBookmarkItemBase(); - BtBookmarkItemBase(QTreeWidgetItem* parent); - virtual ~BtBookmarkItemBase() {} - - virtual QString toolTip() = 0; - virtual CBookmarkIndex* bookmarkWidget() const; - - /** Returns true if the given action should be enabled in the popup menu. */ - virtual bool enableAction( MenuAction action ) = 0; - - /** Rename the item. */ - virtual void rename() = 0; - - /** Update the item (icon etc.) after creating or changing it. */ - virtual void update() {} - -}; - -#endif - diff --git a/src/frontend/mainindex/bookmarks/btbookmarkloader.cpp b/src/frontend/mainindex/bookmarks/btbookmarkloader.cpp deleted file mode 100644 index ddf656e..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkloader.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/mainindex/bookmarks/btbookmarkloader.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend/drivers/cswordmoduleinfo.h" -#include "frontend/mainindex/bookmarks/btbookmarkitem.h" -#include "frontend/mainindex/bookmarks/btbookmarkfolder.h" -#include "util/tool.h" - - -#define CURRENT_SYNTAX_VERSION 1 - -QList BtBookmarkLoader::loadTree(QString fileName) { - qDebug() << "BtBookmarkLoader::loadTree"; - QList itemList; - - QDomDocument doc; - doc.setContent(loadXmlFromFile(fileName)); - - //bookmarkfolder::loadBookmarksFromXML() - - QDomElement document = doc.documentElement(); - if ( document.tagName() != "SwordBookmarks" ) { - qWarning("Not a BibleTime Bookmark XML file"); - return QList(); - } - - QDomElement child = document.firstChild().toElement(); - - while ( !child.isNull() && child.parentNode() == document) { - qDebug() << "BtBookmarkLoader::loadTree while start"; - QTreeWidgetItem* i = handleXmlElement(child, 0); - itemList.append(i); - if (!child.nextSibling().isNull()) { - child = child.nextSibling().toElement(); - } - else { - child = QDomElement(); //null - } - - } - - return itemList; -} - -QTreeWidgetItem* BtBookmarkLoader::handleXmlElement(QDomElement& element, QTreeWidgetItem* parent) { - qDebug() << "BtBookmarkLoader::handleXmlElement"; - QTreeWidgetItem* newItem = 0; - if (element.tagName() == "Folder") { - qDebug() << "BtBookmarkLoader::handleXmlElement: found folder"; - BtBookmarkFolder* newFolder = new BtBookmarkFolder(parent, QString()); - if (element.hasAttribute("caption")) { - newFolder->setText(0, element.attribute("caption")); - } - QDomNodeList childList = element.childNodes(); - for (unsigned int i = 0; i < childList.length(); i++) { - qDebug() << "BtBookmarkLoader::handleXmlElement: go through child list of folder"; - QDomElement newElement = childList.at(i).toElement(); - QTreeWidgetItem* newChildItem = handleXmlElement(newElement, newFolder); - newFolder->addChild(newChildItem); - } - newFolder->update(); - newItem = newFolder; - } - else if (element.tagName() == "Bookmark") { - qDebug() << "BtBookmarkLoader::handleXmlElement: found bookmark"; - BtBookmarkItem* newBookmarkItem = new BtBookmarkItem(parent); - if (element.hasAttribute("modulename")) { - //we use the name in all cases, even if the module isn't installed anymore - newBookmarkItem->m_moduleName = element.attribute("modulename"); - } - if (element.hasAttribute("key")) { - newBookmarkItem->m_key = element.attribute("key"); - } - if (element.hasAttribute("description")) { - newBookmarkItem->m_description = element.attribute("description"); - } - newBookmarkItem->update(); - newItem = newBookmarkItem; - } - qDebug() << "BtBookmarkLoader::handleXmlElement: return new item"; - return newItem; -} - - -QString BtBookmarkLoader::loadXmlFromFile(QString fileName) { - namespace DU = util::directory; - - if (fileName.isNull()) { - fileName = DU::getUserBaseDir().absolutePath() + "/bookmarks.xml"; - } - QFile file(fileName); - if (!file.exists()) - return QString(); - - QString xml; - if (file.open(QIODevice::ReadOnly)) { - QTextStream t; - t.setAutoDetectUnicode(false); - t.setCodec(QTextCodec::codecForName("UTF-8")); - t.setDevice(&file); - xml = t.readAll(); - file.close(); - } - return xml; -} - -void BtBookmarkLoader::saveTreeFromRootItem(QTreeWidgetItem* rootItem, QString fileName, bool forceOverwrite) { - namespace DU = util::directory; - - Q_ASSERT(rootItem); - if (fileName.isNull()) { - fileName = DU::getUserBaseDir().absolutePath() + "/bookmarks.xml"; - } - - QDomDocument doc("DOC"); - doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); - - QDomElement content = doc.createElement("SwordBookmarks"); - content.setAttribute("syntaxVersion", CURRENT_SYNTAX_VERSION); - doc.appendChild(content); - - //append the XML nodes of all child items - - for (int i = 0; i < rootItem->childCount(); i++) { - saveItem(rootItem->child(i), content); - } - util::tool::savePlainFile(fileName, doc.toString(), forceOverwrite, QTextCodec::codecForName("UTF-8")); - -} - -void BtBookmarkLoader::saveItem(QTreeWidgetItem* item, QDomElement& parentElement) { - BtBookmarkFolder* folderItem = 0; - BtBookmarkItem* bookmarkItem = 0; - - if ((folderItem = dynamic_cast(item))) { - QDomElement elem = parentElement.ownerDocument().createElement("Folder"); - elem.setAttribute("caption", folderItem->text(0)); - - parentElement.appendChild(elem); - - for (int i = 0; i < folderItem->childCount(); i++) { - saveItem(folderItem->child(i), elem); - } - } - else if ((bookmarkItem = dynamic_cast(item))) { - QDomElement elem = parentElement.ownerDocument().createElement("Bookmark"); - - elem.setAttribute("key", bookmarkItem->englishKey()); - elem.setAttribute("description", bookmarkItem->description()); - elem.setAttribute("modulename", bookmarkItem->m_moduleName); - elem.setAttribute("moduledescription", bookmarkItem->module() ? bookmarkItem->module()->config(CSwordModuleInfo::Description) : QString::null); - - parentElement.appendChild(elem); - } -} diff --git a/src/frontend/mainindex/bookmarks/btbookmarkloader.h b/src/frontend/mainindex/bookmarks/btbookmarkloader.h deleted file mode 100644 index 3102ca2..0000000 --- a/src/frontend/mainindex/bookmarks/btbookmarkloader.h +++ /dev/null @@ -1,46 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BTBOOKMARKLOADER_H -#define BTBOOKMARKLOADER_H - -#include "util/directory.h" - -#include -#include -#include - - -class QTreeWidgetItem; - -/** -* Class for loading and saving bookmarks. -*/ -class BtBookmarkLoader { - public: - /** Loads a list of items (with subitem trees) from a named file - * or from the default bookmarks file. */ - QList loadTree(QString fileName = QString::null); - - /** Takes one item and saves the tree which is under it to a named file - * or to the default bookmarks file, asking the user about overwriting if necessary. */ - void saveTreeFromRootItem(QTreeWidgetItem* rootItem, QString fileName = QString::null, bool forceOverwrite = true); - - private: - /** Create a new item from a document element. */ - QTreeWidgetItem* handleXmlElement(QDomElement& element, QTreeWidgetItem* parent); - - /** Writes one item to a document element. */ - void saveItem(QTreeWidgetItem* item, QDomElement& parentElement); - - /** Loads a bookmark XML document from a named file or from the default bookmarks file. */ - QString loadXmlFromFile(QString fileName = QString::null); -}; - -#endif diff --git a/src/frontend/mainindex/bookmarks/cbookmarkindex.cpp b/src/frontend/mainindex/bookmarks/cbookmarkindex.cpp deleted file mode 100644 index 1f88125..0000000 --- a/src/frontend/mainindex/bookmarks/cbookmarkindex.cpp +++ /dev/null @@ -1,895 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/mainindex/bookmarks/cbookmarkindex.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend/config/cbtconfig.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/referencemanager.h" -#include "frontend/cdragdrop.h" -#include "frontend/cinfodisplay.h" -#include "frontend/cprinter.h" -#include "frontend/mainindex/bookmarks/btbookmarkitembase.h" -#include "frontend/mainindex/bookmarks/btbookmarkitem.h" -#include "frontend/mainindex/bookmarks/btbookmarkfolder.h" -#include "frontend/mainindex/bookmarks/btbookmarkloader.h" -#include "frontend/searchdialog/csearchdialog.h" -#include "util/cresmgr.h" -#include "util/tool.h" -#include "util/directory.h" -#include "util/dialogutil.h" - - -CBookmarkIndex::CBookmarkIndex(QWidget *parent) - : QTreeWidget(parent), - m_magTimer(this), - m_previousEventItem(0) { - setMouseTracking(true); - m_magTimer.setSingleShot(true); - m_magTimer.setInterval(CBTConfig::get(CBTConfig::magDelay)); - setContextMenuPolicy(Qt::CustomContextMenu); - initView(); - initConnections(); - initTree(); -} - -CBookmarkIndex::~CBookmarkIndex() { - saveBookmarks(); -} - - -/** Initializes the view. */ -void CBookmarkIndex::initView() { - //qDebug() << "CBookmarkIndex::initView"; - - header()->hide(); - - setFocusPolicy(Qt::WheelFocus); - - //d'n'd related settings - setDragEnabled( true ); - setAcceptDrops( true ); - setDragDropMode(QAbstractItemView::DragDrop); - viewport()->setAcceptDrops(true); - setAutoScroll(true); - setAutoExpandDelay(800); - - setItemsExpandable(true); - setRootIsDecorated(true); - setAllColumnsShowFocus(true); - setSelectionMode(QAbstractItemView::ExtendedSelection); - - //setup the popup menu - m_popup = new QMenu(viewport()); - m_popup->setTitle(tr("Bookmarks")); - - m_actions.newFolder = newQAction(tr("New folder"), CResMgr::mainIndex::newFolder::icon, 0, this, SLOT(createNewFolder()), this); - m_actions.changeFolder = newQAction(tr("Rename folder"), CResMgr::mainIndex::changeFolder::icon, 0, this, SLOT(changeFolder()), this); - - m_actions.changeBookmark = newQAction(tr("Change bookmark description..."), CResMgr::mainIndex::changeBookmark::icon, 0, this, SLOT(changeBookmark()), this); - m_actions.importBookmarks = newQAction(tr("Import to folder..."), CResMgr::mainIndex::importBookmarks::icon, 0, this, SLOT(importBookmarks()), this); - m_actions.exportBookmarks = newQAction(tr("Export from folder..."), CResMgr::mainIndex::exportBookmarks::icon, 0, this, SLOT(exportBookmarks()), this); - m_actions.printBookmarks = newQAction(tr("Print bookmarks..."), CResMgr::mainIndex::printBookmarks::icon, 0, this, SLOT(printBookmarks()), this); - - m_actions.deleteEntries = newQAction(tr("Remove selected items..."), CResMgr::mainIndex::deleteItems::icon, 0, this, SLOT(deleteEntries()), this); - - - //fill the popup menu itself - m_popup->addAction(m_actions.newFolder); - m_popup->addAction(m_actions.changeFolder); - QAction* separator = new QAction(this); - separator->setSeparator(true); - m_popup->addAction(separator); - m_popup->addAction(m_actions.changeBookmark); - m_popup->addAction(m_actions.importBookmarks); - m_popup->addAction(m_actions.exportBookmarks); - m_popup->addAction(m_actions.printBookmarks); - separator = new QAction(this); - separator->setSeparator(true); - m_popup->addAction(separator); - m_popup->addAction(m_actions.deleteEntries); - - m_bookmarksModified = false; - //qDebug() << "CBookmarkIndex::initView end"; -} - -/** Convenience function for creating a new QAction. -* Should be replaced with something better; it was easier to make a new function -* than to modify all QAction constructors. -*/ -QAction* CBookmarkIndex::newQAction(const QString& text, const QString& pix, const int /*shortcut*/, const QObject* receiver, const char* slot, QObject* parent) { - namespace DU = util::directory; - QAction* action = new QAction(DU::getIcon(pix), text, parent); - QObject::connect(action, SIGNAL(triggered()), receiver, slot); - return action; -} - -/** Initialize the SIGNAL<->SLOT connections */ -void CBookmarkIndex::initConnections() { - //qDebug() << "CBookmarkIndex::initConnections"; - bool ok; - ok = connect(this, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(slotExecuted(QTreeWidgetItem*))); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), - SLOT(contextMenu(const QPoint&))); - Q_ASSERT(ok); - ok = connect(&m_magTimer, SIGNAL(timeout()), this, SLOT(magTimeout())); - Q_ASSERT(ok); - ok = connect(this, SIGNAL(itemEntered(QTreeWidgetItem*, int)), this, SLOT(slotItemEntered(QTreeWidgetItem*, int)) ); - Q_ASSERT(ok); - - // Connection to detect changes in the items themselves (e.g. renames, - // description changes) so that we can consider saving the bookmarks. - connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(needToSaveBookmarks(QTreeWidgetItem*)) ); - - // Connect the bookmark saving timer. - bookmarkSaveTimer.setSingleShot(true); - connect(&bookmarkSaveTimer, SIGNAL(timeout()), this, SLOT(considerSavingBookmarks()) ); -} - - -/** -* Hack to get single click and selection working. See slotExecuted. -*/ -void CBookmarkIndex::mouseReleaseEvent(QMouseEvent* event) { - //qDebug() << "CBookmarkIndex::mouseReleaseEvent"; - m_mouseReleaseEventModifiers = event->modifiers(); - QTreeWidget::mouseReleaseEvent(event); -} - -/** Called when an item is clicked with mouse or activated with keyboard. */ -void CBookmarkIndex::slotExecuted( QTreeWidgetItem* i ) { - qDebug() << "CBookmarkIndex::slotExecuted"; - - //HACK: checking the modifier keys from the last mouseReleaseEvent - //depends on executing order: mouseReleaseEvent first, then itemClicked signal - int modifiers = m_mouseReleaseEventModifiers; - m_mouseReleaseEventModifiers = Qt::NoModifier; - if (modifiers != Qt::NoModifier) { - return; - } - - BtBookmarkItemBase* btItem = dynamic_cast(i); - if (!btItem) { - return; - } - - BtBookmarkFolder* folderItem = 0; - BtBookmarkItem* bookmarkItem = 0; - if ((folderItem = dynamic_cast(btItem))) { - i->setExpanded( !i->isExpanded() ); - } - else if (( bookmarkItem = dynamic_cast(btItem) )) { //clicked on a bookmark - if (CSwordModuleInfo* mod = bookmarkItem->module()) { - QList modules; - modules.append(mod); - emit createReadDisplayWindow(modules, bookmarkItem->key()); - } - } -} - -/** Creates a drag mime data object for the current selection. */ -QMimeData* CBookmarkIndex::dragObject() { - BTMimeData::ItemList dndItems; - BTMimeData* mimeData = new BTMimeData; - - foreach( QTreeWidgetItem* widgetItem, selectedItems() ) { - if (!widgetItem) - break; - if (dynamic_cast(widgetItem)) { - if (BtBookmarkItem* bookmark = dynamic_cast( widgetItem )) { - //take care of bookmarks which have no valid module any more, e.g. if it was uninstalled - const QString moduleName = bookmark->module() ? bookmark->module()->name() : QString::null; - mimeData->appendBookmark(moduleName, bookmark->key(), bookmark->description()); - } - } - } - return mimeData; -} - -void CBookmarkIndex::dragEnterEvent( QDragEnterEvent* event ) { - //qDebug() << "CBookmarkIndex::dragEnterEvent"; - setState(QAbstractItemView::DraggingState); - QTreeWidget::dragEnterEvent(event); - if (event->source() == this || event->mimeData()->hasFormat("BibleTime/Bookmark")) { - event->acceptProposedAction(); - } -} - - -void CBookmarkIndex::dragMoveEvent( QDragMoveEvent* event ) { - //qDebug() << "CBookmarkIndex::dragMoveEvent"; - - // do this first, otherwise the event may be ignored - QTreeWidget::dragMoveEvent(event); - - event->acceptProposedAction(); - event->accept(); - - // do this to paint the arrow - m_dragMovementPosition = event->pos(); - viewport()->update(); - -} - -void CBookmarkIndex::dragLeaveEvent( QDragLeaveEvent* ) { - qDebug() << "CBookmarkIndex::dragLeaveEvent"; - setState(QAbstractItemView::NoState); // not dragging anymore - viewport()->update(); // clear the arrow -} - - -void CBookmarkIndex::paintEvent(QPaintEvent* event) { - namespace DU = util::directory; - - static QPixmap pix; - static int halfPixHeight; - static bool arrowInitialized = false; - - // Initialize the static variables, including the arrow pixmap - if (!arrowInitialized) { - arrowInitialized = true; - int arrowSize = util::tool::mWidth(this, 1); - QString fileName; - if (DU::getIconDir().exists("pointing_arrow.svg")) { - fileName = DU::getIconDir().filePath("pointing_arrow.svg"); - } - else { - if (DU::getIconDir().exists("pointing_arrow.png")) { - fileName = DU::getIconDir().filePath("pointing_arrow.png"); - } - else { - qWarning() << "Picture file pointing_arrow.svg or .png not found!"; - } - } - - pix = QPixmap(fileName); - pix = pix.scaled(arrowSize, arrowSize, Qt::KeepAspectRatioByExpanding); - halfPixHeight = pix.height() / 2; - } - - // Do the normal painting first - QTreeWidget::paintEvent(event); - - // Paint the arrow if the drag is going on - if (QAbstractItemView::DraggingState == state()) { - bool rtol = QApplication::isRightToLeft(); - - QPainter painter(this->viewport()); - QTreeWidgetItem* item = itemAt(m_dragMovementPosition); - bool isFolder = dynamic_cast(item); - bool isBookmark = dynamic_cast(item); - - // Find the place for the arrow - QRect rect = visualItemRect(item); - int xCoord = rtol ? rect.right() : rect.left(); - int yCoord; - if (isFolder) { - if (m_dragMovementPosition.y() > rect.bottom() - (2* rect.height() / 3) ) { - yCoord = rect.bottom() - halfPixHeight; // bottom - xCoord = rtol ? (xCoord - indentation()) : (xCoord + indentation()); - } - else { - yCoord = rect.top() - halfPixHeight - 1; // top - } - - } - else { - if (isBookmark) { - if (m_dragMovementPosition.y() > rect.bottom() - rect.height() / 2) { - yCoord = rect.bottom() - halfPixHeight; // bottom - } - else { - yCoord = rect.top() - halfPixHeight - 1; // top - } - } - else { - if (item) { // the extra item - yCoord = rect.top() - halfPixHeight - 1; - } - else { // empty area - rect = visualItemRect(m_extraItem); - yCoord = rect.top() - halfPixHeight - 1; - xCoord = rtol ? rect.right() : rect.left(); - } - } - } - - painter.drawPixmap(xCoord, yCoord, pix); - } -} - - -void CBookmarkIndex::dropEvent( QDropEvent* event ) { - qDebug() << "CBookmarkIndex::dropEvent"; - - //setState(QAbstractItemView::NoState); - // Try to prevent annoying timed autocollapsing. Remember to disconnect before return. - QObject::connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); - QTreeWidgetItem* item = itemAt(event->pos()); - QTreeWidgetItem* parentItem = 0; - int indexUnderParent = 0; - - // Find the place where the drag is dropped - if (item) { - qDebug() << "there was item"; - - QRect rect = visualItemRect(item); - bool isFolder = dynamic_cast(item); - bool isBookmark = dynamic_cast(item); - - if (isFolder) { // item is a folder - qDebug() << "item was folder"; - if (event->pos().y() > rect.bottom() - (2* rect.height() / 3) ) { - parentItem = item; - } - else { - parentItem = item->parent(); - if (!parentItem) { - parentItem = invisibleRootItem(); - } - qDebug() << "item:" << item << "parent:" << parentItem; - indexUnderParent = parentItem->indexOfChild(item); // before the current folder - } - } - else { - if (isBookmark) { // item is a bookmark - qDebug() << "item was bookmark"; - parentItem = item->parent(); - if (!parentItem) { - parentItem = invisibleRootItem(); - } - indexUnderParent = parentItem->indexOfChild(item); // before the current bookmark - if (event->pos().y() > rect.bottom() - rect.height() / 2) { - indexUnderParent++; // after the current bookmark - } - } - else { // item is the extra item - parentItem = item->parent(); - if (!parentItem) { - parentItem = invisibleRootItem(); - } - indexUnderParent = parentItem->indexOfChild(item); // before the current bookmark - } - } - - } - else { // no item under event point: drop to the end - qDebug() << "there was no item"; - parentItem = invisibleRootItem(); - indexUnderParent = parentItem->childCount() - 1; - } - - - if ( event->source() == this ) { - qDebug() << "dropping internal drag"; - event->accept(); - - bool bookmarksOnly = true; - bool targetIncluded = false; - bool moreThanOneFolder = false; - - QList newItems = addItemsToDropTree(parentItem, bookmarksOnly, targetIncluded, moreThanOneFolder); - - if (moreThanOneFolder) { - QToolTip::showText(QCursor::pos(), tr("Can drop only bookmarks or one folder")); - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); - return; - } - if (targetIncluded) { - QToolTip::showText(QCursor::pos(), tr("Can't drop folder into the folder itself or into its subfolder")); - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); - return; - } - // Ask whether to copy or move with a popup menu - - QMenu* dropPopupMenu = new QMenu(this); - QAction* copy = dropPopupMenu->addAction(tr("Copy")); - QAction* move = dropPopupMenu->addAction(tr("Move")); - QAction* dropAction = dropPopupMenu->exec(QCursor::pos()); - if (dropAction == copy) { - qDebug() << "copy"; - parentItem->insertChildren(indexUnderParent, newItems); - // Need this here because the "move" case goes through - // "deleteEntries" which has a save call. - needToSaveBookmarks(); - } - else { - if (dropAction == move) { - qDebug() << "move"; - parentItem->insertChildren(indexUnderParent, newItems); - deleteEntries(false); - } - else { - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), - this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); - return; // user canceled - } - } - } - else { - qDebug() << "the source was outside this"; - createBookmarkFromDrop(event, parentItem, indexUnderParent); - } - QObject::disconnect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)), this, SLOT(expandAutoCollapsedItem(QTreeWidgetItem*))); - setState(QAbstractItemView::NoState); -} - - -void CBookmarkIndex::createBookmarkFromDrop(QDropEvent* event, QTreeWidgetItem* parentItem, int indexInParent) { - //qDebug() << "CBookmarkIndex::createBookmarkFromDrop"; - //take the bookmark data from the mime source - const BTMimeData* mdata = dynamic_cast(event->mimeData()); - if (mdata) { - //create the new bookmark - QString moduleName = mdata->bookmark().module(); - QString keyText = mdata->bookmark().key(); - QString description = mdata->bookmark().description(); - CSwordModuleInfo* minfo = CPointers::backend()->findModuleByName(moduleName); - - QTreeWidgetItem* newItem = new BtBookmarkItem(minfo, keyText, description); - // connect(newItem, SIGNAL(bookmarkModified()), this, SLOT(needToSaveBookmarks()) ); - parentItem->insertChild(indexInParent, newItem); - - qDebug() << "Saving in...CBookmarkIndex::createBookmarkFromDrop"; - needToSaveBookmarks(); - } -} - - -/** Load the tree from file */ -void CBookmarkIndex::initTree() { - qDebug() << "CBookmarkIndex::initTree"; - BtBookmarkLoader loader; - addTopLevelItems(loader.loadTree()); - - // add the invisible extra item at the end - m_extraItem = new QTreeWidgetItem(); - m_extraItem->setFlags(Qt::ItemIsDropEnabled); - addTopLevelItem(m_extraItem); -} - -void CBookmarkIndex::slotItemEntered(QTreeWidgetItem* item, int) { - qDebug() << "CBookmarkIndex::slotItemEntered"; - if (item == m_extraItem) { - m_extraItem->setText(0, tr("Drag references from text views to this view")); - } - else { - m_extraItem->setText(0, QString::null); - } -} - - -/** Returns the correct QAction object for the given type of action. */ -QAction* CBookmarkIndex::action( BtBookmarkItemBase::MenuAction type ) const { - switch (type) { - case BtBookmarkItemBase::NewFolder: - return m_actions.newFolder; - case BtBookmarkItemBase::ChangeFolder: - return m_actions.changeFolder; - - case BtBookmarkItemBase::ChangeBookmark: - return m_actions.changeBookmark; - case BtBookmarkItemBase::ImportBookmarks: - return m_actions.importBookmarks; - case BtBookmarkItemBase::ExportBookmarks: - return m_actions.exportBookmarks; - case BtBookmarkItemBase::PrintBookmarks: - return m_actions.printBookmarks; - - case BtBookmarkItemBase::DeleteEntries: - return m_actions.deleteEntries; - - default: - return 0; - } -} - -/** Shows the context menu at the given position. */ -void CBookmarkIndex::contextMenu(const QPoint& p) { - //qDebug() << "CBookmarkIndex::contextMenu"; - //setup menu entries depending on current selection - QTreeWidgetItem* i = itemAt(p); - QList items = selectedItems(); - //The item which was clicked may not be selected - if (i && !items.contains(i) && i != m_extraItem) - items.append(i); - - if (items.count() == 0) { - //special handling for no selection - BtBookmarkItemBase::MenuAction actionType; - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast(index); - if (QAction* a = action(actionType)) { - switch (index) { - //case BtBookmarkItemBase::ExportBookmarks: - //case BtBookmarkItemBase::ImportBookmarks: - case BtBookmarkItemBase::NewFolder: - //case BtBookmarkItemBase::PrintBookmarks: - a->setEnabled(true); - break; - default: - a->setEnabled(false); - } - } - } - } - else if (items.count() == 1) { - //special handling for one selected item - - BtBookmarkItemBase* item = dynamic_cast(items.at(0)); - BtBookmarkItemBase::MenuAction actionType; - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast(index); - if (QAction* a = action(actionType)) - a->setEnabled( item->enableAction(actionType) ); - } - } - else { - //first disable all actions - BtBookmarkItemBase::MenuAction actionType; - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast(index); - if (QAction* a = action(actionType)) - a->setEnabled(false); - } - //enable the menu items depending on the types of the selected items. - for (int index = BtBookmarkItemBase::ActionBegin; index <= BtBookmarkItemBase::ActionEnd; ++index) { - actionType = static_cast(index); - bool enableAction = isMultiAction(actionType); - QListIterator it(items); - while (it.hasNext()) { - BtBookmarkItemBase* i = dynamic_cast(it.next()); - enableAction = enableAction && i->enableAction(actionType); - } - if (enableAction) { - QAction* a = action(actionType) ; - if (i && a) - a->setEnabled(enableAction); - } - } - } - //finally, open the popup - m_popup->exec(mapToGlobal(p)); - //qDebug() << "CBookmarkIndex::contextMenu end"; -} - -/** Adds a new subfolder to the current item. */ -void CBookmarkIndex::createNewFolder() { - //qDebug() << "CBookmarkIndex::createNewFolder"; - QList selected = selectedItems(); - if (selected.count() > 0) { - BtBookmarkFolder* i = dynamic_cast(currentItem()); - if (i) { - i->newSubFolder(); - } - } - else { - // create a top level folder - BtBookmarkFolder* newFolder = new BtBookmarkFolder(0, QObject::tr("New folder")); - //parentFolder->addChild(newFolder); - insertTopLevelItem(topLevelItemCount() - 1, newFolder); - newFolder->update(); - newFolder->rename(); - } - needToSaveBookmarks(); -} - -/** Opens a dialog to change the current folder. */ -void CBookmarkIndex::changeFolder() { - BtBookmarkFolder* i = dynamic_cast(currentItem()); - Q_ASSERT(i); - if (i) { - i->rename(); - } -} - -/** Changes the current bookmark. */ -void CBookmarkIndex::changeBookmark() { - BtBookmarkItem* i = dynamic_cast(currentItem()); - Q_ASSERT(i); - - if (i) { - i->rename(); - } -} - -/** Exports the bookmarks being in the selected folder. */ -void CBookmarkIndex::exportBookmarks() { - BtBookmarkFolder* i = dynamic_cast(currentItem()); - Q_ASSERT(i); - - if (i) { - i->exportBookmarks(); - } -} - -/** Import bookmarks from a file and add them to the selected folder. */ -void CBookmarkIndex::importBookmarks() { - BtBookmarkFolder* i = dynamic_cast(currentItem()); - Q_ASSERT(i); - - if (i) { - i->importBookmarks(); - } - needToSaveBookmarks(); -} - -/** Prints the selected bookmarks. */ -void CBookmarkIndex::printBookmarks() { - Printing::CPrinter::KeyTree tree; - Printing::CPrinter::KeyTreeItem::Settings settings; - settings.keyRenderingFace = Printing::CPrinter::KeyTreeItem::Settings::CompleteShort; - - QList items; - BtBookmarkFolder* bf = dynamic_cast(currentItem()); - - if (bf) { - items = bf->getChildList(); - } - else { - items = selectedItems(); - } - - //create a tree of keytreeitems using the bookmark hierarchy. - QListIterator it(items); - while (it.hasNext()) { - BtBookmarkItem* i = dynamic_cast(it.next()); - if (i) { - qDebug() << "printBookmarks: add to list" << i->key(); - tree.append( new Printing::CPrinter::KeyTreeItem( i->key(), i->module(), settings ) ); - } - } - - if (items.count() == 0) { - qWarning("Tried to print empty bookmark list."); - return; - } - boost::scoped_ptr printer( - new Printing::CPrinter( this, CBTConfig::getDisplayOptionDefaults(), CBTConfig::getFilterOptionDefaults() ) - ); - printer->printKeyTree(tree); -} - -/** Deletes the selected entries. */ -void CBookmarkIndex::deleteEntries(bool confirm) { - if (confirm) { - if (!selectedItems().count()) { - BtBookmarkItemBase* f = dynamic_cast(currentItem()); - if (f) { - currentItem()->setSelected(true); - } - else { - return; - } - } - - if (util::showQuestion(this, tr("Delete Items"), - tr("Do you really want to delete the selected items and child-items?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) - != QMessageBox::Yes) { - return; - } - } - - while (selectedItems().size() > 0) { - delete selectedItems().at(0); // deleting all does not work because it may cause double deletion - } - // Save the bookmarks. One way would be to signal that the bookmarks have - // changed emit a signal so that a number of changes may be saved at once. - // Another way is to simply save the bookmarks after each change, which can - // be inefficient. - needToSaveBookmarks(); -} - - -/* -Reimplementation from QAbstractItemView/QTreeWidget. Takes care of movable items. -It's easier to use this than to start drag with mouse event handlers. -The default implementation would drag items, but we don't call it. Instead we create -a BibleTime mimedata object. It can be dragged and dropped to a text view or somewhere else. -The internal drag is handled differently, it doesn't use the mimedata (see dropEvent()). -*/ -void CBookmarkIndex::startDrag(Qt::DropActions) { - qDebug() << "CBookmarkIndex::startDrag"; - - QMimeData* mData = dragObject(); // create the data which can be used in other widgets - QDrag* drag = new QDrag(this); - drag->setMimeData(mData); - drag->exec(); - - viewport()->update(); // because of the arrow -} - - - - - - -/* Returns true if more than one entry is supported by this action type. Returns false for actions which support only one entry, e.g. about module etc. */ -bool CBookmarkIndex::isMultiAction( const BtBookmarkItemBase::MenuAction type ) const { - switch (type) { - case BtBookmarkItemBase::NewFolder: - return false; - case BtBookmarkItemBase::ChangeFolder: - return false; - - case BtBookmarkItemBase::ChangeBookmark: - return false; - case BtBookmarkItemBase::ImportBookmarks: - return false; - case BtBookmarkItemBase::ExportBookmarks: - return false; - case BtBookmarkItemBase::PrintBookmarks: - return true; - - case BtBookmarkItemBase::DeleteEntries: - return true; - } - - return false; -} - -/* Saves the bookmarks to the default bookmarks file. */ -void CBookmarkIndex::saveBookmarks() { - - qDebug() << "CBookmarkIndex::saveBookmarks()"; - BtBookmarkLoader loader; - loader.saveTreeFromRootItem(invisibleRootItem()); -} - -void CBookmarkIndex::mouseMoveEvent(QMouseEvent* event) { - //qDebug() << "CBookmarkIndex::mouseMoveEvent"; - - // Restart the mag timer if we have moved to another item and shift was not pressed. - QTreeWidgetItem* itemUnderPointer = itemAt(event->pos()); - if (itemUnderPointer && (itemUnderPointer != m_previousEventItem) ) { - //qDebug() << "CBookmarkIndex::mouseMoveEvent, moved onto another item"; - if ( !(event->modifiers() & Qt::ShiftModifier)) { - m_magTimer.start(); // see the ctor for the timer properties - } - } - m_previousEventItem = itemUnderPointer; - - // Clear the extra item text unless we are on top of it - if ( (itemUnderPointer != m_extraItem) && !m_extraItem->text(0).isNull()) { - m_extraItem->setText(0, QString::null); - } - - QTreeWidget::mouseMoveEvent(event); -} - -void CBookmarkIndex::magTimeout() { - //qDebug() << "CBookmarkIndex::magTimeout"; - - QTreeWidgetItem* itemUnderPointer = 0; - if (underMouse()) { - itemUnderPointer = itemAt(mapFromGlobal(QCursor::pos())); - } - // if the mouse pointer have been over the same item since the timer was started - if (itemUnderPointer && (m_previousEventItem == itemUnderPointer)) { - BtBookmarkItem* bitem = dynamic_cast(itemUnderPointer); - if (bitem) { - //qDebug() << "CBookmarkIndex::timerEvent: update the infodisplay"; - // Update the mag - if (bitem->module()) { - (CPointers::infoDisplay())->setInfo( - InfoDisplay::CInfoDisplay::CrossReference, - bitem->module()->name() + ":" + bitem->key() - ); - } - else { - (CPointers::infoDisplay())->setInfo(InfoDisplay::CInfoDisplay::Text, tr("The work to which the bookmark points to is not installed.")); - } - - } - } -} - -/* -Creates a list of new items based on the current selection. -If there are only bookmarks in the selection they are all included. -If there is one folder it's included as a deep copy. -Sets bookmarksOnly=false if it finds a folder. -Sets targetIncluded=true if the target is in the list. -Sets moreThanOneFolder=true if selection includes one folder and something more. -If moreThanOneFolder or targetIncluded is detected the creation of list is stopped -and the list is incomplete. -*/ -QList CBookmarkIndex::addItemsToDropTree( - QTreeWidgetItem* target, bool& bookmarksOnly, bool& targetIncluded, bool& moreThanOneFolder) { - qDebug() << "CBookmarkIndex::addItemsToDropTree"; - QList selectedList = selectedItems(); - QList newList; - - foreach(QTreeWidgetItem* item, selectedList) { - qDebug() << "go through all items:" << item; - if ( BtBookmarkFolder* folder = dynamic_cast(item)) { - bookmarksOnly = false; - if (selectedList.count() > 1) { // only one item allowed if a folder is selected - qDebug() << "one folder and something else is selected"; - moreThanOneFolder = true; - break; - } - if (folder->hasDescendant(target)) { // dropping to self or descendand not allowed - qDebug() << "addItemsToDropTree: target is included"; - targetIncluded = true; - break; - } - } - else { - qDebug() << "append new QTreeWidget item (should be BtBookmarkItem?)"; - newList.append(new BtBookmarkItem( *(dynamic_cast(item)) )); - } - } - if (!bookmarksOnly && selectedList.count() == 1) { - qDebug() << "exactly one folder"; - BtBookmarkFolder* folder = dynamic_cast(selectedList.value(0)); - BtBookmarkFolder* copy = folder->deepCopy(); - newList.append(copy); - } - if (!bookmarksOnly && selectedList.count() > 1) { - // wrong amount of items - qDebug() << "one folder and something else is selected 2"; - moreThanOneFolder = true; - } - qDebug() << "return the new list" << newList; - return newList; -} - -/// Bookmark saving code. To avoid many saves during a short period of time, -/// bookmark modification is first noted. Then, after a wait (1.5s), if no more -/// modifications are made, the bookmarks are saved. The timer is reset when a -/// new modification is made. The timer bookmarkSaveTimer is set to be oneshot. -void CBookmarkIndex::needToSaveBookmarks() { - qDebug() << "Got signal to save bookmarks!"; - m_bookmarksModified = true; - bookmarkSaveTimer.start(1500); // Only save after 1.5s. -} -void CBookmarkIndex::needToSaveBookmarks(QTreeWidgetItem* treeItem) { - // Need to test whether the item that changed is not just a display item, - // but actually a folder or bookmark. - BtBookmarkItemBase* bookmark = dynamic_cast(treeItem); - if (bookmark) { - qDebug() << "Got signal to save bookmarks!"; - m_bookmarksModified = true; - bookmarkSaveTimer.start(1500); // Only save after 1.5s. - } -} - -/// Considers saving bookmarks only if they have been modified. This procedure -/// should be called by the qtimer bookmarkTimer. -void CBookmarkIndex::considerSavingBookmarks() { - qDebug() << "Considering to save bookmarks!"; - if (m_bookmarksModified) { - saveBookmarks(); - m_bookmarksModified = false; - } -} - diff --git a/src/frontend/mainindex/bookmarks/cbookmarkindex.h b/src/frontend/mainindex/bookmarks/cbookmarkindex.h deleted file mode 100644 index 90f9ab2..0000000 --- a/src/frontend/mainindex/bookmarks/cbookmarkindex.h +++ /dev/null @@ -1,207 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CBOOKMARKINDEX_H -#define CBOOKMARKINDEX_H - -#include "frontend/mainindex/bookmarks/btbookmarkitembase.h" - -#include -#include -#include -#include -#include -#include "frontend/displaywindow/cdisplaywindow.h" -#include "util/cpointers.h" - - -class BTMimeData; -class CSearchDialog; -class CSwordModuleInfo; -class QAction; -class QDragLeaveEvent; -class QDragMoveEvent; -class QDropEvent; -class QMenu; -class QMouseEvent; -class QPaintEvent; -class QWidget; - -/** -* The widget which manages all bookmarks. -* @author The BibleTime team -*/ -class CBookmarkIndex : public QTreeWidget { - Q_OBJECT - public: - CBookmarkIndex(QWidget *parent); - virtual ~CBookmarkIndex(); - - void initTree(); - - /** - * Saves the bookmarks to disk - */ - void saveBookmarks(); - - signals: - /** - * Is emitted when a module should be opened, - */ - void createReadDisplayWindow( QList, const QString& ); - - public slots: - - /** - * Indicates a need to save the bookmarks. - * This is needed to provide a way for a bookmarkitem stored in the - * treeWidget to inform us that it has been modified, namely its - * description text. It only sets a dirty-bit so we don't execute many - * consecutive saves. - */ - void needToSaveBookmarks(); - void needToSaveBookmarks(QTreeWidgetItem* treeItem); - - - protected: // Protected methods - - /** A hack to get the modifiers. */ - virtual void mouseReleaseEvent(QMouseEvent* event); - - /** Needed to paint an drag pointer arrow. */ - virtual void paintEvent(QPaintEvent* event); - - /** Initialize the SIGNAL<->SLOT connections. */ - void initConnections(); - - /** Returns the drag object for the current selection. */ - virtual QMimeData* dragObject(); - - /** - * D'n'd methods are reimplementations from QTreeWidget or its ancestors. - * In these we handle creating, moving and copying bookmarks with d'n'd. - */ - virtual void dragEnterEvent( QDragEnterEvent* event ); - virtual void dragMoveEvent( QDragMoveEvent* event ); - virtual void dropEvent( QDropEvent* event ); - virtual void dragLeaveEvent( QDragLeaveEvent* event ); - - /** Returns the correct action object for the given type of action. */ - QAction* action( BtBookmarkItemBase::MenuAction type ) const; - - /** Reimplementation from QAbstractItemView. Takes care of movable items. */ - virtual void startDrag(Qt::DropActions supportedActions); - - - /** Handle mouse moving (mag updates) */ - virtual void mouseMoveEvent(QMouseEvent* event); - - - protected slots: - - /** Prevents annoying folder collapsing while dropping. */ - void expandAutoCollapsedItem(QTreeWidgetItem* i) { - expandItem(i); - } - - /** Is called when an item was clicked or activated. */ - void slotExecuted( QTreeWidgetItem* ); - - /** Shows the context menu at the given position. */ - void contextMenu(const QPoint&); - - /** Adds a new subfolder to the current item. */ - void createNewFolder(); - - /** Opens a dialog to change the current folder. */ - void changeFolder(); - - /** Exports the bookmarks from the selected folder. */ - void exportBookmarks(); - - /** Changes the current bookmark. */ - void changeBookmark(); - - /** Helps with the extra item. */ - void slotItemEntered(QTreeWidgetItem*, int); - - /** Import bookmarks from a file and add them to the selected folder. */ - void importBookmarks(); - - /** Deletes the selected entries. */ - void deleteEntries(bool confirm = true); - - /** Prints the selected bookmarks. */ - void printBookmarks(); - - /** Slot for the mag update timer. */ - void magTimeout(); - - private: - - /** Initializes the view. */ - void initView(); - - /** Convenience function for creating a new action. */ - QAction* newQAction(const QString& text, const QString& pix, int shortcut, const QObject* receiver, const char* slot, QObject* parent); - - /** - * Returns true if more than one entry is supported by this action type. - * Returns false for actions which support only one entry. - */ - bool isMultiAction( const BtBookmarkItemBase::MenuAction type ) const; - - /** A helper function for d'n'd which creates a new bookmark item when drop happens. */ - void createBookmarkFromDrop(QDropEvent* event, QTreeWidgetItem* parentItem, int indexInParent); - - /** - * Returns a list of new items created from the selection. - * Sets flags which indicate whether the selection was legal for dropping. - */ - QList addItemsToDropTree(QTreeWidgetItem* target, bool& bookmarksOnly, bool& targetIncluded, bool& moreThanOneFolder); - - struct Actions { - QAction* newFolder; - QAction* changeFolder; - - QAction* changeBookmark; - QAction* importBookmarks; - QAction* exportBookmarks; - QAction* printBookmarks; - - QAction* deleteEntries; - } - m_actions; - - QMenu* m_popup; - QTimer m_magTimer; - int m_mouseReleaseEventModifiers; - QTreeWidgetItem* m_previousEventItem; - QPoint m_dragMovementPosition; - QPoint m_dragStartPosition; - QTreeWidgetItem* m_extraItem; - - // The following is for managing saving bookmarks. It uses a QTimer to - // determine whether the bookmarks should be saved. This may seem like - // a hassle, but it is to prevent many saves from being executed at a - // time. - - /** Flag indicating that bookmarks have been modified. */ - bool m_bookmarksModified; - QTimer bookmarkSaveTimer; - - private slots: - /** - * Saves the bookmarks. - * It checks m_bookmarksModified and resets it at the end. It should be - * connected to a timer that periodically calls this. */ - void considerSavingBookmarks(); -}; - -#endif diff --git a/src/frontend/mainindex/btbookshelfview.cpp b/src/frontend/mainindex/btbookshelfview.cpp deleted file mode 100644 index 60b10d1..0000000 --- a/src/frontend/mainindex/btbookshelfview.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License -* version 2.0. -* -**********/ - -#include "frontend/mainindex/btbookshelfview.h" - -#include -#include -#include -#include "backend/bookshelfmodel/btbookshelftreemodel.h" -#include "backend/drivers/cswordmoduleinfo.h" - - -BtBookshelfView::BtBookshelfView(QWidget *parent) - : QTreeView(parent) { - header()->hide(); - - /* - Uncommenting the following statement will hide the [+]expand/[-]collapse - controls in front of first-level items, which might not be desirable since - hiding them also means that one has to do a total of 2 clicks (double- - click)to expand or collapse top-level items: - */ - // setRootIsDecorated(false); - - connect(this, SIGNAL(activated(QModelIndex)), - this, SLOT(slotItemActivated(QModelIndex))); -} - -BtBookshelfView::~BtBookshelfView() { - // Intentionally empty -} - -CSwordModuleInfo *BtBookshelfView::getModule(const QModelIndex &index) const { - return (CSwordModuleInfo *) model() - ->data(index, BtBookshelfModel::ModulePointerRole).value(); -} - -void BtBookshelfView::keyPressEvent(QKeyEvent *event) { - switch (event->key()) { - case Qt::Key_Menu: - scrollTo(currentIndex()); - { - CSwordModuleInfo *i(getModule(currentIndex())); - QRect itemRect(visualRect(currentIndex())); - QPoint p(viewport()->mapToGlobal(itemRect.bottomLeft())); - if (i == 0) { - emit contextMenuActivated(p); - } - else { - emit moduleContextMenuActivated(i, p); - } - } - event->accept(); - break; - case Qt::Key_Return: - case Qt::Key_Enter: { - QModelIndex i(currentIndex()); - CSwordModuleInfo *m(getModule(i)); - if (m != 0) { - emit moduleActivated(m); - } - else { - setExpanded(i, !isExpanded(i)); - } - } - event->accept(); - break; - default: - QTreeView::keyPressEvent(event); - break; - } -} - -void BtBookshelfView::mousePressEvent(QMouseEvent *event) { - if (event->buttons() == Qt::RightButton) { - QModelIndex clickedItemIndex(indexAt(event->pos())); - if (clickedItemIndex.isValid()) { - setCurrentIndex(clickedItemIndex); - } - CSwordModuleInfo *i(getModule(clickedItemIndex)); - if (i == 0) { - emit contextMenuActivated(mapToGlobal(event->pos())); - } - else { - emit moduleContextMenuActivated(i, mapToGlobal(event->pos())); - } - event->accept(); - } - else { - QTreeView::mousePressEvent(event); - } -} - -void BtBookshelfView::slotItemActivated(const QModelIndex &index) { - CSwordModuleInfo *i(getModule(index)); - if (i != 0) { - emit moduleActivated(i); - } -} diff --git a/src/frontend/mainindex/btbookshelfview.h b/src/frontend/mainindex/btbookshelfview.h deleted file mode 100644 index b91d60f..0000000 --- a/src/frontend/mainindex/btbookshelfview.h +++ /dev/null @@ -1,43 +0,0 @@ -/********* -* -* In the name of the Father, and of the Son, and of the Holy Spirit. -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License -* version 2.0. -* -**********/ - -#ifndef BTBOOKSHELFVIEW_H -#define BTBOOKSHELFVIEW_H - -#include - - -class CSwordModuleInfo; - -class BtBookshelfView: public QTreeView { - Q_OBJECT - public: - BtBookshelfView(QWidget *parent = 0); - virtual ~BtBookshelfView(); - - CSwordModuleInfo *getModule(const QModelIndex &index) const; - - signals: - void contextMenuActivated(QPoint pos); - void moduleContextMenuActivated(CSwordModuleInfo *item, - QPoint pos); - void moduleActivated(CSwordModuleInfo *item); - - protected: - void keyPressEvent(QKeyEvent *event); - void mousePressEvent(QMouseEvent *event); - - protected slots: - void slotItemActivated(const QModelIndex &index); -}; - -#endif // BTBOOKSHELFVIEW_H diff --git a/src/frontend/profile/cprofile.cpp b/src/frontend/profile/cprofile.cpp index 34f397b..e36c227 100644 --- a/src/frontend/profile/cprofile.cpp +++ b/src/frontend/profile/cprofile.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/profile/cprofile.h b/src/frontend/profile/cprofile.h index 621167e..8acffd3 100644 --- a/src/frontend/profile/cprofile.h +++ b/src/frontend/profile/cprofile.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/profile/cprofilemgr.cpp b/src/frontend/profile/cprofilemgr.cpp index 279a562..99e7823 100644 --- a/src/frontend/profile/cprofilemgr.cpp +++ b/src/frontend/profile/cprofilemgr.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -48,7 +48,7 @@ const QList& CProfileMgr::profiles() { } /** Creates a new profile with the name "name" (first parameter). @return The profile object */ -CProfile* CProfileMgr::create( const QString name ) { +CProfile *CProfileMgr::create(const QString &name) { CProfile* p = new CProfile(QString::null, name); m_profiles.append(p); diff --git a/src/frontend/profile/cprofilemgr.h b/src/frontend/profile/cprofilemgr.h index 462ce93..7f5edcf 100644 --- a/src/frontend/profile/cprofilemgr.h +++ b/src/frontend/profile/cprofilemgr.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -28,7 +28,7 @@ class CProfileMgr { /** Creates a new profile with the name "name" (first parameter). * @return The profile object */ - CProfile* create( const QString name ); + CProfile *create(const QString &name); /** * @return a list of available profiles */ diff --git a/src/frontend/profile/cprofilewindow.cpp b/src/frontend/profile/cprofilewindow.cpp index bfeabc8..4f8fab9 100644 --- a/src/frontend/profile/cprofilewindow.cpp +++ b/src/frontend/profile/cprofilewindow.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/profile/cprofilewindow.h b/src/frontend/profile/cprofilewindow.h index 74294f7..f9c144f 100644 --- a/src/frontend/profile/cprofilewindow.h +++ b/src/frontend/profile/cprofilewindow.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp b/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp index e638130..ece0ced 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,11 +26,14 @@ namespace Search { static const int DIALOG_HEIGHT = 400; static const int DIALOG_BORDER = 30; -CSearchAnalysisDialog::CSearchAnalysisDialog( QList modules, QWidget* parentDialog ) - : QDialog(parentDialog) { +CSearchAnalysisDialog::CSearchAnalysisDialog( + const CSwordModuleSearch::Results &results, + QWidget *parentDialog) + : QDialog(parentDialog) +{ initView(); m_analysis->reset(); - m_analysis->analyse(modules); + m_analysis->analyse(results); // Set initial width based on the search data, but limit to the // width of the desktop @@ -39,7 +42,6 @@ CSearchAnalysisDialog::CSearchAnalysisDialog( QList modules, if (width > desktopWidth) width = desktopWidth; resize(width, DIALOG_HEIGHT); - } /** Initializes this dialog. */ @@ -49,7 +51,7 @@ void CSearchAnalysisDialog::initView() { m_analysis = new CSearchAnalysisScene(this); m_analysisView = new CSearchAnalysisView(m_analysis, this); -//// m_analysisView->show(); +//// m_analysisView->show(); vboxLayout->addWidget(m_analysisView); m_buttonBox = new QDialogButtonBox(this); diff --git a/src/frontend/searchdialog/analysis/csearchanalysisdialog.h b/src/frontend/searchdialog/analysis/csearchanalysisdialog.h index 4bff4a0..b4edcad 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisdialog.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,7 +12,10 @@ #include -#include +#include "backend/cswordmodulesearch.h" + +// Sword includes +#include class CSwordModuleInfo; @@ -25,13 +28,13 @@ class CSearchAnalysisView; class CSearchAnalysisScene; /** - @author The BibleTime team + @author The BibleTime team */ class CSearchAnalysisDialog : public QDialog { Q_OBJECT public: - CSearchAnalysisDialog(QList modules, QWidget* parentDialog); - ~CSearchAnalysisDialog() {} + CSearchAnalysisDialog(const CSwordModuleSearch::Results &results, + QWidget *parentDialog = 0); protected: // Protected methods /** diff --git a/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp b/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp index b2fc1ad..23b2962 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisitem.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -41,13 +41,17 @@ const int LEGEND_INNER_BORDER = 5; const int LEGEND_DELTAY = 4; const int LEGEND_WIDTH = 85; -CSearchAnalysisItem::CSearchAnalysisItem(const int moduleCount, const QString &bookname, double *scaleFactor, QList* modules) - : QGraphicsRectItem(), - m_moduleList( modules ), - m_scaleFactor(scaleFactor), - m_bookName(bookname), - m_moduleCount(moduleCount), - m_bufferPixmap(0) { +CSearchAnalysisItem::CSearchAnalysisItem( + const int moduleCount, + const QString &bookname, + double *scaleFactor, + const CSwordModuleSearch::Results &results) + : m_results(results), + m_scaleFactor(scaleFactor), + m_bookName(bookname), + m_moduleCount(moduleCount), + m_bufferPixmap(0) +{ m_resultCountArray.resize(m_moduleCount); int index = 0; for (index = 0; index < m_moduleCount; ++index) m_resultCountArray[index] = 0; @@ -137,23 +141,27 @@ int CSearchAnalysisItem::width() { /** Returns the tooltip for this item. */ const QString CSearchAnalysisItem::getToolTip() { + typedef CSwordModuleSearch::Results::const_iterator RCI; + QString toolTipString = QString("
    %1

    ").arg(m_bookName); toolTipString += ""; /// \todo Fix that loop int i = 0; - QList::iterator end_it = m_moduleList->end(); + for (RCI it = m_results.begin(); it != m_results.end(); it++) { + const CSwordModuleInfo *info = it.key(); + + /// \warning This is a workaround for sword constness + sword::ListKey &results = const_cast(it.value()); - for (QList::iterator it(m_moduleList->begin()); it != end_it; ++it) { - CSwordModuleInfo* info = (*it); const QColor c = CSearchAnalysisScene::getColor(i); toolTipString.append( - QString("") - .arg(QString().sprintf("%02X%02X%02X", c.red(), c.green(), c.blue())) + QString("") + .arg(c.name()) .arg(info ? info->name() : QString::null) .arg( m_resultCountArray[i] ) - .arg( (info && m_resultCountArray[i]) ? ((double)m_resultCountArray[i] / (double)info->searchResult().Count())*(double)100 : 0.0, 0, 'g', 2) + .arg( (info && m_resultCountArray[i]) ? ((double)m_resultCountArray[i] / (double)results.Count())*(double)100 : 0.0, 0, 'g', 2) ); ++i; } diff --git a/src/frontend/searchdialog/analysis/csearchanalysisitem.h b/src/frontend/searchdialog/analysis/csearchanalysisitem.h index d5a46a9..7db96a9 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisitem.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisitem.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -13,19 +13,19 @@ #include #include +#include "backend/cswordmodulesearch.h" class CSwordModuleInfo; namespace Search { -/** - @author The BibleTime team -*/ class CSearchAnalysisItem : public QGraphicsRectItem { public: + CSearchAnalysisItem(const int moduleCount, const QString &bookname, + double *scaleFactor, + const CSwordModuleSearch::Results &results); - CSearchAnalysisItem(const int moduleCount, const QString& bookname, double *scaleFactor, QList* modules); ~CSearchAnalysisItem(); /** * Sets the resultcount of this item @@ -52,7 +52,8 @@ class CSearchAnalysisItem : public QGraphicsRectItem { private: virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*); - QList* m_moduleList; + private: /* Fields: */ + CSwordModuleSearch::Results m_results; double *m_scaleFactor; QString m_bookName; int m_moduleCount; diff --git a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp index 38b6552..c5b9d02 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -39,12 +39,6 @@ const int LEGEND_DELTAY = 4; const int LEGEND_WIDTH = 85; -CSearchAnalysisLegendItem::CSearchAnalysisLegendItem(QList *list ) - : QGraphicsRectItem() { - m_moduleList = list; -} - -/** Reimplementation. Draws the content of this item. */ void CSearchAnalysisLegendItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) { painter->save(); @@ -61,8 +55,7 @@ void CSearchAnalysisLegendItem::paint(QPainter* painter, const QStyleOptionGraph // for (unsigned int index=0; index < m_moduleList->count(); index++){ int moduleIndex = 0; - QList::iterator end_it = m_moduleList->end(); - for (QList::iterator it(m_moduleList->begin()); it != end_it; ++it) { + Q_FOREACH(const CSwordModuleInfo *m, m_moduleList) { // the module color indicators QPoint p1( (int)(rect().x()) + LEGEND_INNER_BORDER, (int)(rect().y()) + LEGEND_INNER_BORDER + moduleIndex*(LEGEND_DELTAY + ITEM_TEXT_SIZE) ); QPoint p2(p1.x() + ITEM_TEXT_SIZE, p1.y() + ITEM_TEXT_SIZE); @@ -72,7 +65,7 @@ void CSearchAnalysisLegendItem::paint(QPainter* painter, const QStyleOptionGraph painter->drawRect(r); QPoint p3( p2.x() + LEGEND_INNER_BORDER, p2.y() ); - painter->drawText(p3, (*it)->name() ); + painter->drawText(p3, m->name() ); ++moduleIndex; } diff --git a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h index b3110eb..232fe64 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h +++ b/src/frontend/searchdialog/analysis/csearchanalysislegenditem.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,19 +17,20 @@ class CSwordModuleInfo; namespace Search { -/** - @author The BibleTime team -*/ class CSearchAnalysisLegendItem : public QGraphicsRectItem { - public: - CSearchAnalysisLegendItem(QList* list ); + public: /* Methods: */ + inline CSearchAnalysisLegendItem(const QList &modules) + : m_moduleList(modules) {} - private: + private: /* Methods: */ + /** Reimplementation of QGraphicsItem::paint. */ virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*); - QList* m_moduleList; + + private: /* Fields: */ + QList m_moduleList; }; -} +} // namespace Search #endif diff --git a/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp b/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp index 6d486a8..e4165ab 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisscene.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -51,14 +51,12 @@ CSearchAnalysisScene::CSearchAnalysisScene(QObject *parent ) setSceneRect(0, 0, 1, 1); } - -QHash* CSearchAnalysisScene::getSearchAnalysisItemList() { - // Returns pointer to the search analysis items - return &m_itemList; -} - /** Starts the analysis of the search result. This should be called only once because QCanvas handles the updates automatically. */ -void CSearchAnalysisScene::analyse(QList modules) { +void CSearchAnalysisScene::analyse( + const CSwordModuleSearch::Results &results) +{ + typedef CSwordModuleSearch::Results::const_iterator RCI; + /** * Steps of analysing our search result; * -Create the items for all available books ("Genesis" - "Revelation") @@ -67,13 +65,13 @@ void CSearchAnalysisScene::analyse(QList modules) { * -Find out how many times we found the book * -Set the count to the items which belongs to the book */ - setModules(modules); + setResults(results); m_lastPosList.clear(); - const int numberOfModules = m_moduleList.count(); + const int numberOfModules = m_results.count(); if (!numberOfModules) return; - m_legend = new CSearchAnalysisLegendItem(&m_moduleList); + m_legend = new CSearchAnalysisLegendItem(m_results.keys()); addItem(m_legend); m_legend->setRect(LEFT_BORDER, UPPER_BORDER, LEGEND_WIDTH, LEGEND_INNER_BORDER*2 + ITEM_TEXT_SIZE*numberOfModules + LEGEND_DELTAY*(numberOfModules - 1) ); @@ -84,20 +82,19 @@ void CSearchAnalysisScene::analyse(QList modules) { m_maxCount = 0; int count = 0; CSwordVerseKey key(0); - key.key("Genesis 1:1"); + key.setKey("Genesis 1:1"); CSearchAnalysisItem* analysisItem = m_itemList[key.book()]; bool ok = true; while (ok && analysisItem) { moduleIndex = 0; - QList::iterator end_it = m_moduleList.end(); - for (QList::iterator it(m_moduleList.begin()); it != end_it; ++it) { + for (RCI it = m_results.begin(); it != m_results.end(); it++) { qApp->processEvents( QEventLoop::AllEvents ); - if (!m_lastPosList.contains(*it)) { - m_lastPosList.insert(*it, 0); + if (!m_lastPosList.contains(it.key())) { + m_lastPosList.insert(it.key(), 0); } - analysisItem->setCountForModule(moduleIndex, (count = getCount(key.book(), *it))); + analysisItem->setCountForModule(moduleIndex, (count = getCount(key.book(), it.key()))); m_maxCount = (count > m_maxCount) ? count : m_maxCount; ++moduleIndex; @@ -112,25 +109,30 @@ void CSearchAnalysisScene::analyse(QList modules) { ok = key.next(CSwordVerseKey::UseBook); analysisItem = m_itemList[key.book()]; } - setSceneRect(0, 0, xPos + BAR_WIDTH + (m_moduleList.count() - 1)*BAR_DELTAX + RIGHT_BORDER, height() ); + setSceneRect(0, 0, xPos + BAR_WIDTH + (m_results.count() - 1)*BAR_DELTAX + RIGHT_BORDER, height() ); slotResized(); } /** Sets the module list used for the analysis. */ -void CSearchAnalysisScene::setModules(QList modules) { - m_moduleList.clear(); - foreach (CSwordModuleInfo * mod, modules) { - if ( (mod->type() == CSwordModuleInfo::Bible) || (mod->type() == CSwordModuleInfo::Commentary) ) { //a Bible or an commentary - m_moduleList.append(mod); +void CSearchAnalysisScene::setResults( + const CSwordModuleSearch::Results &results) +{ + typedef CSwordModuleSearch::Results::const_iterator RCI; + + m_results.clear(); + for (RCI it = results.begin(); it != results.end(); it++) { + const CSwordModuleInfo *m = it.key(); + if ( (m->type() == CSwordModuleInfo::Bible) || (m->type() == CSwordModuleInfo::Commentary) ) { //a Bible or an commentary + m_results.insert(m, it.value()); } } m_itemList.clear(); CSearchAnalysisItem* analysisItem = 0; CSwordVerseKey key(0); - key.key("Genesis 1:1"); + key.setKey("Genesis 1:1"); do { - analysisItem = new CSearchAnalysisItem(m_moduleList.count(), key.book(), &m_scaleFactor, &m_moduleList); + analysisItem = new CSearchAnalysisItem(m_results.count(), key.book(), &m_scaleFactor, m_results); addItem(analysisItem); analysisItem->hide(); m_itemList.insert(key.book(), analysisItem); @@ -160,13 +162,13 @@ void CSearchAnalysisScene::reset() { /** No descriptions */ void CSearchAnalysisScene::slotResized() { - m_scaleFactor = (double)( (double)(height() - UPPER_BORDER - LOWER_BORDER - BAR_LOWER_BORDER - 100 - (m_moduleList.count() - 1) * BAR_DELTAY) + m_scaleFactor = (double)( (double)(height() - UPPER_BORDER - LOWER_BORDER - BAR_LOWER_BORDER - 100 - (m_results.count() - 1) * BAR_DELTAY) / (double)m_maxCount); QHashIterator it( m_itemList ); while ( it.hasNext() ) { it.next(); if (it.value()) { - it.value()->setRect(it.value()->rect().x(), UPPER_BORDER, BAR_WIDTH + (m_moduleList.count() - 1)*BAR_DELTAX, height() - LOWER_BORDER - BAR_LOWER_BORDER); + it.value()->setRect(it.value()->rect().x(), UPPER_BORDER, BAR_WIDTH + (m_results.count() - 1)*BAR_DELTAX, height() - LOWER_BORDER - BAR_LOWER_BORDER); } } update(); @@ -200,9 +202,12 @@ QColor CSearchAnalysisScene::getColor(int index) { } } -/** Returns the count of the book in the module */ -unsigned int CSearchAnalysisScene::getCount( const QString book, CSwordModuleInfo* module ) { - sword::ListKey& result = module->searchResult(); +unsigned int CSearchAnalysisScene::getCount(const QString &book, + const CSwordModuleInfo* module) +{ + /// \warning This is a workaround for sword constness + sword::ListKey result = m_results[module]; + const int length = book.length(); unsigned int i = m_lastPosList[module]; unsigned int count = 0; @@ -218,6 +223,8 @@ unsigned int CSearchAnalysisScene::getCount( const QString book, CSwordModuleInf } void CSearchAnalysisScene::saveAsHTML() { + typedef CSwordModuleSearch::Results::const_iterator RCI; + const QString fileName = QFileDialog::getSaveFileName(0, tr("Save Search Analysis"), QString::null, tr("HTML files (*.html;*.HTML;*.HTM;*.htm)") ); if (fileName.isEmpty()) return; @@ -230,9 +237,8 @@ void CSearchAnalysisScene::saveAsHTML() { const QString txtCSS = QString("\n"); const QString metaEncoding = QString(""); CSwordVerseKey key(0); - sword::ListKey searchResult; - key.key("Genesis 1:1"); + key.setKey("Genesis 1:1"); CSearchAnalysisItem* analysisItem = m_itemList.value( key.book() ); @@ -242,9 +248,12 @@ void CSearchAnalysisScene::saveAsHTML() { tableTitle = ""; tableTotals = ""; - foreach (CSwordModuleInfo* mod, m_moduleList) { + for (RCI it = m_results.begin(); it != m_results.end(); it++) { + const CSwordModuleInfo *mod = it.key(); tableTitle += QString(""); - searchResult = mod->searchResult(); + + /// \warning This is a workaround for sword constness + sword::ListKey searchResult = it.value(); countStr.setNum(searchResult.Count()); tableTotals += QString(""); @@ -259,8 +268,7 @@ void CSearchAnalysisScene::saveAsHTML() { analysisItem = m_itemList.value( key.book() ); int moduleIndex = 0; - QList::iterator end_it = m_moduleList.end(); - for (QList::iterator it(m_moduleList.begin()); it != end_it; ++it) { + for (RCI it = m_results.begin(); it != m_results.end(); it++) { count = analysisItem->getCountForModule(moduleIndex); countStr.setNum(count); m_searchAnalysisHTML += QString(""); diff --git a/src/frontend/searchdialog/analysis/csearchanalysisscene.h b/src/frontend/searchdialog/analysis/csearchanalysisscene.h index 2a4f171..a3a1832 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisscene.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisscene.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,8 +15,12 @@ #include #include #include +#include "backend/cswordmodulesearch.h" #include "frontend/searchdialog/analysis/csearchanalysisitem.h" +// Sword includes +#include + class CSwordModuleInfo; @@ -39,16 +43,14 @@ class CSearchAnalysisScene : public QGraphicsScene { * This should be called only once because * QCanvas handles the updates automatically. */ - void analyse(QList modules); + void analyse(const CSwordModuleSearch::Results &results); + /** * This function returns a color for each module * @return The color at position index in the list */ static QColor getColor(int index); - /** - * This function returns a pointer to the list of AnalysisItems - */ - QHash* getSearchAnalysisItemList(); + void reset(); /** * resize the height of the scene @@ -65,17 +67,17 @@ class CSearchAnalysisScene : public QGraphicsScene { void slotResized(); protected: - void setModules(QList modules); + void setResults(const CSwordModuleSearch::Results &results); private: /** * Returns the count of the book in the module */ - unsigned int getCount( const QString book, CSwordModuleInfo* module ); + unsigned int getCount(const QString &book, const CSwordModuleInfo *module); - QList m_moduleList; + CSwordModuleSearch::Results m_results; QHash m_itemList; - QMap m_lastPosList; + QMap m_lastPosList; int m_maxCount; double m_scaleFactor; CSearchAnalysisLegendItem* m_legend; diff --git a/src/frontend/searchdialog/analysis/csearchanalysisview.cpp b/src/frontend/searchdialog/analysis/csearchanalysisview.cpp index 7efa604..d177f63 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisview.cpp +++ b/src/frontend/searchdialog/analysis/csearchanalysisview.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/analysis/csearchanalysisview.h b/src/frontend/searchdialog/analysis/csearchanalysisview.h index e66fc57..8d8c5f3 100644 --- a/src/frontend/searchdialog/analysis/csearchanalysisview.h +++ b/src/frontend/searchdialog/analysis/csearchanalysisview.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,7 +22,7 @@ namespace Search { class CSearchAnalysisScene; /** - @author The BibleTime team + @author The BibleTime team */ class CSearchAnalysisView : public QGraphicsView { public: @@ -31,10 +31,10 @@ class CSearchAnalysisView : public QGraphicsView { ~CSearchAnalysisView() {} /** - * Returns the sizeHint for this view - * We give back the size of the parent widgetas default. - * This is a reimplementation from QCanvasView::sizeHint(). - */ + * Returns the sizeHint for this view + * We give back the size of the parent widgetas default. + * This is a reimplementation from QCanvasView::sizeHint(). + */ virtual QSize sizeHint() const; /** diff --git a/src/frontend/searchdialog/btsearchmodulechooserdialog.cpp b/src/frontend/searchdialog/btsearchmodulechooserdialog.cpp new file mode 100644 index 0000000..1d5f556 --- /dev/null +++ b/src/frontend/searchdialog/btsearchmodulechooserdialog.cpp @@ -0,0 +1,58 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#include "frontend/searchdialog/btsearchmodulechooserdialog.h" + +#include +#include +#include "backend/bookshelfmodel/btbookshelftreemodel.h" +#include "backend/managers/cswordbackend.h" +#include "util/tool.h" + + +namespace { +const QString groupingOrderKey("GUI/SearchDialog/ModuleChooserDialog/grouping"); +} + +BtSearchModuleChooserDialog::BtSearchModuleChooserDialog(QWidget *parent, + Qt::WindowFlags flags) + : BtModuleChooserDialog(parent, flags) +{ + // Initialize the tree model: + BtBookshelfTreeModel::Grouping grouping(groupingOrderKey); + BtBookshelfTreeModel *treeModel = new BtBookshelfTreeModel(grouping, this); + treeModel->setCheckable(true); + connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)), + this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&))); + + // Initialize the bookshelf widget: + bookshelfWidget()->showHideAction()->setVisible(false); + bookshelfWidget()->showHideButton()->hide(); + bookshelfWidget()->setTreeModel(treeModel); + bookshelfWidget()->setSourceModel(CSwordBackend::instance()->model()); + + retranslateUi(); +} + +BtSearchModuleChooserDialog::~BtSearchModuleChooserDialog() { + // Intentionally empty +} + +void BtSearchModuleChooserDialog::retranslateUi() { + setWindowTitle(tr("Works to Search in")); + util::tool::initExplanationLabel(label(), QString::null, + tr("Select the works which should be searched.")); +} + +void BtSearchModuleChooserDialog::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) { + g.saveTo(groupingOrderKey); +} diff --git a/src/frontend/searchdialog/btsearchmodulechooserdialog.h b/src/frontend/searchdialog/btsearchmodulechooserdialog.h new file mode 100644 index 0000000..103682c --- /dev/null +++ b/src/frontend/searchdialog/btsearchmodulechooserdialog.h @@ -0,0 +1,45 @@ +/********* +* +* In the name of the Father, and of the Son, and of the Holy Spirit. +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License +* version 2.0. +* +**********/ + +#ifndef BTSEARCHMODULECHOOSERDIALOG_H +#define BTSEARCHMODULECHOOSERDIALOG_H + +#include "frontend/btmodulechooserdialog.h" + +#include "backend/bookshelfmodel/btbookshelftreemodel.h" + + +class BtBookshelfTreeModel; +class CSwordModuleInfo; + +class BtSearchModuleChooserDialog: public BtModuleChooserDialog { + Q_OBJECT + public: + BtSearchModuleChooserDialog(QWidget *parent = 0, + Qt::WindowFlags flags = 0); + ~BtSearchModuleChooserDialog(); + + inline void setCheckedModules(const QSet &modules) { + bookshelfWidget()->treeModel()->setCheckedModules(modules); + } + inline const QSet &checkedModules() const { + return bookshelfWidget()->treeModel()->checkedModules(); + } + + protected slots: + void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g); + + protected: + void retranslateUi(); +}; + +#endif // BTSEARCHMODULECHOOSERDIALOG_H diff --git a/src/frontend/searchdialog/btsearchoptionsarea.cpp b/src/frontend/searchdialog/btsearchoptionsarea.cpp index 95c9218..9f76b6b 100644 --- a/src/frontend/searchdialog/btsearchoptionsarea.cpp +++ b/src/frontend/searchdialog/btsearchoptionsarea.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -19,12 +19,12 @@ #include #include #include +#include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "backend/config/cbtconfig.h" #include "backend/drivers/cswordmoduleinfo.h" -#include "frontend/htmldialogs/bttabhtmldialog.h" +#include "frontend/searchdialog/btsearchmodulechooserdialog.h" +#include "frontend/searchdialog/btsearchsyntaxhelpdialog.h" #include "frontend/searchdialog/crangechooserdialog.h" -#include "frontend/searchdialog/csearchmodulechooserdialog.h" -#include "util/cpointers.h" #include "util/cresmgr.h" #include "util/tool.h" #include "util/directory.h" @@ -204,15 +204,15 @@ void BtSearchOptionsArea::initConnections() { } /** Sets the modules used by the search. */ -void BtSearchOptionsArea::setModules( QList modules ) { +void BtSearchOptionsArea::setModules(const QList &modules) { qDebug() << "BtSearchOptionsArea::setModules"; qDebug() << modules; QString t; m_modules.clear(); //remove old modules - QList::iterator end_it = modules.end(); + QList::const_iterator end_it = modules.end(); - for (QList::iterator it(modules.begin()); it != end_it; ++it) { + for (QList::const_iterator it(modules.begin()); it != end_it; ++it) { /// \todo Check for containsRef compat if (*it == 0) { //don't operate on null modules. continue; @@ -256,24 +256,30 @@ void BtSearchOptionsArea::moduleListTextSelected(int index) { QString text = m_modulesCombo->itemText(index); qDebug() << text; QStringList moduleNamesList = text.split(", "); - QList moduleList; + QList moduleList; foreach(QString name, moduleNamesList) { - moduleList.append(CPointers::backend()->findModuleByName(name)); + moduleList.append(CSwordBackend::instance()->findModuleByName(name)); } //set the list and the combobox list and text setModules(moduleList); } void BtSearchOptionsArea::chooseModules() { - QString title(tr("Works to Search in")); - QString label(tr("Select the works which should be searched.")); - CSearchModuleChooserDialog* dlg = new CSearchModuleChooserDialog(this, title, label, modules()); - connect(dlg, SIGNAL(modulesChanged(QList, QTreeWidget*)), this, SLOT(setModules(QList))); - dlg->exec(); -} + BtSearchModuleChooserDialog* dlg = new BtSearchModuleChooserDialog(this); + QSet ms; + Q_FOREACH (const CSwordModuleInfo *module, modules()) { + ms.insert(const_cast(module)); + } -QList BtSearchOptionsArea::modules() const { - return m_modules; + dlg->setCheckedModules(ms); + if (dlg->exec() == QDialog::Accepted) { + QList ms; + Q_FOREACH(const CSwordModuleInfo *m, dlg->checkedModules()) { + ms.append(m); + } + setModules(ms); + } + delete dlg; } void BtSearchOptionsArea::reset() { @@ -333,108 +339,8 @@ void BtSearchOptionsArea::setupRanges() { } void BtSearchOptionsArea::syntaxHelp() { - - QString style = QString( - ""); - - //: Don't translate words inside <> tags! - //: Translate 'All words' etc. indentically to the Search dialog options. - QString intro = tr( - "

    " - "This help is mainly for 'Full syntax' option. 'All words' and 'Some words' options " "have more limited syntax; wildcards and text fields are supported for them. Some other syntax features " "may give strange or wrong results with All words/Some words." - "

    "); - - QString links = tr( - ""); - - //: Syntax words (AND, OR...) must not be translated. - QString whichwords = tr( - "

    Which words to find

    " - "

    Search terms are separated by spaces. AND (all words), " "OR (some words) and NOT (not the following word) " "can be added between the words. If none is added explicitly OR is used " "automatically. '+word' means the word must be in the results, " "'-word' means it must not be in the results.

    "); - - //: In examples words to be searched for may be translated, but syntax words (AND, OR...) must not be translated. - QString whichwordstable = tr( - "

    %2%3 (%4%)
    %2%3 (%4%)
    " + tr("Book") + "
    " + tr("Total hits") + "") + mod->name() + QString("") + countStr + QString("") + countStr + QString("
    " - "" - "" - "" - "" - "" - "" - "" - "
    jesus AND godFinds verses with both 'Jesus' and 'God'
    jesus OR godFinds verses with 'Jesus' or 'God' or both
    jesus NOT godFinds verses with 'Jesus' but with no 'God'
    +jesus -godFinds verses with 'Jesus' but with no 'God'

    "); - - QString grouping = tr( - "

    Grouping and order

    " - "

    Words can be grouped with parenthesis. " - "Strict word order can be defined with quotes.

    "); - - QString groupingtable = tr( - "

    " - "" - "" - "" - "" - "" - "
    (a AND b) OR cFinds verses with both 'a' AND 'b', and verses with 'c'
    \"says lord\"Finds e.g. '...Isaiah says, \"Lord...' but not '...says the LORD'
    \"says the lord\"Finds all verses with 'says the LORD'

    "); - - QString wildcards = tr( - "

    Wildcards (partial words)

    " - "

    '*' matches any sequence of 0 or more characters, while '?' matches any single character. A wildcard can not be used in the beginning of a word.

    "); - - QString wildcardstable = tr( - "

    " - "" - "" - "" - "" - "" - "" - "" - "
    a*All words beginning with 'a'
    a*a'Assyria', 'aroma', 'abba' etc.
    a?'at' and 'an'
    a??a'abba', 'area', 'Asia' etc.

    "); - - QString fields = tr( - "

    Text fields (different parts of text)

    " - "

    Available text fields:
    " - "" - "" - "" - "
    heading:Searches headings
    footnote:Searches footnotes
    strong:Searches Strong's numbers
    morph:Searches morphology codes

    "); - - QString fieldstable = tr( - "

    Examples:
    " - "" - "" - "" - "" - "
    heading:JesusFinds headings with 'Jesus'
    footnote:Jesus AND footnote:saidFinds footnotes with 'Jesus' and 'said'
    strong:G846Finds verses with Strong's Greek number 846
    morph:\"N-NSF\"Finds verses with morphology code 'N-NSF'

    "); - - QString lucene = tr( - "

    Other syntax features

    " - "

    BibleTime uses the CLucene search engine. You can read more on the lucene syntax web page (in external browser).

    "); - - QString syntax = style + intro + links + whichwords + whichwordstable + - grouping + groupingtable + wildcards + wildcardstable + - fields + fieldstable + lucene; - - BtTabHtmlDialog* dlg = new BtTabHtmlDialog(tr("Search Syntax Help"), 0, this); - dlg->setHtml(syntax); + // The dialog is deleted on close: + BtSearchSyntaxHelpDialog *dlg = new BtSearchSyntaxHelpDialog(this); dlg->show(); } @@ -490,28 +396,28 @@ bool BtSearchOptionsArea::eventFilter(QObject* obj, QEvent* event) { } void BtSearchOptionsArea::slotValidateText(const QString& /*newText*/) { -// static const QRegExp re("\\b(AND|OR)\\b"); -// qDebug() << "new text:" << newText; -// qDebug() << "contains:" << (newText.contains(re)); -// if (newText.isEmpty() || !newText.contains(re) ) { -// qDebug()<< "no AND/OR"; -// if (!m_typeAndButton->isEnabled()) { -// m_typeOrButton->setEnabled(true); -// m_typeAndButton->setEnabled(true); -// m_typeAndButton->setToolTip(tr("All of the words (AND is added between the words)")); -// m_typeOrButton->setToolTip(tr("Some of the words")); -// } -// } -// else { -// qDebug() << "AND/OR!"; -// if (m_typeAndButton->isEnabled()) { -// m_typeOrButton->setChecked(true); -// m_typeOrButton->setEnabled(false); -// m_typeAndButton->setEnabled(false); -// m_typeAndButton->setToolTip(tr("Full syntax is used because text includes AND or OR")); -// m_typeOrButton->setToolTip(tr("Full syntax is used because text includes AND or OR")); -// } -// } +// static const QRegExp re("\\b(AND|OR)\\b"); +// qDebug() << "new text:" << newText; +// qDebug() << "contains:" << (newText.contains(re)); +// if (newText.isEmpty() || !newText.contains(re) ) { +// qDebug()<< "no AND/OR"; +// if (!m_typeAndButton->isEnabled()) { +// m_typeOrButton->setEnabled(true); +// m_typeAndButton->setEnabled(true); +// m_typeAndButton->setToolTip(tr("All of the words (AND is added between the words)")); +// m_typeOrButton->setToolTip(tr("Some of the words")); +// } +// } +// else { +// qDebug() << "AND/OR!"; +// if (m_typeAndButton->isEnabled()) { +// m_typeOrButton->setChecked(true); +// m_typeOrButton->setEnabled(false); +// m_typeAndButton->setEnabled(false); +// m_typeAndButton->setToolTip(tr("Full syntax is used because text includes AND or OR")); +// m_typeOrButton->setToolTip(tr("Full syntax is used because text includes AND or OR")); +// } +// } } //bool BtSearchOptionsArea::isAndSearchType() diff --git a/src/frontend/searchdialog/btsearchoptionsarea.h b/src/frontend/searchdialog/btsearchoptionsarea.h index c7c1b1c..afc73ca 100644 --- a/src/frontend/searchdialog/btsearchoptionsarea.h +++ b/src/frontend/searchdialog/btsearchoptionsarea.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -57,9 +57,11 @@ class BtSearchOptionsArea : public QWidget { QPushButton* searchButton() const; /** - * Returns the list of used modules. + Returns the list of used modules. */ - QList modules() const; + inline QList modules() const { + return m_modules; + } /** * Sets all options back to the default. @@ -88,11 +90,12 @@ class BtSearchOptionsArea : public QWidget { */ void saveSettings(); bool eventFilter(QObject* obj, QEvent* event); + public slots: /** - * Sets the modules used by the search. + Sets the modules used by the search. */ - void setModules( QList modules ); + void setModules(const QList &modules); /** Sets the modules when user selects them from the combobox.*/ void moduleListTextSelected(int index); @@ -121,7 +124,7 @@ class BtSearchOptionsArea : public QWidget { void sigStartSearch(); private: - QList m_modules; + QList m_modules; QHBoxLayout *hboxLayout; QGroupBox *searchGroupBox; diff --git a/src/frontend/searchdialog/btsearchresultarea.cpp b/src/frontend/searchdialog/btsearchresultarea.cpp index 4b33f80..623de0e 100644 --- a/src/frontend/searchdialog/btsearchresultarea.cpp +++ b/src/frontend/searchdialog/btsearchresultarea.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -22,8 +23,6 @@ #include "backend/keys/cswordversekey.h" #include "backend/rendering/cdisplayrendering.h" #include "frontend/display/cdisplay.h" -#include "frontend/display/creaddisplay.h" -#include "frontend/searchdialog/analysis/csearchanalysisdialog.h" #include "frontend/searchdialog/cmoduleresultview.h" #include "frontend/searchdialog/csearchdialog.h" #include "frontend/searchdialog/csearchresultview.h" @@ -40,10 +39,6 @@ BtSearchResultArea::BtSearchResultArea(QWidget *parent) qDebug() << "BtSearchResultArea::BtSearchResultArea end"; } -BtSearchResultArea::~BtSearchResultArea() { - saveDialogSettings(); -} - void BtSearchResultArea::initView() { QVBoxLayout *mainLayout; QWidget *resultListsWidget; @@ -54,32 +49,32 @@ void BtSearchResultArea::initView() { int mWidth = util::tool::mWidth(this, 1); this->setMinimumSize(QSize(mWidth*40, mWidth*15)); mainLayout = new QVBoxLayout(this); - mainSplitter = new QSplitter(this); - mainSplitter->setOrientation(Qt::Horizontal); + m_mainSplitter = new QSplitter(this); + m_mainSplitter->setOrientation(Qt::Horizontal); - resultListsWidget = new QWidget(mainSplitter); + resultListsWidget = new QWidget(m_mainSplitter); resultListsWidgetLayout = new QVBoxLayout(resultListsWidget); resultListsWidgetLayout->setContentsMargins(0, 0, 0, 0); //Splitter for two result lists - resultListSplitter = new QSplitter(resultListsWidget); - resultListSplitter->setOrientation(Qt::Vertical); - m_moduleListBox = new CModuleResultView(resultListSplitter); - resultListSplitter->addWidget(m_moduleListBox); - m_resultListBox = new CSearchResultView(resultListSplitter); - resultListSplitter->addWidget(m_resultListBox); - resultListsWidgetLayout->addWidget(resultListSplitter); + m_resultListSplitter = new QSplitter(resultListsWidget); + m_resultListSplitter->setOrientation(Qt::Vertical); + m_moduleListBox = new CModuleResultView(m_resultListSplitter); + m_resultListSplitter->addWidget(m_moduleListBox); + m_resultListBox = new CSearchResultView(m_resultListSplitter); + m_resultListSplitter->addWidget(m_resultListBox); + resultListsWidgetLayout->addWidget(m_resultListSplitter); - mainSplitter->addWidget(resultListsWidget); + m_mainSplitter->addWidget(resultListsWidget); //Preview ("info") area - m_displayFrame = new QFrame(mainSplitter); + m_displayFrame = new QFrame(m_mainSplitter); m_displayFrame->setFrameShape(QFrame::NoFrame); m_displayFrame->setFrameShadow(QFrame::Plain); - mainSplitter->addWidget(m_displayFrame); + m_mainSplitter->addWidget(m_displayFrame); - mainLayout->addWidget(mainSplitter); + mainLayout->addWidget(m_mainSplitter); QVBoxLayout* frameLayout = new QVBoxLayout(m_displayFrame); frameLayout->setContentsMargins(0, 0, 0, 0); @@ -87,20 +82,38 @@ void BtSearchResultArea::initView() { m_previewDisplay->view()->setToolTip(tr("Text of the selected search result item")); frameLayout->addWidget(m_previewDisplay->view()); + QAction* selectAllAction = new QAction(QIcon(), tr("Select all"), this); + selectAllAction->setShortcut(QKeySequence::SelectAll); + QObject::connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()) ); + + QAction* copyAction = new QAction(tr("Copy"), this); + copyAction->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_C) ); + QObject::connect(copyAction, SIGNAL(triggered()), this, SLOT(copySelection()) ); + + QMenu* menu = new QMenu(); + menu->addAction(selectAllAction); + menu->addAction(copyAction); + m_previewDisplay->installPopup(menu); + loadDialogSettings(); } -void BtSearchResultArea::setSearchResult(QList modules) { +void BtSearchResultArea::setSearchResult( + const CSwordModuleSearch::Results &results) +{ const QString searchedText = CSearchDialog::getSearchDialog()->searchText(); reset(); //clear current modules - m_modules = modules; - //pre-select the first module in the list - //this will pre-select and display the first hit of that module - m_moduleListBox->setupTree(modules, searchedText); + m_results = results; + + // Populate listbox: + m_moduleListBox->setupTree(results, searchedText); + + // Pre-select the first module in the list: m_moduleListBox->setCurrentItem(m_moduleListBox->topLevelItem(0), 0); - qobject_cast(parent())->m_analyseButton->setEnabled(true); + Q_ASSERT(qobject_cast(parent()) != 0); + static_cast(parent())->m_analyseButton->setEnabled(true); } void BtSearchResultArea::reset() { @@ -108,7 +121,6 @@ void BtSearchResultArea::reset() { m_resultListBox->clear(); m_previewDisplay->setText(""); qobject_cast(parent())->m_analyseButton->setEnabled(false); - m_modules.clear(); } void BtSearchResultArea::clearPreview() { @@ -125,7 +137,7 @@ void BtSearchResultArea::updatePreview(const QString& key) { QString text; CDisplayRendering render; - QList modules; + QList modules; modules.append(module); CTextRendering::KeyTreeItem::Settings settings; @@ -134,7 +146,7 @@ void BtSearchResultArea::updatePreview(const QString& key) { if (module->type() == CSwordModuleInfo::Bible) { CSwordVerseKey vk(module); vk.Headings(1); - vk.key(key); + vk.setKey(key); ((sword::VerseKey*)(module->module()->getKey()))->Headings(1); //HACK: enable headings for VerseKeys @@ -152,7 +164,7 @@ void BtSearchResultArea::updatePreview(const QString& key) { const QString startKey = vk.key(); - vk.key(key); + vk.setKey(key); vk.next(CSwordVerseKey::UseVerse); vk.next(CSwordVerseKey::UseVerse); @@ -165,7 +177,7 @@ void BtSearchResultArea::updatePreview(const QString& key) { else if (module->type() == CSwordModuleInfo::Commentary) { CSwordVerseKey vk(module); vk.Headings(1); - vk.key(key); + vk.setKey(key); ((sword::VerseKey*)(module->module()->getKey()))->Headings(1); //HACK: enable headings for VerseKeys @@ -178,7 +190,7 @@ void BtSearchResultArea::updatePreview(const QString& key) { } const QString startKey = vk.key(); - vk.key(key); + vk.setKey(key); const QString endKey = vk.key(); settings.keyRenderingFace = CTextRendering::KeyTreeItem::Settings::NoKey; @@ -193,7 +205,7 @@ void BtSearchResultArea::updatePreview(const QString& key) { } } -QStringList BtSearchResultArea::QueryParser(const QString& queryString) { +QStringList BtSearchResultArea::queryParser(const QString& queryString) { QString token; QStringList tokenList; int cnt, pos; @@ -226,13 +238,13 @@ QStringList BtSearchResultArea::QueryParser(const QString& queryString) { } // wild card - treat as a special token break //else if (queryString[cnt] == '*') { - // token = token + queryString[cnt]; - // token = token.simplified(); - // if ((token != "*") && (token != "")) - // tokenList.append(token); - // // start next token with wildcard (kin*m -> kin* *m) - // token = "*"; - // cnt++; + // token = token + queryString[cnt]; + // token = token.simplified(); + // if ((token != "*") && (token != "")) + // tokenList.append(token); + // // start next token with wildcard (kin*m -> kin* *m) + // token = "*"; + // cnt++; //} // the ! token is also a token break else if (queryString[cnt] == '!') { @@ -423,20 +435,20 @@ QString BtSearchResultArea::highlightSearchedText(const QString& content, const //char buf8[1000]; //standard::WhitespaceAnalyzer analyzer; //lucene_utf8towcs(m_wcharBuffer, searchedText.utf8(), MAX_CONV_SIZE); - //boost::scoped_ptr q( QueryParser::parse(m_wcharBuffer, _T("content"), &analyzer) ); + //QSharedPointer q( QueryParser::parse(m_wcharBuffer, _T("content"), &analyzer) ); //StringReader reader(m_wcharBuffer); //TokenStream* tokenStream = analyzer.tokenStream( _T("field"), &reader); //Token token; //while(tokenStream->next(&token) != 0) { - // lucene_wcstoutf8(buf8, token.termText(), 1000); - // printf("%s\n", buf8); + // lucene_wcstoutf8(buf8, token.termText(), 1000); + // printf("%s\n", buf8); //} //=========================================================== // since I could not figure out the lucene query parser, I // made a simple parser. //=========================================================== - QStringList words = QueryParser(newSearchText); + QStringList words = queryParser(newSearchText); qDebug() << "btsearchresultarea.cpp: " << __LINE__ << ": " << words << '\n'; foreach (QString word, words) { //search for every word in the list QRegExp findExp; @@ -481,18 +493,15 @@ QString BtSearchResultArea::highlightSearchedText(const QString& content, const void BtSearchResultArea::initConnections() { connect(m_resultListBox, SIGNAL(keySelected(const QString&)), this, SLOT(updatePreview(const QString&))); connect(m_resultListBox, SIGNAL(keyDeselected()), this, SLOT(clearPreview())); - connect(m_moduleListBox, SIGNAL(moduleSelected(CSwordModuleInfo*)), m_resultListBox, SLOT(setupTree(CSwordModuleInfo*))); + connect(m_moduleListBox, + SIGNAL(moduleSelected(const CSwordModuleInfo*, const sword::ListKey&)), + m_resultListBox, + SLOT(setupTree(const CSwordModuleInfo*, const sword::ListKey&))); connect(m_moduleListBox, SIGNAL(moduleChanged()), m_previewDisplay->connectionsProxy(), SLOT(clear())); // connect the strongs list - connect(m_moduleListBox, SIGNAL(strongsSelected(CSwordModuleInfo*, QStringList*)), - m_resultListBox, SLOT(setupStrongsTree(CSwordModuleInfo*, QStringList*))); -} - -/** Shows a dialog with the search analysis of the current search. */ -void BtSearchResultArea::showAnalysis() { - CSearchAnalysisDialog dlg(m_modules, this); - dlg.exec(); + connect(m_moduleListBox, SIGNAL(strongsSelected(CSwordModuleInfo*, const QStringList&)), + m_resultListBox, SLOT(setupStrongsTree(CSwordModuleInfo*, const QStringList&))); } /** @@ -501,127 +510,97 @@ void BtSearchResultArea::showAnalysis() { void BtSearchResultArea::loadDialogSettings() { QList mainSplitterSizes = CBTConfig::get(CBTConfig::searchMainSplitterSizes); if (mainSplitterSizes.count() > 0) { - mainSplitter->setSizes(mainSplitterSizes); + m_mainSplitter->setSizes(mainSplitterSizes); } else { int w = this->size().width(); int w2 = m_moduleListBox->sizeHint().width(); mainSplitterSizes << w2 << w - w2; - mainSplitter->setSizes(mainSplitterSizes); + m_mainSplitter->setSizes(mainSplitterSizes); } QList resultSplitterSizes = CBTConfig::get(CBTConfig::searchResultSplitterSizes); - if (resultSplitterSizes.count() > 0) resultListSplitter->setSizes(resultSplitterSizes); + if (resultSplitterSizes.count() > 0) m_resultListSplitter->setSizes(resultSplitterSizes); } /** * Save the settings to the resource file */ void BtSearchResultArea::saveDialogSettings() { - CBTConfig::set(CBTConfig::searchMainSplitterSizes, mainSplitter->sizes()); - CBTConfig::set(CBTConfig::searchResultSplitterSizes, resultListSplitter->sizes()); -} - -StrongsResult::StrongsResult() { -} - -StrongsResult::StrongsResult(const QString& text, const QString &keyName) - : text(text) { - //keyNameList.clear(); - keyNameList.append(keyName); -} - -QString StrongsResult::keyText() const { - return text; -} - -int StrongsResult::keyCount() const { - return keyNameList.count(); -} - -void StrongsResult::addKeyName(const QString& keyName) { - if (keyNameList.indexOf(keyName) == -1) - keyNameList.append(keyName); -} - -QStringList* StrongsResult::getKeyList() { - return & keyNameList; + CBTConfig::set(CBTConfig::searchMainSplitterSizes, m_mainSplitter->sizes()); + CBTConfig::set(CBTConfig::searchResultSplitterSizes, m_resultListSplitter->sizes()); } +/****************************************************************************** +* StrongsResultList: +******************************************************************************/ - -/******************************************** -************ StrongsResultClass ************* -********************************************/ -void StrongsResultClass::initStrongsResults(void) { +StrongsResultList::StrongsResultList(const CSwordModuleInfo *module, + const sword::ListKey &results, + const QString &strongsNumber) +{ using namespace Rendering; - CDisplayRendering render; - QList modules; - CTextRendering::KeyTreeItem::Settings settings; - QString rText, lText, key; - bool found; - int sIndex; - int count; - int index; - QString text; - - modules.append(srModule); - sword::ListKey& result = srModule->searchResult(); + /// \warning This is a workaround for Sword constness + sword::ListKey result = results; - count = result.Count(); + int count = result.Count(); if (!count) return; - qApp->processEvents( QEventLoop::AllEvents, 1 ); //1 ms only - srList.clear(); + + CTextRendering::KeyTreeItem::Settings settings; + QList modules; + modules.append(module); + clear(); + // for whatever reason the text "Parsing...translations." does not appear. // this is not critical but the text is necessary to get the dialog box // to be wide enough. - QProgressDialog* progress = new QProgressDialog(QObject::tr("Parsing Strong's Numbers"), 0, 0, count); + QProgressDialog progress(QObject::tr("Parsing Strong's Numbers"), 0, 0, count); //0, "progressDialog", tr("Parsing Strong's Numbers"), tr("Parsing Strong's numbers for translations."), true); - //progress->setAllowCancel(false); //progress->setMinimumDuration(0); - progress->show(); - progress->raise(); - for (index = 0; index < count; index++) { - progress->setValue( index ); - qApp->processEvents(QEventLoop::AllEvents, 1 ); //1 ms only - - key = QString::fromUtf8(result.GetElement(index)->getText()); - text = render.renderSingleKey(key, modules, settings); - sIndex = 0; - while ((rText = getStrongsNumberText(text, &sIndex)) != "") { - StrongsResultList::iterator it; - found = FALSE; - for ( it = srList.begin(); it != srList.end(); ++it ) { - lText = (*it).keyText(); - if (lText == rText) { - found = TRUE; + progress.show(); + progress.raise(); + + qApp->processEvents(QEventLoop::AllEvents, 1); //1 ms only + + for (int index = 0; index < count; index++) { + progress.setValue(index); + qApp->processEvents(QEventLoop::AllEvents, 1); //1 ms only + + QString key = QString::fromUtf8(result.GetElement(index)->getText()); + QString text = CDisplayRendering().renderSingleKey(key, modules, settings); + for (int sIndex = 0;;) { + continueloop: + QString rText = getStrongsNumberText(text, sIndex, strongsNumber); + if (rText.isEmpty()) break; + + for (iterator it = begin(); it != end(); ++it) { + if ((*it).keyText() == rText) { (*it).addKeyName(key); - break; + goto continueloop; // break, then continue } } - if (found == FALSE) - srList.append( StrongsResult(rText, key) ); + append(StrongsResult(rText, key)); } } - delete progress; - progress = 0; - //qHeapSort(srList); } -QString StrongsResultClass::getStrongsNumberText(const QString& verseContent, int *startIndex) { +QString StrongsResultList::getStrongsNumberText(const QString &verseContent, + int &startIndex, + const QString &lemmaText) +{ // get the strongs text int idx1, idx2, index; QString sNumber, strongsText; //const bool cs = CSwordModuleSearch::caseSensitive; const Qt::CaseSensitivity cs = Qt::CaseInsensitive; - if (*startIndex == 0) { + if (startIndex == 0) { index = verseContent.indexOf(" #include "backend/managers/cswordbackend.h" #include "backend/cswordmodulesearch.h" +#include "frontend/display/creaddisplay.h" +#include "frontend/searchdialog/analysis/csearchanalysisdialog.h" namespace Search { class CModuleResultView; class CSearchResultView; } -class CReadDisplay; class CSwordModuleInfo; class QFrame; class QHBoxLayout; @@ -44,73 +45,45 @@ namespace Search { * To add a new verse to a strongs text result use addKeyName. */ class StrongsResult { - public: - StrongsResult(); - StrongsResult(const QString& text, const QString &keyName); - - QString keyText() const; - int keyCount() const; - void addKeyName(const QString& keyName); - QStringList* getKeyList(); + public: /* Methods: */ + inline StrongsResult() {} + inline StrongsResult(const QString &text, + const QString &keyName) + : m_text(text) + { + m_keyNameList.append(keyName); + } - /* ???? - bool operator==(const StrongsResult &l, const StrongsResult &r) - { return (l.keyText() == r.keyText()); } + const QString &keyText() const { return m_text; } + inline int keyCount() const { return m_keyNameList.count(); } + inline void addKeyName(const QString &keyName) { + if (m_keyNameList.contains(keyName)) return; + m_keyNameList.append(keyName); + } - bool operator<(const StrongsResult &l, const StrongsResult &r) - { return (l->keyText() < r->keyText()); } + inline const QStringList &getKeyList() const { return m_keyNameList; } - bool operator>(const StrongsResult &l, const StrongsResult &r) - { return (l->keyText() > r->keyText()); } - */ - private: - QString text; - QStringList keyNameList; + private: /* Fields: */ + QString m_text; + QStringList m_keyNameList; }; -typedef QList StrongsResultList; - /** +* \todo Fix comment! * This class is used to keep track of the text strongs results. * It keeps track of all instances of all strongs text results. * This class makes use of the above class StrongsResult. -* -* The functions of the class are: -* - Store an instance of a strongs text result. -* - Each strongs text result will contain a list of verses (keyNames). -* - The number of verses (keyNames) is returned by keyCount(). -* - The text for the strongs text result is returned by keyText(). -* - The list of verses (keyNames) is returned by getKeyList() [as QStringList]. -* -* To add a new verse to a strongs text result use addKeyName. */ -class StrongsResultClass { - public: - StrongsResultClass(CSwordModuleInfo* module, const QString& strongsNumber) - : srModule(module), lemmaText(strongsNumber) { - initStrongsResults(); - } - - QString keyText(int index) const { - return srList[index].keyText(); - } - int keyCount(int index) const { - return srList[index].keyCount(); - } - QStringList* getKeyList(int index) { - return srList[index].getKeyList(); - } - int Count() const { - return srList.count(); - } - - private: - void initStrongsResults(void); - QString getStrongsNumberText(const QString& verseContent, int *startIndex); - - StrongsResultList srList; - CSwordModuleInfo* srModule; - QString lemmaText; +class StrongsResultList: public QList { + public: /* Methods: */ + StrongsResultList(const CSwordModuleInfo *module, + const sword::ListKey &results, + const QString &strongsNumber); + + private: /* Methods: */ + QString getStrongsNumberText(const QString &verseContent, + int &startIndex, + const QString &lemmaText); }; @@ -119,18 +92,27 @@ class StrongsResultClass { */ class BtSearchResultArea : public QWidget { Q_OBJECT - public: + public: /* Methods: */ BtSearchResultArea(QWidget *parent = 0); - ~BtSearchResultArea(); + inline ~BtSearchResultArea() { saveDialogSettings(); } + /** * Sets the modules which contain the result of each. */ - void setSearchResult(QList modules); + void setSearchResult( + const CSwordModuleSearch::Results &results); - QSize sizeHint() const { + /** + Reimplemented from QWidget::sizeHint(). + */ + virtual QSize sizeHint() const { return baseSize(); } - QSize minimumSizeHint() const { + + /** + Reimplemented from QWidget::minimumSizeHint(). + */ + virtual QSize minimumSizeHint() const { return minimumSize(); } @@ -140,19 +122,22 @@ class BtSearchResultArea : public QWidget { */ void reset(); - protected: + protected: /* Methods: */ /** * Initializes the view of this widget. */ void initView(); + /** * Initializes the signal slot conections of the child widgets */ void initConnections(); + /** * This function breakes the queryString into clucene tokens */ - QStringList QueryParser(const QString& queryString); + QStringList queryParser(const QString& queryString); + /** * This function highlights the searched text in the content using the search type given by search flags */ @@ -162,6 +147,7 @@ class BtSearchResultArea : public QWidget { * Load the settings from the resource file */ void loadDialogSettings(); + /** * Save the settings to the resource file */ @@ -172,16 +158,33 @@ class BtSearchResultArea : public QWidget { * Update the preview of the selected key. */ void updatePreview(const QString& key); + /** * Clear the preview of the selected key. */ void clearPreview(); + /** * Shows a dialog with the search analysis of the current search. */ - void showAnalysis(); + inline void showAnalysis() { + CSearchAnalysisDialog(m_results, this).exec(); + } + + /** + * Select all text + */ + inline void selectAll() { m_previewDisplay->selectAll(); } - private: + /** + * Copy selected text + */ + inline void copySelection() { + m_previewDisplay->connectionsProxy()->copySelection(); + } + + private: /* Fields: */ + CSwordModuleSearch::Results m_results; CModuleResultView* m_moduleListBox; CSearchResultView* m_resultListBox; @@ -189,10 +192,8 @@ class BtSearchResultArea : public QWidget { QFrame *m_displayFrame; CReadDisplay* m_previewDisplay; - QList m_modules; - - QSplitter *mainSplitter; - QSplitter *resultListSplitter; + QSplitter *m_mainSplitter; + QSplitter *m_resultListSplitter; }; } //namespace Search diff --git a/src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp new file mode 100644 index 0000000..a1debc3 --- /dev/null +++ b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.cpp @@ -0,0 +1,229 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/searchdialog/btsearchsyntaxhelpdialog.h" + +#include +#include +#include +#include +#include "util/dialogutil.h" +#include "util/directory.h" + + +namespace Search { + +BtSearchSyntaxHelpDialog::BtSearchSyntaxHelpDialog(QWidget *parent, Qt::WindowFlags wflags) + : QDialog(parent, wflags) +{ + setAttribute(Qt::WA_DeleteOnClose); + resize(550, 340); + + QVBoxLayout *l = new QVBoxLayout; + + m_webView = new QWebView(this); + m_webView->page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks); + connect(m_webView, SIGNAL(linkClicked(QUrl)), + this, SLOT(linkClicked(QUrl))); + l->addWidget(m_webView); + + m_buttons = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this); + connect(m_buttons, SIGNAL(rejected()), this, SLOT(reject())); + l->addWidget(m_buttons); + + setLayout(l); + + retranslateUi(); +} + +BtSearchSyntaxHelpDialog::~BtSearchSyntaxHelpDialog() { + // Intentionally empty +} + +void BtSearchSyntaxHelpDialog::retranslateUi() { + namespace DU = util::directory; + + QString theTitle(tr("Search Syntax Help")); + setWindowTitle(theTitle); + + QString html(""); + html += theTitle; + html += "

    "; + + html += tr("This help is mainly for 'Full syntax' option. 'All words' and 'Some words' " + "options have more limited syntax; wildcards and " + "text fields are supported for them. Some other syntax " + "features may give strange or wrong results with All words/Some words."); + html += "

    "; + html += tr("Which words to find"); + html += "

    "; + html += tr("Search terms are separated by spaces. AND (all words), " + "OR (some words) and NOT (not the following word) " + "can be added between the words. If none is added explicitly OR is used " + "automatically. '+word' means the word must be in the results, " + "'-word' means it must not be in the results.", + "Do not translate \"AND\", \"OR\" or \"NOT\"."); + html += "

    "; + html += tr("jesus AND god", "Do not translate \"AND\"."); + html += ""; + html += tr("Finds verses with both 'Jesus' and 'God'"); + html += "
    "; + html += tr("jesus OR god", "Do not translate \"OR\"."); + html += ""; + html += tr("Finds verses with 'Jesus' or 'God' or both"); + html += "
    "; + html += tr("jesus NOT god", "Do not translate \"NOT\"."); + html += ""; + html += tr("Finds verses with 'Jesus' but with no 'God'"); + html += "
    "; + html += tr("+jesus -god"); + html += ""; + html += tr("Finds verses with 'Jesus' but with no 'God'"); + + html += "

    "; + html += tr("Grouping and order"); + html += "

    "; + html += tr("Words can be grouped with parenthesis. Strict word order " + "can be defined with quotes."); + html += "

    "; + html += tr("(a AND b) OR c", "Do not translate \"AND\" or \"OR\"."); + html += ""; + html += tr("Finds verses with both 'a' AND 'b', and verses with 'c'"); + html += "
    "; + html += tr("\"says lord\""); + html += ""; + html += ("Finds e.g. '...Isaiah says, \"Lord...' but not '...says the LORD'"); + html += "
    "; + html += tr("\"says the lord\""); + html += ""; + html += tr("Finds all verses with 'says the LORD'"); + + html += "

    "; + html += tr("Wildcards (partial words)"); + html += "

    "; + html += tr("'*' matches any sequence of 0 or more characters, while " + "'?' matches any single character. A wildcard can not be used in " + "the beginning of a word."); + html += "

    "; + html += tr("a*"); + html += ""; + html += tr("All words beginning with 'a'"); + html += "
    "; + html += tr("a*a"); + html += ""; + html += tr("'Assyria', 'aroma', 'abba' etc."); + html += "
    "; + html += tr("a?"); + html += ""; + html += tr("'at' and 'an'"); + html += "
    "; + html += tr("a??a"); + html += ""; + html += tr("'abba', 'area', 'Asia' etc."); + + html += "

    "; + html += tr("Text fields (different parts of text)"); + html += "

    "; + html += tr("Available text fields:" ); + html += "
    heading:"; + html += tr("Searches headings"); + html += "
    footnote:"; + html += tr("Searches footnotes"); + html += "
    strong:"; + html += tr("Searches Strong's numbers"); + html += "
    morph:"; + html += tr("Searches morphology codes"); + html += "

    "; + html += tr("Examples:" ); + html += "
    "; + html += tr("heading:Jesus", "Do not translate \"heading:\"."); + html += ""; + html += tr("Finds headings with 'Jesus'"); + html += "
    "; + html += tr("footnote:Jesus AND footnote:said", + "Do not translate \"footnote:\" or \"AND\"."); + html += ""; + html += tr("Finds footnotes with 'Jesus' and 'said'"); + html += "
    "; + html += tr("strong:G846", "Do not translate \"strong:\"."); + html += ""; + html += tr("Finds verses with Strong's Greek number 846"); + html += "
    "; + html += tr("morph:\"N-NSF\"", "Do not translate \"morph:\"."); + html += ""; + html += tr("Finds verses with morphology code 'N-NSF'"); + html += "

    "; + html += tr("Other syntax features"); + html += "

    "; + html += tr("BibleTime uses the CLucene search engine. You can read more on the " + "lucene syntax web page (in external browser).") + .arg("http://lucene.apache.org/java/1_4_3/queryparsersyntax.html"); + html += "

    "; + + m_webView->setHtml(html, QUrl::fromLocalFile(DU::getIconDir().path())); + + util::prepareDialogBox(m_buttons); +} + +void BtSearchSyntaxHelpDialog::linkClicked(const QUrl &url) { + QDesktopServices::openUrl(url); +} + +} // namespace Search diff --git a/src/frontend/searchdialog/btsearchsyntaxhelpdialog.h b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.h new file mode 100644 index 0000000..89cc805 --- /dev/null +++ b/src/frontend/searchdialog/btsearchsyntaxhelpdialog.h @@ -0,0 +1,40 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTTABDIALOG_H +#define BTTABDIALOG_H + +#include + +class QDialogButtonBox; +class QUrl; +class QWebView; + +namespace Search { + +class BtSearchSyntaxHelpDialog: public QDialog { + Q_OBJECT + public: + BtSearchSyntaxHelpDialog(QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); + ~BtSearchSyntaxHelpDialog(); + + protected: + void retranslateUi(); + + protected slots: + void linkClicked(const QUrl &url); + + private: + QWebView *m_webView; + QDialogButtonBox *m_buttons; +}; + +} // namespace Search + +#endif diff --git a/src/frontend/searchdialog/chistorycombobox.cpp b/src/frontend/searchdialog/chistorycombobox.cpp index 355ed00..cf77627 100644 --- a/src/frontend/searchdialog/chistorycombobox.cpp +++ b/src/frontend/searchdialog/chistorycombobox.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/chistorycombobox.h b/src/frontend/searchdialog/chistorycombobox.h index d750e16..dffbcd8 100644 --- a/src/frontend/searchdialog/chistorycombobox.h +++ b/src/frontend/searchdialog/chistorycombobox.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/cmoduleresultview.cpp b/src/frontend/searchdialog/cmoduleresultview.cpp index ef23756..f37b4d9 100644 --- a/src/frontend/searchdialog/cmoduleresultview.cpp +++ b/src/frontend/searchdialog/cmoduleresultview.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -38,8 +38,7 @@ CModuleResultView::CModuleResultView(QWidget* parent) } CModuleResultView::~CModuleResultView() { - qDeleteAll(strongsResults); - strongsResults.clear(); + qDeleteAll(m_strongsResults); } @@ -98,32 +97,31 @@ void CModuleResultView::initConnections() { this, SLOT(executed(QTreeWidgetItem*, QTreeWidgetItem*))); } -/** Setups the tree using the given list of modules. */ -void CModuleResultView::setupTree( QList modules, const QString& searchedText ) { +void CModuleResultView::setupTree( + const CSwordModuleSearch::Results &results, + const QString &searchedText) +{ clear(); + + m_results = results; + /// \todo this class is for sorting //util::CSortListViewItem* item = 0; //util::CSortListViewItem* oldItem = 0; QTreeWidgetItem* item = 0; - QTreeWidgetItem* oldItem = 0; - sword::ListKey result; - - qDeleteAll(strongsResults); - strongsResults.clear(); + qDeleteAll(m_strongsResults); + m_strongsResults.clear(); bool strongsAvailable = false; - QList::iterator end_it = modules.end(); - for (QList::iterator it(modules.begin()); it != end_it; ++it) { - // for (modules.first(); modules.current(); modules.next()) { - result = (*it)->searchResult(); + Q_FOREACH(const CSwordModuleInfo *m, results.keys()) { + sword::ListKey result = results.value(m); - item = new QTreeWidgetItem(this, QStringList((*it)->name()) << QString::number(result.Count()) ); + item = new QTreeWidgetItem(this, QStringList(m->name()) << QString::number(result.Count()) ); /// \todo item->setColumnSorting(1, util::CSortListViewItem::Number); - item->setIcon(0, util::tool::getIconForModule(*it) ); - oldItem = item; + item->setIcon(0, util::tool::getIconForModule(m) ); //---------------------------------------------------------------------- // we need to make a decision here. Either don't show any Strong's // number translations, or show the first one in the search text, or @@ -142,7 +140,7 @@ void CModuleResultView::setupTree( QList modules, const QStri sTokenIndex = searchedText.indexOf(" ", sstIndex); sNumber = searchedText.mid(sstIndex, sTokenIndex - sstIndex); - setupStrongsResults((*it), item, sNumber); + setupStrongsResults(m, results[m], item, sNumber); /// \todo item->setOpen(true); strongsAvailable = true; @@ -153,53 +151,50 @@ void CModuleResultView::setupTree( QList modules, const QStri setRootIsDecorated( strongsAvailable ); } -void CModuleResultView::setupStrongsResults(CSwordModuleInfo* module, QTreeWidgetItem* parent, - const QString& sNumber) { - QString lText; - /// \todo - //util::CSortListViewItem* item = 0; - QTreeWidgetItem* item = 0; - - strongsResults[module] = new StrongsResultClass(module, sNumber); - - for (int cnt = 0; cnt < strongsResults[module]->Count(); ++cnt) { - lText = strongsResults[module]->keyText(cnt); - - item = new QTreeWidgetItem(parent, QStringList(lText) << QString::number(strongsResults[module]->keyCount(cnt))); - /// \todo - //item->setColumnSorting(1, util::CSortListViewItem::Number); +void CModuleResultView::setupStrongsResults(const CSwordModuleInfo *module, + const sword::ListKey &results, + QTreeWidgetItem *parent, + const QString &sNumber) +{ + StrongsResultList *m = new StrongsResultList(module, results, sNumber); + m_strongsResults[module] = m; + + for (int cnt = 0; cnt < m->count(); ++cnt) { + QStringList columns(m->at(cnt).keyText()); + columns.append(QString::number(m->at(cnt).keyCount())); + new QTreeWidgetItem(parent, columns); } } /// \todo /** Is executed when an item was selected in the list. */ void CModuleResultView::executed( QTreeWidgetItem* i, QTreeWidgetItem*) { - QString itemText, lText; + QString itemText; if (!i) { //Clear list emit moduleChanged(); return; } - if (CSwordModuleInfo* m = CPointers::backend()->findModuleByName(i->text(0))) { + if (CSwordModuleInfo *m = CSwordBackend::instance()->findModuleByName(i->text(0))) { emit moduleChanged(); - emit moduleSelected(m); + emit moduleSelected(m, m_results.value(m)); return; } - StrongsResultClass* strongsResult = strongsResults[activeModule()]; + StrongsResultList *strongsResult = m_strongsResults[activeModule()]; if (!strongsResult) { return; } itemText = i->text(0); - for (int cnt = 0; cnt < strongsResult->Count(); cnt++) { - lText = strongsResult->keyText(cnt); - if (lText == itemText) { + for (int cnt = 0; cnt < strongsResult->count(); cnt++) { + if (strongsResult->at(cnt).keyText() == itemText) { //clear the verses list emit moduleChanged(); - emit strongsSelected(activeModule(), strongsResult->getKeyList(cnt)); + emit strongsSelected(activeModule(), + strongsResult->at(cnt).getKeyList()); return; } } @@ -221,7 +216,7 @@ CSwordModuleInfo* CModuleResultView::activeModule() { } if (item) { - return CPointers::backend()->findModuleByName(item->text(0)); + return CSwordBackend::instance()->findModuleByName(item->text(0)); } return 0; @@ -236,46 +231,57 @@ void CModuleResultView::contextMenuEvent( QContextMenuEvent * event ) { /** Copies the whole search result into the clipboard. */ void CModuleResultView::copyResult() { - if (CSwordModuleInfo* m = activeModule()) { - sword::ListKey result = m->searchResult(); - CExportManager mgr(tr("Copy search result..."), true, tr("Copying search result")); - mgr.copyKeyList(&result, m, CExportManager::Text, false); + CSwordModuleInfo *m = activeModule(); + if (m != 0) { + CExportManager mgr(tr("Copy search result..."), true, + tr("Copying search result")); + + mgr.copyKeyList(m_results[m], m, CExportManager::Text, false); }; } /** Copies the whole search result with the text into the clipboard. */ void CModuleResultView::copyResultWithText() { - if (CSwordModuleInfo* m = activeModule()) { - sword::ListKey result = m->searchResult(); - CExportManager mgr(tr("Copy search result..."), true, tr("Copying search result")); - mgr.copyKeyList(&result, m, CExportManager::Text, true); + CSwordModuleInfo *m = activeModule(); + if (m != 0) { + CExportManager mgr(tr("Copy search result..."), true, + tr("Copying search result")); + + mgr.copyKeyList(m_results[m], m, CExportManager::Text, true); }; } /** Saves the search result keys. */ void CModuleResultView::saveResult() { - if (CSwordModuleInfo* m = activeModule()) { - sword::ListKey result = m->searchResult(); - CExportManager mgr(tr("Save search result..."), true, tr("Saving search result")); - mgr.saveKeyList(&result, m, CExportManager::Text, false); + CSwordModuleInfo *m = activeModule(); + if (m != 0) { + CExportManager mgr(tr("Save search result..."), true, + tr("Saving search result")); + + mgr.saveKeyList(m_results[m], m, CExportManager::Text, false); }; } /** Saves the search result with it's text. */ void CModuleResultView::saveResultWithText() { - if (CSwordModuleInfo* m = activeModule()) { - sword::ListKey result = m->searchResult(); - CExportManager mgr(tr("Save search result..."), true, tr("Saving search result")); - mgr.saveKeyList(&result, m, CExportManager::Text, true); + CSwordModuleInfo *m = activeModule(); + if (m != 0) { + CExportManager mgr(tr("Save search result..."), true, + tr("Saving search result")); + + mgr.saveKeyList(m_results[m], m, CExportManager::Text, true); }; } /** Appends the whole search result to the printer queue. */ void CModuleResultView::printResult() { - if (CSwordModuleInfo* m = activeModule()) { - sword::ListKey result = m->searchResult(); - CExportManager mgr(tr("Print search result..."), true, tr("Printing search result")); - mgr.printKeyList(&result, m, CBTConfig::getDisplayOptionDefaults(), CBTConfig::getFilterOptionDefaults()); + CSwordModuleInfo *m = activeModule(); + if (m != 0) { + CExportManager mgr(tr("Print search result..."), true, + tr("Printing search result")); + + mgr.printKeyList(m_results[m], m, CBTConfig::getDisplayOptionDefaults(), + CBTConfig::getFilterOptionDefaults()); }; } diff --git a/src/frontend/searchdialog/cmoduleresultview.h b/src/frontend/searchdialog/cmoduleresultview.h index ab48f60..5940859 100644 --- a/src/frontend/searchdialog/cmoduleresultview.h +++ b/src/frontend/searchdialog/cmoduleresultview.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,7 +22,7 @@ class QContextMenuEvent; class QMenu; class QPoint; class QStringList; -class StrongsResultClass; +class StrongsResultList; namespace Search { @@ -33,9 +33,11 @@ class CModuleResultView : public QTreeWidget { ~CModuleResultView(); /** - * Setups the tree using the given list of modules. + Setups the tree using the given list of modules. */ - void setupTree( QList modules, const QString& searchedText ); + void setupTree(const CSwordModuleSearch::Results &results, + const QString &searchedText); + /** * Returns the currently active module. */ @@ -56,7 +58,10 @@ class CModuleResultView : public QTreeWidget { void initConnections(); - void setupStrongsResults(CSwordModuleInfo* module, QTreeWidgetItem* parent, const QString& searchedText); + void setupStrongsResults(const CSwordModuleInfo *module, + const sword::ListKey &results, + QTreeWidgetItem *parent, + const QString &searchedText); protected slots: /** @@ -89,9 +94,9 @@ class CModuleResultView : public QTreeWidget { void saveResult(); signals: - void moduleSelected(CSwordModuleInfo*); + void moduleSelected(const CSwordModuleInfo*, const sword::ListKey&); void moduleChanged(); - void strongsSelected(CSwordModuleInfo*, QStringList*); + void strongsSelected(CSwordModuleInfo*, const QStringList&); private: struct { @@ -119,7 +124,8 @@ class CModuleResultView : public QTreeWidget { QMenu* m_popup; - QHash strongsResults; + CSwordModuleSearch::Results m_results; + QHash m_strongsResults; QSize m_size; }; diff --git a/src/frontend/searchdialog/crangechooserdialog.cpp b/src/frontend/searchdialog/crangechooserdialog.cpp index 335fc5e..4fc2a3d 100644 --- a/src/frontend/searchdialog/crangechooserdialog.cpp +++ b/src/frontend/searchdialog/crangechooserdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/crangechooserdialog.h b/src/frontend/searchdialog/crangechooserdialog.h index b665a8f..8a3a91e 100644 --- a/src/frontend/searchdialog/crangechooserdialog.h +++ b/src/frontend/searchdialog/crangechooserdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/searchdialog/csearchdialog.cpp b/src/frontend/searchdialog/csearchdialog.cpp index 6f8214c..5461732 100644 --- a/src/frontend/searchdialog/csearchdialog.cpp +++ b/src/frontend/searchdialog/csearchdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -24,7 +25,7 @@ #include "backend/cswordmodulesearch.h" #include "backend/keys/cswordkey.h" #include "backend/keys/cswordversekey.h" -#include "frontend/cmoduleindexdialog.h" +#include "frontend/btmoduleindexdialog.h" #include "frontend/searchdialog/btsearchoptionsarea.h" #include "frontend/searchdialog/btsearchresultarea.h" #include "util/cresmgr.h" @@ -36,7 +37,9 @@ namespace Search { static CSearchDialog* m_staticDialog = 0; -void CSearchDialog::openDialog(const QList modules, const QString& searchText, QWidget* parentDialog) { +void CSearchDialog::openDialog(const QList modules, + const QString &searchText, QWidget *parentDialog) +{ if (!m_staticDialog) { m_staticDialog = new CSearchDialog(parentDialog); }; @@ -81,7 +84,7 @@ CSearchDialog::CSearchDialog(QWidget *parent) setWindowIcon(DU::getIcon(CResMgr::searchdialog::icon)); setWindowTitle(tr("Search")); setAttribute(Qt::WA_DeleteOnClose); - m_searcher.connectFinished( this, SLOT(searchFinished())); + initView(); initConnections(); } @@ -91,10 +94,9 @@ CSearchDialog::~CSearchDialog() { m_staticDialog = 0; } -/** Starts the search with the set modules and the set search text. */ void CSearchDialog::startSearch() { + typedef QList ML; QString originalSearchText(m_searchOptionsArea->searchText()); - QString searchText(""); // first check the search string for errors { @@ -104,50 +106,72 @@ void CSearchDialog::startSearch() { return; } } - - searchText = prepareSearchText(originalSearchText); + QString searchText = prepareSearchText(originalSearchText); // Insert search text into history list of combobox m_searchOptionsArea->addToHistory(originalSearchText); - // check that we have the indices we need for searching - if (!m_searcher.modulesHaveIndices( modules() ) ) { - int result = util::showQuestion(this, tr("Missing indices"), - tr("One or more works need indexing before they can be searched.\n" - "This could take a long time. Proceed with indexing?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - // In SuSE 10.0 the result is the logical or of the button type, just like it is - // inputed into the QMessageBox. - if ( (result == (QMessageBox::Yes | QMessageBox::Default)) || - (result == QMessageBox::Yes) || (result == QMessageBox::Default) ) { - CModuleIndexDialog* dlg = CModuleIndexDialog::getInstance(); - dlg->indexUnindexedModules( modules() ); + // Check that we have the indices we need for searching + ML unindexedModules = CSwordModuleSearch::unindexedModules(modules()); + if (unindexedModules.size() > 0) { + // Build the list of module names: + QStringList moduleNameList; + Q_FOREACH (const CSwordModuleInfo *m, unindexedModules) { + moduleNameList.append(m->name()); } - else { + QString moduleNames("
    "); + moduleNames.append(moduleNameList.join(", ")); + moduleNames.append("

    "); + + // Ask the user about unindexed modules: + int result = util::showQuestion( + this, tr("Missing indices"), + tr("The following modules need to be indexed before they can be" + " searched in:") + moduleNames + tr("Indexing could take a l" + "ong time. Click \"Yes\" to index the modules and start the " + "search, or \"No\" to cancel the search."), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + + // User didn't press "Yes": + if ((result & (QMessageBox::Yes | QMessageBox::Default)) == 0x0) { + return; + } + + // Show indexing dialog, and index the modules: + if (!BtModuleIndexDialog::indexAllModules(unindexedModules)) { + // Failed or user cancelled. return; } } + // Set the search options: + m_searcher.setSearchedText(searchText); + m_searcher.setModules(modules()); if (m_searchOptionsArea->hasSearchScope()) { - m_searcher.setSearchScope( m_searchOptionsArea->searchScope() ); - } - else { + m_searcher.setSearchScope(m_searchOptionsArea->searchScope()); + } else { m_searcher.resetSearchScope(); } - m_searcher.setModules( modules() ); - m_searcher.setSearchedText(searchText); - - - //Just to be sure that it can't be clicked again, if the search happens to be a bit slow. - m_searchOptionsArea->searchButton()->setEnabled(false); - m_searchOptionsArea->m_searchTextCombo->setEnabled(false); + // Disable the dialog: + setEnabled(false); + setCursor(Qt::WaitCursor); + // Execute search: m_searcher.startSearch(); - m_searchOptionsArea->searchButton()->setEnabled(true); - m_searchOptionsArea->m_searchTextCombo->setEnabled(true); - m_searchOptionsArea->m_searchTextCombo->setFocus(); + // Display the search results: + if (m_searcher.foundItems() > 0) { + m_searchResultArea->setSearchResult(m_searcher.results()); + } else { + m_searchResultArea->reset(); + } + m_staticDialog->raise(); + m_staticDialog->activateWindow(); + + // Re-enable the dialog: + setEnabled(true); + setCursor(Qt::ArrowCursor); } QString CSearchDialog::prepareSearchText(const QString& orig) { @@ -179,8 +203,9 @@ QString CSearchDialog::prepareSearchText(const QString& orig) { return text; } -/** Starts the search with the given module list and given search text. */ -void CSearchDialog::startSearch( const QList modules, const QString& searchText) { +void CSearchDialog::startSearch(const QList modules, + const QString &searchText) +{ m_searchResultArea->reset(); m_searchOptionsArea->reset(); setModules(modules); @@ -189,27 +214,8 @@ void CSearchDialog::startSearch( const QList modules, const Q startSearch(); } -/** Returns the list of used modules. */ -QList CSearchDialog::modules() const { - return m_searchOptionsArea->modules(); -} - -/** Sets the list of modules for the search. */ -void CSearchDialog::setModules( const QList modules ) { - m_searchOptionsArea->setModules(modules); -} - -/** Returns the search text which is set currently. */ -QString CSearchDialog::searchText() const { - return m_searchOptionsArea->searchText(); -} - -sword::ListKey CSearchDialog::searchScope() { - return m_searchOptionsArea->searchScope(); -} - /** Sets the search text which is used for the search. */ -void CSearchDialog::setSearchText( const QString searchText ) { +void CSearchDialog::setSearchText( const QString &searchText ) { m_searchOptionsArea->setSearchText(searchText); } @@ -224,12 +230,16 @@ void CSearchDialog::initView() { verticalLayout->addWidget(m_searchOptionsArea); m_searchResultArea = new BtSearchResultArea(this); + m_searchResultArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); verticalLayout->addWidget(m_searchResultArea); + QLabel* hint = new QLabel(tr("Drag any verse reference onto an open Bible window"), this); + verticalLayout->addWidget(hint); + QHBoxLayout* horizontalLayout = new QHBoxLayout(); m_analyseButton = new QPushButton(tr("&Analyze results..."), 0); - m_analyseButton->setToolTip(tr("Show a graphical analyzis of the search result")); + m_analyseButton->setToolTip(tr("Show a graphical analysis of the search result")); QSpacerItem* spacerItem = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout->addWidget(m_analyseButton); horizontalLayout->addItem(spacerItem); @@ -244,17 +254,6 @@ void CSearchDialog::initView() { loadDialogSettings(); } -void CSearchDialog::searchFinished() { - if ( m_searcher.foundItems() ) { - m_searchResultArea->setSearchResult(modules()); - } - else { - m_searchResultArea->reset(); - } - m_staticDialog->raise(); - m_staticDialog->activateWindow(); -} - void CSearchDialog::showModulesSelector() { m_searchOptionsArea->chooseModules(); } diff --git a/src/frontend/searchdialog/csearchdialog.h b/src/frontend/searchdialog/csearchdialog.h index 55bded4..b8c097f 100644 --- a/src/frontend/searchdialog/csearchdialog.h +++ b/src/frontend/searchdialog/csearchdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -15,12 +15,10 @@ #include #include "backend/cswordmodulesearch.h" #include "backend/managers/cswordbackend.h" -#include "util/cpointers.h" - +#include "frontend/searchdialog/btsearchoptionsarea.h" namespace Search { class BtSearchResultArea; -class BtSearchOptionsArea; } class QPushButton; class QWidget; @@ -28,12 +26,15 @@ class QWidget; namespace Search { /** - *@author The BibleTime team - */ + \note destroys itself on close +*/ class CSearchDialog : public QDialog { Q_OBJECT public: - static void openDialog(const QList modules, const QString& searchText = QString::null, QWidget* parentDialog = 0); + static void openDialog(const QList modules, + const QString &searchText = QString::null, + QWidget *parentDialog = 0); + static void closeDialog(); protected: @@ -47,10 +48,6 @@ class CSearchDialog : public QDialog { */ static CSearchDialog* getSearchDialog(); - /** - * The constructor of the dialog. It's protected because you should use the static public function openDialog. - * The dialog destroys itself if it was closed. - */ CSearchDialog(QWidget *parent); ~CSearchDialog(); @@ -58,33 +55,48 @@ class CSearchDialog : public QDialog { * Initializes this object. */ void initView(); + /** - * Starts the search with the given module list and given search text. - * Doesn't wait for the start button press, starts immediately + Starts the search with the given module list and given search text. */ - void startSearch( const QList modules, const QString& searchText); + void startSearch(const QList modules, + const QString &searchText); + /**Prepares the search string given by user for a specific search type */ QString prepareSearchText(const QString& orig); + /** - * Sets the list of modules for the search. + Sets the list of modules for the search. */ - void setModules( const QList modules ); + void setModules(const QList modules) { + m_searchOptionsArea->setModules(modules); + } + /** - * Returns the list of used modules. + Returns the list of used modules. */ - QList modules() const; + inline QList modules() const { + return m_searchOptionsArea->modules(); + } + /** * Sets the search text which is used for the search. */ - void setSearchText( const QString searchText ); + void setSearchText( const QString &searchText ); + /** - * Returns the search text which is set currently. + \returns the search text which is set currently. */ - QString searchText() const; + QString searchText() const { + return m_searchOptionsArea->searchText(); + } + /** - * Returns the used search scope as a list key + \returns the used search scope as a list key */ - sword::ListKey searchScope(); + inline sword::ListKey searchScope() const { + return m_searchOptionsArea->searchScope(); + } /** * Resets the parts to the default. @@ -101,10 +113,10 @@ class CSearchDialog : public QDialog { protected slots: /** - * Starts the search with the set modules and the set search text. + Starts the search with the set modules and the set search text. */ void startSearch(); - void searchFinished(); + void showModulesSelector(); /** * Initializes the signal slot connections diff --git a/src/frontend/searchdialog/csearchmodulechooserdialog.cpp b/src/frontend/searchdialog/csearchmodulechooserdialog.cpp deleted file mode 100644 index d09ae2a..0000000 --- a/src/frontend/searchdialog/csearchmodulechooserdialog.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2007 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/searchdialog/csearchmodulechooserdialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend/btmoduletreeitem.h" -#include "backend/drivers/cswordmoduleinfo.h" -#include "backend/managers/cswordbackend.h" -#include "util/cpointers.h" -#include "util/cresmgr.h" -#include "util/directory.h" - - -namespace Search { - -CSearchModuleChooserDialog::CSearchModuleChooserDialog( QWidget* parent, QString title, QString label, - QList selectedModules) - : CModuleChooserDialog(parent, title, label), - m_selectedModules(selectedModules) { - m_hiddenFilter = new BTModuleTreeItem::HiddenOff(); - QList filters; - filters.append(m_hiddenFilter); - setFilters(filters); - init(); -} - -CSearchModuleChooserDialog::~CSearchModuleChooserDialog() { - //see the ctor - delete m_hiddenFilter; -} - -void CSearchModuleChooserDialog::initModuleItem(BTModuleTreeItem* btItem, QTreeWidgetItem* widgetItem) { - widgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - if (m_selectedModules.contains(btItem->moduleInfo())) - widgetItem->setCheckState(0, Qt::Checked); - else - widgetItem->setCheckState(0, Qt::Unchecked); -} - -} //end of namespace Search diff --git a/src/frontend/searchdialog/csearchmodulechooserdialog.h b/src/frontend/searchdialog/csearchmodulechooserdialog.h deleted file mode 100644 index bfa6126..0000000 --- a/src/frontend/searchdialog/csearchmodulechooserdialog.h +++ /dev/null @@ -1,38 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CSEARCHMODULECHOOSERDIALOG_H -#define CSEARCHMODULECHOOSERDIALOG_H - -#include "frontend/cmodulechooserdialog.h" - - -class BTModuleTreeItem; -class CSwordModuleInfo; -class QTreeWidgetItem; - -namespace Search { - -class CSearchModuleChooserDialog : public CModuleChooserDialog { - Q_OBJECT - public: - CSearchModuleChooserDialog(QWidget* parent, QString title, QString label, QList selectedModules); - ~CSearchModuleChooserDialog(); - - protected: // Protected methods - virtual void initModuleItem(BTModuleTreeItem* btItem, QTreeWidgetItem* widgetItem); - - private: - QList m_selectedModules; - BTModuleTreeItem::HiddenOff* m_hiddenFilter; -}; - -} //end of namespace Search - -#endif diff --git a/src/frontend/searchdialog/csearchresultview.cpp b/src/frontend/searchdialog/csearchresultview.cpp index fc137e2..6f15b62 100644 --- a/src/frontend/searchdialog/csearchresultview.cpp +++ b/src/frontend/searchdialog/csearchresultview.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -93,13 +93,16 @@ void CSearchResultView::initConnections() { } /** Setups the list with the given module. */ -void CSearchResultView::setupTree(CSwordModuleInfo* m) { +void CSearchResultView::setupTree(const CSwordModuleInfo *m, + const sword::ListKey &results) +{ clear(); if (!m) return; m_module = m; - sword::ListKey& result = m->searchResult(); + /// \warning This is a workaround for Sword constness + sword::ListKey &result = const_cast(results); const int count = result.Count(); if (!count) return; @@ -118,24 +121,20 @@ void CSearchResultView::setupTree(CSwordModuleInfo* m) { this->setCurrentItem(this->topLevelItem(0), 0); } -void CSearchResultView::setupStrongsTree(CSwordModuleInfo* m, QStringList* vList) { +void CSearchResultView::setupStrongsTree(CSwordModuleInfo* m, const QStringList &vList) { clear(); - if (!m) { - return; - } + if (!m) return; m_module = m; - if (vList->count() <= 0) { - return; - } + if (vList.empty()) return; setUpdatesEnabled(false); QTreeWidgetItem* oldItem = 0; QTreeWidgetItem* item = 0; - foreach (QString s, *vList) { + foreach (QString s, vList) { item = new QTreeWidgetItem(this, oldItem); item->setText(0, (s)); oldItem = item; @@ -180,13 +179,13 @@ void CSearchResultView::printItems() { void CSearchResultView::saveItems() { CExportManager mgr(tr("Save search result..."), true, tr("Saving search result")); - CSwordModuleInfo* m = module(); + const CSwordModuleInfo *m = module(); CSwordKey* k = 0; QList items = selectedItems(); QList keys; foreach (QTreeWidgetItem* i, items) { k = CSwordKey::createInstance( m ); - k->key(i->text(0)); + k->setKey(i->text(0)); keys.append( k ); } mgr.saveKeyList( keys, CExportManager::Text, false); @@ -198,13 +197,13 @@ void CSearchResultView::saveItems() { void CSearchResultView::saveItemsWithText() { CExportManager mgr(tr("Save search result..."), true, tr("Saving search result")); - CSwordModuleInfo* m = module(); + const CSwordModuleInfo *m = module(); CSwordKey* k = 0; QList items = selectedItems(); QList keys; foreach (QTreeWidgetItem* i, items) { k = CSwordKey::createInstance( m ); - k->key(i->text(0)); + k->setKey(i->text(0)); keys.append( k ); }; mgr.saveKeyList( keys, CExportManager::Text, true); @@ -216,13 +215,13 @@ void CSearchResultView::saveItemsWithText() { void CSearchResultView::copyItems() { CExportManager mgr(tr("Copy search result..."), true, tr("Copying search result")); - CSwordModuleInfo* m = module(); + const CSwordModuleInfo *m = module(); CSwordKey* k = 0; QList items = selectedItems(); QList keys; foreach (QTreeWidgetItem* i, items) { k = CSwordKey::createInstance( m ); - k->key(i->text(0)); + k->setKey(i->text(0)); keys.append( k ); }; mgr.copyKeyList( keys, CExportManager::Text, false); @@ -234,13 +233,13 @@ void CSearchResultView::copyItems() { void CSearchResultView::copyItemsWithText() { CExportManager mgr(tr("Copy search result..."), true, tr("Copying search result")); - CSwordModuleInfo* m = module(); + const CSwordModuleInfo *m = module(); CSwordKey* k = 0; QList items = selectedItems(); QList keys; foreach (QTreeWidgetItem* i, items) { k = CSwordKey::createInstance( m ); - k->key(i->text(0)); + k->setKey(i->text(0)); keys.append( k ); }; mgr.copyKeyList( keys, CExportManager::Text, true); @@ -249,25 +248,21 @@ void CSearchResultView::copyItemsWithText() { keys.clear(); //delete all the keys we created } -CSwordModuleInfo* CSearchResultView::module() { - return m_module; -} - /// \todo port this to the new d'n'd // Q3DragObject* CSearchResultView::dragObject() { -// //return a valid DragObject to make DnD possible! +// //return a valid DragObject to make DnD possible! // -// /* -// * First get all selected items and fill with them the dndItems list. The return the QDragObject we got from CDRagDropMgr -// */ -// CDragDropMgr::ItemList dndItems; +// /* +// * First get all selected items and fill with them the dndItems list. The return the QDragObject we got from CDRagDropMgr +// */ +// CDragDropMgr::ItemList dndItems; // -// Q3PtrList items = selectedItems(); -// for (items.first(); items.current(); items.next()) { -// dndItems.append( CDragDropMgr::Item(m_module->name(), items.current()->text(0), QString::null) ); //no description -// }; +// Q3PtrList items = selectedItems(); +// for (items.first(); items.current(); items.next()) { +// dndItems.append( CDragDropMgr::Item(m_module->name(), items.current()->text(0), QString::null) ); //no description +// }; // -// return CDragDropMgr::dragObject(dndItems, viewport()); +// return CDragDropMgr::dragObject(dndItems, viewport()); // } diff --git a/src/frontend/searchdialog/csearchresultview.h b/src/frontend/searchdialog/csearchresultview.h index 52e6929..b3a09ee 100644 --- a/src/frontend/searchdialog/csearchresultview.h +++ b/src/frontend/searchdialog/csearchresultview.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -10,11 +10,13 @@ #ifndef CSEARCHRESULTSVIEW_H #define CSEARCHRESULTSVIEW_H -class CSwordModuleInfo; - #include +// Sword includes +#include + +class CSwordModuleInfo; class CReadDisplay; class QAction; class QMenu; @@ -26,8 +28,13 @@ class CSearchResultView : public QTreeWidget { public: CSearchResultView(QWidget* parent); virtual ~CSearchResultView(); - /** Returns the module which is currently used. */ - CSwordModuleInfo* module(); + + /** + \returns the module which is currently used. + */ + inline const CSwordModuleInfo *module() const { + return m_module; + } protected: // Protected methods /** @@ -42,11 +49,13 @@ class CSearchResultView : public QTreeWidget { public slots: // Public slots void saveItems(); + /** - * Setups the list with the given module. + Setups the list with the given module. */ - void setupTree(CSwordModuleInfo*); - void setupStrongsTree(CSwordModuleInfo*, QStringList*); + void setupTree(const CSwordModuleInfo *m, const sword::ListKey &results); + + void setupStrongsTree(CSwordModuleInfo*, const QStringList&); void copyItemsWithText(); void copyItems(); void saveItemsWithText(); @@ -88,7 +97,7 @@ class CSearchResultView : public QTreeWidget { m_actions; QMenu* m_popup; - CSwordModuleInfo* m_module; + const CSwordModuleInfo *m_module; signals: // Signals void keySelected(const QString&); diff --git a/src/frontend/settingsdialogs/btfontsettings.cpp b/src/frontend/settingsdialogs/btfontsettings.cpp new file mode 100644 index 0000000..7160e54 --- /dev/null +++ b/src/frontend/settingsdialogs/btfontsettings.cpp @@ -0,0 +1,164 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/settingsdialogs/btfontsettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include "frontend/settingsdialogs/cfontchooser.h" +#include "util/cresmgr.h" +#include "util/tool.h" +#include "util/directory.h" + +// Sword includes: +#include +#include + + +BtFontSettingsPage::BtFontSettingsPage(QWidget *parent) + : BtConfigPage(parent) +{ + namespace DU = util::directory; + + m_languageLabel = new QLabel(tr("&Language:"), this); + + m_languageComboBox = new QComboBox(this); + m_languageComboBox->setToolTip(tr("The font selection below will apply to all texts in this language")); + m_languageLabel->setBuddy(m_languageComboBox); + + m_languageCheckBox = new QCheckBox(tr("Use custom font"), this); + connect(m_languageCheckBox, SIGNAL(toggled(bool)), + this, SLOT(useOwnFontClicked(bool)) ); + + + QHBoxLayout *hLayout = new QHBoxLayout; + hLayout->setContentsMargins(0, 0, 0, 0); + hLayout->addWidget(m_languageLabel, 0, Qt::AlignRight); + hLayout->addWidget(m_languageComboBox, 1); + hLayout->addWidget(m_languageCheckBox); + + CLanguageMgr::LangMap langMap = CLanguageMgr::instance()->availableLanguages(); + + for (CLanguageMgr::LangMapIterator it = langMap.constBegin() ; it != langMap.constEnd(); ++it ) { + const QString name = + (*it)->translatedName().isEmpty() + ? (*it)->abbrev() + : (*it)->translatedName(); + + m_fontMap.insert(name, CBTConfig::get(*it) ); + } + + for ( QMap::Iterator it = m_fontMap.begin(); it != m_fontMap.end(); ++it ) { + if ( m_fontMap[it.key()].first ) { //show font icon + m_languageComboBox->addItem(DU::getIcon("fonts.svg"), it.key() ); + } + else { //don't show icon for font + m_languageComboBox->addItem(it.key()); + } + } + + /// \todo remember the last selected font and jump there. + + m_fontChooser = new CFontChooser(this); + + /// \todo Eeli's wishlist: why not show something relevant here, like a Bible verse in chosen (not tr()'ed!) language? + QString sampleText; + sampleText.append("1 In the beginning God created the heaven and the earth. "); + sampleText.append("2 And the earth was without form, and void; and darkness was on the face of the deep."); + sampleText.append(" And the Spirit of God moved on the face of the waters."); + + m_fontChooser->setSampleText(sampleText); + + connect(m_fontChooser, SIGNAL(fontSelected(const QFont&)), SLOT(newDisplayWindowFontSelected(const QFont&))); + connect(m_languageComboBox, SIGNAL(activated(const QString&)), SLOT(newDisplayWindowFontAreaSelected(const QString&))); + + m_fontChooser->setFont( m_fontMap[m_languageComboBox->currentText()].second ); + useOwnFontClicked( m_fontMap[m_languageComboBox->currentText()].first ); + m_languageCheckBox->setChecked( m_fontMap[m_languageComboBox->currentText()].first ); + m_fontChooser->setMinimumSize(m_fontChooser->sizeHint()); + + QVBoxLayout *fLayout = new QVBoxLayout; + fLayout->setContentsMargins(0, 0, 0, 0); + fLayout->addLayout(hLayout); + fLayout->addWidget(m_fontChooser); + + m_fontsGroupBox = new QGroupBox(tr("Optionally specify a custom font for each language:"), this); + m_fontsGroupBox->setFlat(true); + m_fontsGroupBox->setLayout(fLayout); + + Q_ASSERT(qobject_cast(layout()) != 0); + static_cast(layout())->addWidget(m_fontsGroupBox); +} + + +BtFontSettingsPage::~BtFontSettingsPage() { +} + +void BtFontSettingsPage::save() { + for (QMap::Iterator it = m_fontMap.begin(); it != m_fontMap.end(); ++it ) { + const CLanguageMgr::Language * const lang = CLanguageMgr::instance()->languageForTranslatedName(it.key()); + if (!lang->isValid()) { //we possibly use a language, for which we have only the abbrev + if (!lang->abbrev().isEmpty()) { + CLanguageMgr::Language l(it.key(), it.key(), it.key()); //create a temp language + CBTConfig::set(&l, it.value()); + } + } + else { + CBTConfig::set(lang, it.value()); + } + } +} + +/** */ +void BtFontSettingsPage::newDisplayWindowFontSelected(const QFont &newFont) { + //belongs to the languages/fonts page + CBTConfig::FontSettingsPair oldSettings = m_fontMap[ m_languageComboBox->currentText() ]; + m_fontMap.insert( m_languageComboBox->currentText(), CBTConfig::FontSettingsPair(oldSettings.first, newFont) ); +} + +/** Called when the combobox contents is changed */ +void BtFontSettingsPage::newDisplayWindowFontAreaSelected(const QString& usage) { + //belongs to fonts/languages + useOwnFontClicked( m_fontMap[usage].first ); + m_languageCheckBox->setChecked( m_fontMap[usage].first ); + + m_fontChooser->setFont( m_fontMap[usage].second ); +} + + +/** This slot is called when the "Use own font for language" bo was clicked. */ +void BtFontSettingsPage::useOwnFontClicked(bool isOn) { + namespace DU = util::directory; + + //belongs to fonts/languages + + m_fontChooser->setEnabled(isOn); + m_fontMap[ m_languageComboBox->currentText() ].first = isOn; + + if (isOn) { //show font icon + m_languageComboBox->setItemIcon(m_languageComboBox->currentIndex(), DU::getIcon("fonts.svg")); + } + else { //don't show + m_languageComboBox->setItemText(m_languageComboBox->currentIndex(), m_languageComboBox->currentText() ); /// \todo should this change icon to empty? + } +} + + +const QIcon &BtFontSettingsPage::icon() const { + return util::directory::getIcon(CResMgr::settings::fonts::icon); +} + +QString BtFontSettingsPage::header() const { + return tr("Fonts"); +} diff --git a/src/frontend/settingsdialogs/btfontsettings.h b/src/frontend/settingsdialogs/btfontsettings.h new file mode 100644 index 0000000..9df4bc5 --- /dev/null +++ b/src/frontend/settingsdialogs/btfontsettings.h @@ -0,0 +1,62 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTFONTSETTINGS_H +#define BTFONTSETTINGS_H + +#include "frontend/bookshelfmanager/btconfigdialog.h" + +#include +#include +#include "backend/config/cbtconfig.h" + + +class CFontChooser; +class QCheckBox; +class QComboBox; +class QGroupBox; + +/** + @author The BibleTime team +*/ +class BtFontSettingsPage : public BtConfigPage { + Q_OBJECT + public: + BtFontSettingsPage(QWidget *parent = 0); + ~BtFontSettingsPage(); + void save(); + + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; + + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; + + protected slots: + + // This slot is called when the "Use own font for language" button was clicked. + void useOwnFontClicked(bool); + + // Called when a new font in the fonts page was selected. + void newDisplayWindowFontSelected(const QFont &); + + // Called when the combobox contents is changed + void newDisplayWindowFontAreaSelected(const QString&); + + private: + QGroupBox *m_fontsGroupBox; + QLabel *m_languageLabel; + QComboBox *m_languageComboBox; + QCheckBox *m_languageCheckBox; + CFontChooser* m_fontChooser; + + QMap m_fontMap; +}; + +#endif diff --git a/src/frontend/settingsdialogs/btlanguagesettings.cpp b/src/frontend/settingsdialogs/btlanguagesettings.cpp new file mode 100644 index 0000000..dc31d0b --- /dev/null +++ b/src/frontend/settingsdialogs/btlanguagesettings.cpp @@ -0,0 +1,145 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "frontend/settingsdialogs/btlanguagesettings.h" + +#include +#include +#include +#include +#include + +#include "util/cresmgr.h" +#include "util/tool.h" +#include "util/directory.h" + +// Sword includes: +#include +#include + + +BtLanguageSettingsPage::BtLanguageSettingsPage(QWidget *parent) + : BtConfigPage(parent) +{ + namespace DU = util::directory; + + Q_ASSERT(qobject_cast(layout()) != 0); + QVBoxLayout *mainLayout = static_cast(layout()); + + //Sword locales + m_swordLocaleCombo = new QComboBox(this); + QLabel* label = new QLabel( tr("Language for names of Bible books:"), this); + label->setBuddy(m_swordLocaleCombo); + m_swordLocaleCombo->setToolTip(tr("The languages which can be used for the biblical booknames")); + + + QHBoxLayout* hBoxLayout = new QHBoxLayout(); + hBoxLayout->addWidget(label); + hBoxLayout->addWidget(m_swordLocaleCombo); + hBoxLayout->addStretch(); + mainLayout->addLayout(hBoxLayout); + + mainLayout->addSpacerItem(new QSpacerItem(1,1, QSizePolicy::Fixed, QSizePolicy::Expanding)); + + QStringList languageNames; + languageNames.append(CLanguageMgr::instance()->languageForAbbrev("en_US")->translatedName()); + + std::list locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); + for (std::list::const_iterator it = locales.begin(); it != locales.end(); it++) { + // qWarning("working on %s", (*it).c_str()); + const CLanguageMgr::Language * const l = + CLanguageMgr::instance()->languageForAbbrev( sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getName() ); + + if (l->isValid()) { + languageNames.append( l->translatedName() ); + } + else { + languageNames.append( + sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getDescription() + ); + } + } //for + + languageNames.sort(); + m_swordLocaleCombo->addItems( languageNames ); + + const CLanguageMgr::Language * const l = + CLanguageMgr::instance()->languageForAbbrev( CBTConfig::get(CBTConfig::language) ); + + QString currentLanguageName; + if ( l->isValid() && languageNames.contains(l->translatedName()) ) { //tranlated language name is in the box + currentLanguageName = l->translatedName(); + } + else { //a language like "German Abbrevs" might be the language to set + sword::SWLocale* locale = + sword::LocaleMgr::getSystemLocaleMgr()->getLocale( CBTConfig::get(CBTConfig::language).toLocal8Bit() ); + if (locale) { + currentLanguageName = QString::fromLatin1(locale->getDescription()); + } + } + + if (currentLanguageName.isEmpty()) { // set english as default if nothing was chosen + Q_ASSERT(CLanguageMgr::instance()->languageForAbbrev("en_US")); + currentLanguageName = CLanguageMgr::instance()->languageForAbbrev("en_US")->translatedName(); + } + + //now set the item with the right name as current item + for (int i = 0; i < m_swordLocaleCombo->count(); ++i) { + if (currentLanguageName == m_swordLocaleCombo->itemText(i)) { + m_swordLocaleCombo->setCurrentIndex(i); + break; //item found, finish the loop + } + } + +} + + +BtLanguageSettingsPage::~BtLanguageSettingsPage() { +} + +void BtLanguageSettingsPage::save() { + + QString languageAbbrev; + + const QString currentLanguageName = m_swordLocaleCombo->currentText(); + const CLanguageMgr::Language * const l = CLanguageMgr::instance()->languageForTranslatedName( currentLanguageName ); + + if (l && l->isValid()) { + languageAbbrev = l->abbrev(); + } + else { //it can be the lang abbrev like de_abbrev or the Sword description + std::list locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); + + for (std::list ::iterator it = locales.begin(); it != locales.end(); it++) { + sword::SWLocale* locale = sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str()); + Q_ASSERT(locale); + + if ( locale && (QString::fromLatin1(locale->getDescription()) == currentLanguageName) ) { + languageAbbrev = QString::fromLatin1(locale->getName()); //we found the abbrevation for the current language + break; + } + } + + if (languageAbbrev.isEmpty()) { + languageAbbrev = currentLanguageName; //probably a non-standard locale name like de_abbrev + } + } + + if (!languageAbbrev.isEmpty()) { + CBTConfig::set(CBTConfig::language, languageAbbrev); + } +} + +const QIcon &BtLanguageSettingsPage::icon() const { + return util::directory::getIcon(CResMgr::settings::languages::icon); +} + +QString BtLanguageSettingsPage::header() const { + return tr("Languages"); +} diff --git a/src/frontend/settingsdialogs/btlanguagesettings.h b/src/frontend/settingsdialogs/btlanguagesettings.h new file mode 100644 index 0000000..911e466 --- /dev/null +++ b/src/frontend/settingsdialogs/btlanguagesettings.h @@ -0,0 +1,60 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTLANGUAGESETTINGS_H +#define BTLANGUAGESETTINGS_H + +#include "frontend/bookshelfmanager/btconfigdialog.h" + +#include +#include +#include "backend/config/cbtconfig.h" + + +//class CFontChooser; +//class QCheckBox; +class QComboBox; + +/** + @author The BibleTime team +*/ +class BtLanguageSettingsPage : public BtConfigPage { + Q_OBJECT + public: + BtLanguageSettingsPage(QWidget *parent = 0); + ~BtLanguageSettingsPage(); + void save(); + + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; + + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; + + protected slots: + + // This slot is called when the "Use own font for language" button was clicked. + //void useOwnFontClicked(bool); + + // Called when a new font in the fonts page was selected. + //void newDisplayWindowFontSelected(const QFont &); + + // Called when the combobox contents is changed + //void newDisplayWindowFontAreaSelected(const QString&); + + private: + QComboBox* m_swordLocaleCombo; + //QComboBox* m_usageCombo; + //QCheckBox* m_useOwnFontCheck; + //CFontChooser* m_fontChooser; + + //QMap m_fontMap; +}; + +#endif diff --git a/src/frontend/settingsdialogs/btshortcutsdialog.cpp b/src/frontend/settingsdialogs/btshortcutsdialog.cpp index ec92855..a5d856d 100644 --- a/src/frontend/settingsdialogs/btshortcutsdialog.cpp +++ b/src/frontend/settingsdialogs/btshortcutsdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,7 +21,6 @@ // *************** BtShortcutsDialog *************************************************************************** // A dialog to allow the user to input a shortcut for a primary and alternate key -// dialog constructor BtShortcutsDialog::BtShortcutsDialog(QWidget* parent) : QDialog(parent), m_primaryLabel(0), m_alternateLabel(0), m_primaryButton(0), m_alternateButton(0) { setWindowTitle(tr("Configure shortcuts")); diff --git a/src/frontend/settingsdialogs/btshortcutsdialog.h b/src/frontend/settingsdialogs/btshortcutsdialog.h index 53f738c..f475ebd 100644 --- a/src/frontend/settingsdialogs/btshortcutsdialog.h +++ b/src/frontend/settingsdialogs/btshortcutsdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/btshortcutseditor.cpp b/src/frontend/settingsdialogs/btshortcutseditor.cpp index f92a27e..d8fdfd8 100644 --- a/src/frontend/settingsdialogs/btshortcutseditor.cpp +++ b/src/frontend/settingsdialogs/btshortcutseditor.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -157,10 +157,8 @@ void BtShortcutsEditor::commitChanges() { void BtShortcutsEditor::addCollection(BtActionCollection* collection, const QString& title) { Q_UNUSED(title); /// \todo Is this correct? - QList actionList = collection->actions(); - int count; - count = actionList.count(); foreach (QAction *action, collection->actions()) { + /// \todo Is the following check really necessary? if (action) { int count = m_table->rowCount(); m_table->insertRow(count); diff --git a/src/frontend/settingsdialogs/btshortcutseditor.h b/src/frontend/settingsdialogs/btshortcutseditor.h index 93e2bfc..f9a812a 100644 --- a/src/frontend/settingsdialogs/btshortcutseditor.h +++ b/src/frontend/settingsdialogs/btshortcutseditor.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -33,7 +33,7 @@ class BtShortcutsEditor : public QWidget { void commitChanges(); // puts actions and shortcut keys into QTableWidget - void addCollection(BtActionCollection* collection, const QString& title = QString()); + void addCollection(BtActionCollection *collection, const QString &title = QString::null); // clears any shortcut keys in the table matching the specified keys void clearConflictWithKeys(const QString& keys); diff --git a/src/frontend/settingsdialogs/cacceleratorsettings.cpp b/src/frontend/settingsdialogs/cacceleratorsettings.cpp index 636b9cc..15394fb 100644 --- a/src/frontend/settingsdialogs/cacceleratorsettings.cpp +++ b/src/frontend/settingsdialogs/cacceleratorsettings.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -26,12 +26,14 @@ #include "frontend/displaywindow/clexiconreadwindow.h" #include "frontend/displaywindow/creadwindow.h" #include "util/cresmgr.h" +#include "util/directory.h" -CAcceleratorSettingsPage::CAcceleratorSettingsPage(QWidget* /* parent */ ) - : BtConfigPage() { - QVBoxLayout* mainLayout = new QVBoxLayout(this); - this->setLayout(mainLayout); +CAcceleratorSettingsPage::CAcceleratorSettingsPage(QWidget *parent) + : BtConfigPage(parent) +{ + Q_ASSERT(qobject_cast(layout()) != 0); + QVBoxLayout *mainLayout = static_cast(layout()); QHBoxLayout* layoutForWindowTypeChooser = new QHBoxLayout(); mainLayout->addLayout(layoutForWindowTypeChooser); @@ -97,7 +99,7 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(QWidget* /* parent */ ) // ----- Commentary windows ------ // m_commentary.actionCollection = new BtActionCollection(this); CCommentaryReadWindow::insertKeyboardActions( m_commentary.actionCollection); - CBTConfig::setupAccelSettings(CBTConfig::commentaryWindow, m_commentary.actionCollection); + CBTConfig::setupAccelSettings(CBTConfig::commentaryWindow, m_commentary.actionCollection); m_commentary.keyChooser = new BtShortcutsEditor(m_commentary.actionCollection, m_keyChooserStack); m_keyChooserStack->addWidget(m_commentary.keyChooser); ok = connect(m_commentary.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), @@ -108,7 +110,7 @@ CAcceleratorSettingsPage::CAcceleratorSettingsPage(QWidget* /* parent */ ) m_lexicon.actionCollection = new BtActionCollection(this); CLexiconReadWindow::insertKeyboardActions( m_lexicon.actionCollection ); CBTConfig::setupAccelSettings(CBTConfig::lexiconWindow, m_lexicon.actionCollection); - m_lexicon.keyChooser = new BtShortcutsEditor(m_lexicon.actionCollection, m_keyChooserStack ); + m_lexicon.keyChooser = new BtShortcutsEditor(m_lexicon.actionCollection, m_keyChooserStack ); m_keyChooserStack->addWidget(m_lexicon.keyChooser); ok = connect(m_lexicon.keyChooser, SIGNAL(keyChangeRequest(BtShortcutsEditor*, const QString&)), this, SLOT(completeKeyChangeRequest(BtShortcutsEditor*, const QString&))); @@ -195,7 +197,7 @@ QString CAcceleratorSettingsPage::getTitleForEditor(BtShortcutsEditor* editor) { return m_lexicon.title; if (editor == m_book.keyChooser) return m_book.title; - return QString(); + return QString::null; } // Gets list of shortcuts editors that can conflict with a key change in the current shortcut editor @@ -230,12 +232,12 @@ void CAcceleratorSettingsPage::save() { if (m_book.keyChooser) m_book.keyChooser->commitChanges(); - CBTConfig::saveAccelSettings(CBTConfig::application, m_application.actionCollection); //application - CBTConfig::saveAccelSettings(CBTConfig::allWindows, m_general.actionCollection); //read display windows - CBTConfig::saveAccelSettings(CBTConfig::bibleWindow, m_bible.actionCollection); //bible - CBTConfig::saveAccelSettings(CBTConfig::commentaryWindow, m_commentary.actionCollection); //commentary - CBTConfig::saveAccelSettings(CBTConfig::lexiconWindow, m_lexicon.actionCollection); //lexicon - CBTConfig::saveAccelSettings(CBTConfig::bookWindow, m_book.actionCollection); //book + CBTConfig::saveAccelSettings(CBTConfig::application, m_application.actionCollection); //application + CBTConfig::saveAccelSettings(CBTConfig::allWindows, m_general.actionCollection); //read display windows + CBTConfig::saveAccelSettings(CBTConfig::bibleWindow, m_bible.actionCollection); //bible + CBTConfig::saveAccelSettings(CBTConfig::commentaryWindow, m_commentary.actionCollection); //commentary + CBTConfig::saveAccelSettings(CBTConfig::lexiconWindow, m_lexicon.actionCollection); //lexicon + CBTConfig::saveAccelSettings(CBTConfig::bookWindow, m_book.actionCollection); //book } void CAcceleratorSettingsPage::slotKeyChooserTypeChanged(const QString& title) { @@ -246,15 +248,10 @@ void CAcceleratorSettingsPage::slotKeyChooserTypeChanged(const QString& title) { } -QString CAcceleratorSettingsPage::iconName() { - return CResMgr::settings::keys::icon; +const QIcon &CAcceleratorSettingsPage::icon() const { + return util::directory::getIcon(CResMgr::settings::keys::icon); } -QString CAcceleratorSettingsPage::label() { - //: Empty string, don't translate - return tr(""); -} - -QString CAcceleratorSettingsPage::header() { +QString CAcceleratorSettingsPage::header() const { return tr("Shortcuts"); } diff --git a/src/frontend/settingsdialogs/cacceleratorsettings.h b/src/frontend/settingsdialogs/cacceleratorsettings.h index 74401ab..999e3d0 100644 --- a/src/frontend/settingsdialogs/cacceleratorsettings.h +++ b/src/frontend/settingsdialogs/cacceleratorsettings.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,7 +11,6 @@ #define CACCELERATORSETTINGS_H #include "frontend/bookshelfmanager/btconfigdialog.h" -#include "util/cpointers.h" #include #include @@ -26,15 +25,18 @@ class QStackedWidget; /** @author The BibleTime team */ -class CAcceleratorSettingsPage : public BtConfigPage, CPointers { +class CAcceleratorSettingsPage : public BtConfigPage { Q_OBJECT public: - CAcceleratorSettingsPage(QWidget *parent); + CAcceleratorSettingsPage(QWidget *parent = 0); ~CAcceleratorSettingsPage(); void save(); - QString iconName(); - QString label(); - QString header(); + + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; + + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; protected slots: diff --git a/src/frontend/settingsdialogs/cconfigurationdialog.cpp b/src/frontend/settingsdialogs/cconfigurationdialog.cpp index f127883..e1d68ca 100644 --- a/src/frontend/settingsdialogs/cconfigurationdialog.cpp +++ b/src/frontend/settingsdialogs/cconfigurationdialog.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,9 +16,9 @@ #include #include "frontend/settingsdialogs/cacceleratorsettings.h" #include "frontend/settingsdialogs/cdisplaysettings.h" -#include "frontend/settingsdialogs/clanguagesettings.h" +#include "frontend/settingsdialogs/btfontsettings.h" +#include "frontend/settingsdialogs/btlanguagesettings.h" #include "frontend/settingsdialogs/cswordsettings.h" -#include "util/cpointers.h" #include "util/cresmgr.h" #include "util/directory.h" #include "util/dialogutil.h" @@ -30,6 +30,7 @@ CConfigurationDialog::CConfigurationDialog(QWidget * parent, BtActionCollection* m_displayPage(0), m_swordPage(0), m_acceleratorsPage(0), + m_fontsPage(0), m_languagesPage(0), m_bbox(0) { setWindowTitle(tr("Configure BibleTime")); @@ -43,10 +44,14 @@ CConfigurationDialog::CConfigurationDialog(QWidget * parent, BtActionCollection* m_swordPage = new CSwordSettingsPage(this); addPage(m_swordPage); - // Add "Languages" (fonts) page - m_languagesPage = new CLanguageSettingsPage(this); + // Add "Languages" page + m_languagesPage = new BtLanguageSettingsPage(this); addPage(m_languagesPage); + // Add "Fonts" page + m_fontsPage = new BtFontSettingsPage(this); + addPage(m_fontsPage); + // Add "Keyboard" (accelerators) page m_acceleratorsPage = new CAcceleratorSettingsPage(this); addPage(m_acceleratorsPage); @@ -74,6 +79,7 @@ CConfigurationDialog::~CConfigurationDialog() { void CConfigurationDialog::save() { m_acceleratorsPage->save(); m_languagesPage->save(); + m_fontsPage->save(); m_swordPage->save(); m_displayPage->save(); emit signalSettingsChanged( ); diff --git a/src/frontend/settingsdialogs/cconfigurationdialog.h b/src/frontend/settingsdialogs/cconfigurationdialog.h index 6b423e4..e0fbf93 100644 --- a/src/frontend/settingsdialogs/cconfigurationdialog.h +++ b/src/frontend/settingsdialogs/cconfigurationdialog.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -16,7 +16,8 @@ class BtActionCollection; class CAcceleratorSettingsPage; class CDisplaySettingsPage; -class CLanguageSettingsPage; +class BtFontSettingsPage; +class BtLanguageSettingsPage; class CSwordSettingsPage; class QAbstractButton; class QDialogButtonBox; @@ -37,7 +38,8 @@ class CConfigurationDialog : public BtConfigDialog { CDisplaySettingsPage* m_displayPage; CSwordSettingsPage* m_swordPage; CAcceleratorSettingsPage* m_acceleratorsPage; - CLanguageSettingsPage* m_languagesPage; + BtFontSettingsPage* m_fontsPage; + BtLanguageSettingsPage* m_languagesPage; QDialogButtonBox* m_bbox; // Load the settings from the resource file diff --git a/src/frontend/settingsdialogs/cdisplaysettings.cpp b/src/frontend/settingsdialogs/cdisplaysettings.cpp index 9341632..dd390a6 100644 --- a/src/frontend/settingsdialogs/cdisplaysettings.cpp +++ b/src/frontend/settingsdialogs/cdisplaysettings.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -17,8 +17,8 @@ #include "backend/config/cbtconfig.h" #include "backend/managers/cdisplaytemplatemgr.h" #include "backend/rendering/cdisplayrendering.h" -#include "util/cpointers.h" #include "util/cresmgr.h" +#include "util/directory.h" #include "util/tool.h" @@ -44,9 +44,11 @@ QSize CWebViewerWidget::sizeHint () const { // ************************ /** Initializes the startup section of the OD. */ -CDisplaySettingsPage::CDisplaySettingsPage(QWidget* /*parent*/) - : BtConfigPage() { - QVBoxLayout* layout = new QVBoxLayout(this); +CDisplaySettingsPage::CDisplaySettingsPage(QWidget *parent) + : BtConfigPage(parent) +{ + Q_ASSERT(qobject_cast(layout()) != 0); + QVBoxLayout *mainLayout = static_cast(layout()); { //startup logo m_showLogoCheck = new QCheckBox(this); @@ -54,11 +56,11 @@ CDisplaySettingsPage::CDisplaySettingsPage(QWidget* /*parent*/) m_showLogoCheck->setToolTip(tr("Show the BibleTime logo on startup")); m_showLogoCheck->setChecked(CBTConfig::get(CBTConfig::logo)); - layout->addWidget(m_showLogoCheck); + mainLayout->addWidget(m_showLogoCheck); } - layout->addSpacing(20); + mainLayout->addSpacing(20); - layout->addWidget( + mainLayout->addWidget( util::tool::explanationLabel( this, tr("Display templates"), @@ -77,7 +79,7 @@ CDisplaySettingsPage::CDisplaySettingsPage(QWidget* /*parent*/) hboxlayout->addWidget(availableLabel); hboxlayout->addWidget( m_styleChooserCombo ); hboxlayout->addStretch(); - layout->addLayout( hboxlayout ); + mainLayout->addLayout( hboxlayout ); QWidget* webViewWidget = new CWebViewerWidget(this); QLayout* webViewLayout = new QVBoxLayout(webViewWidget); @@ -87,10 +89,10 @@ CDisplaySettingsPage::CDisplaySettingsPage(QWidget* /*parent*/) webViewLayout->addWidget(previewLabel); webViewLayout->addWidget(m_stylePreviewViewer); webViewWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - layout->addWidget(webViewWidget); + mainLayout->addWidget(webViewWidget); m_styleChooserCombo->addItems( - CPointers::displayTemplateManager()->availableTemplates() + CDisplayTemplateMgr::instance()->availableTemplates() ); for (int i = 0; i < m_styleChooserCombo->count(); ++i) { @@ -137,7 +139,7 @@ void CDisplaySettingsPage::updateStylePreview() { tree.append( new CTextRendering::KeyTreeItem( QString("\n19%1") - .arg(tr("This is the judgment, that the light has come into the world, and men loved the darkness rather than the light; for their works were evil.")), + .arg(tr("This is the judgement, that the light has come into the world, and men loved the darkness rather than the light; for their works were evil.")), settings)); tree.append( new CTextRendering::KeyTreeItem( @@ -173,14 +175,11 @@ void CDisplaySettingsPage::save() { // implement the BtConfigPage methods -QString CDisplaySettingsPage::iconName() { - return CResMgr::settings::startup::icon; +const QIcon &CDisplaySettingsPage::icon() const { + return util::directory::getIcon(CResMgr::settings::startup::icon); } -QString CDisplaySettingsPage::label() { - //: Empty string, don't translate - return tr(""); -} -QString CDisplaySettingsPage::header() { + +QString CDisplaySettingsPage::header() const { return tr("Display"); } diff --git a/src/frontend/settingsdialogs/cdisplaysettings.h b/src/frontend/settingsdialogs/cdisplaysettings.h index be9a359..fe46679 100644 --- a/src/frontend/settingsdialogs/cdisplaysettings.h +++ b/src/frontend/settingsdialogs/cdisplaysettings.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,11 +22,14 @@ class QWebView; class CDisplaySettingsPage : public BtConfigPage { Q_OBJECT public: - CDisplaySettingsPage(QWidget* parent); + CDisplaySettingsPage(QWidget *parent = 0); void save(); - QString iconName(); - QString label(); - QString header(); + + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; + + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; protected slots: /** Update the style preview widget. */ diff --git a/src/frontend/settingsdialogs/cfontchooser.cpp b/src/frontend/settingsdialogs/cfontchooser.cpp index 786847b..81a8868 100644 --- a/src/frontend/settingsdialogs/cfontchooser.cpp +++ b/src/frontend/settingsdialogs/cfontchooser.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/cfontchooser.h b/src/frontend/settingsdialogs/cfontchooser.h index fc5b8dd..0ebed51 100644 --- a/src/frontend/settingsdialogs/cfontchooser.h +++ b/src/frontend/settingsdialogs/cfontchooser.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/clanguagesettings.cpp b/src/frontend/settingsdialogs/clanguagesettings.cpp deleted file mode 100644 index a54a023..0000000 --- a/src/frontend/settingsdialogs/clanguagesettings.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "frontend/settingsdialogs/clanguagesettings.h" - -#include -#include -#include -#include -#include -#include -#include "frontend/settingsdialogs/cfontchooser.h" -#include "util/cpointers.h" -#include "util/cresmgr.h" -#include "util/tool.h" -#include "util/directory.h" - -// Sword includes: -#include -#include - - -CLanguageSettingsPage::CLanguageSettingsPage(QWidget* /*parent*/) - : BtConfigPage() { - namespace DU = util::directory; - - QVBoxLayout* layout = new QVBoxLayout(this); - - //Sword locales - layout->addWidget( - util::tool::explanationLabel( - this, - tr(""), - tr("Select the language in which the Biblical book names are displayed.") - )); - - m_swordLocaleCombo = new QComboBox(this); - QLabel* label = new QLabel( tr("Language for names of Bible books:"), this); - label->setBuddy(m_swordLocaleCombo); - m_swordLocaleCombo->setToolTip(tr("The languages which can be used for the biblical booknames")); - - - QHBoxLayout* hBoxLayout = new QHBoxLayout(); - hBoxLayout->addWidget(label); - hBoxLayout->addWidget(m_swordLocaleCombo); - hBoxLayout->addStretch(); - layout->addLayout(hBoxLayout); - - QStringList languageNames; - languageNames.append( languageMgr()->languageForAbbrev("en_US")->translatedName() ); - - std::list locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); - for (std::list::const_iterator it = locales.begin(); it != locales.end(); it++) { - // qWarning("working on %s", (*it).c_str()); - const CLanguageMgr::Language* const l = - CPointers::languageMgr()->languageForAbbrev( sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getName() ); - - if (l->isValid()) { - languageNames.append( l->translatedName() ); - } - else { - languageNames.append( - sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str())->getDescription() - ); - } - } //for - - languageNames.sort(); - m_swordLocaleCombo->addItems( languageNames ); - - const CLanguageMgr::Language* const l = - CPointers::languageMgr()->languageForAbbrev( CBTConfig::get(CBTConfig::language) ); - - QString currentLanguageName; - if ( l->isValid() && languageNames.contains(l->translatedName()) ) { //tranlated language name is in the box - currentLanguageName = l->translatedName(); - } - else { //a language like "German Abbrevs" might be the language to set - sword::SWLocale* locale = - sword::LocaleMgr::getSystemLocaleMgr()->getLocale( CBTConfig::get(CBTConfig::language).toLocal8Bit() ); - if (locale) { - currentLanguageName = QString::fromLatin1(locale->getDescription()); - } - } - - if (currentLanguageName.isEmpty()) { // set english as default if nothing was chosen - Q_ASSERT(languageMgr()->languageForAbbrev("en_US")); - currentLanguageName = languageMgr()->languageForAbbrev("en_US")->translatedName(); - } - - //now set the item with the right name as current item - for (int i = 0; i < m_swordLocaleCombo->count(); ++i) { - if (currentLanguageName == m_swordLocaleCombo->itemText(i)) { - m_swordLocaleCombo->setCurrentIndex(i); - break; //item found, finish the loop - } - } - - layout->addSpacing(20); - - //Font settings - - layout->addWidget( - util::tool::explanationLabel( - this, - tr("Fonts"), - tr("You can specify a custom font for each language.") - ) - ); - QHBoxLayout* hLayout = new QHBoxLayout(); - - m_usageCombo = new QComboBox(this); - m_usageCombo->setToolTip(tr("The font selection below will apply to all texts in this language")); - - hLayout->addWidget(m_usageCombo); - - CLanguageMgr::LangMap langMap = languageMgr()->availableLanguages(); - - for (CLanguageMgr::LangMapIterator it = langMap.constBegin() ; it != langMap.constEnd(); ++it ) { - const QString name = - (*it)->translatedName().isEmpty() - ? (*it)->abbrev() - : (*it)->translatedName(); - - m_fontMap.insert(name, CBTConfig::get(*it) ); - } - - for ( QMap::Iterator it = m_fontMap.begin(); it != m_fontMap.end(); ++it ) { - if ( m_fontMap[it.key()].first ) { //show font icon - m_usageCombo->addItem(DU::getIcon("fonts.svg"), it.key() ); - } - else { //don't show icon for font - m_usageCombo->addItem(it.key()); - } - } - - m_useOwnFontCheck = new QCheckBox(tr("Use custom font"), this); - m_useOwnFontCheck->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - connect(m_useOwnFontCheck, SIGNAL(toggled(bool)), SLOT(useOwnFontClicked(bool)) ); - hLayout->addWidget(m_useOwnFontCheck); - - layout->addLayout(hLayout); - hLayout->setContentsMargins(0, 0, 0, 0); - /// \todo remember the last selected font and jump there. - - m_fontChooser = new CFontChooser(this); - - /// \todo Eeli's wishlist: why not show something relevant here, like a Bible verse in chosen (not tr()'ed!) language? - QString sampleText; - sampleText.append("1 In the beginning God created the heaven and the earth. "); - sampleText.append("2 And the earth was without form, and void; and darkness was on the face of the deep."); - sampleText.append(" And the Spirit of God moved on the face of the waters."); - - m_fontChooser->setSampleText(sampleText); - layout->addWidget(m_fontChooser); - - connect(m_fontChooser, SIGNAL(fontSelected(const QFont&)), SLOT(newDisplayWindowFontSelected(const QFont&))); - connect(m_usageCombo, SIGNAL(activated(const QString&)), SLOT(newDisplayWindowFontAreaSelected(const QString&))); - - m_fontChooser->setFont( m_fontMap[m_usageCombo->currentText()].second ); - useOwnFontClicked( m_fontMap[m_usageCombo->currentText()].first ); - m_useOwnFontCheck->setChecked( m_fontMap[m_usageCombo->currentText()].first ); - m_fontChooser->setMinimumSize(m_fontChooser->sizeHint()); -} - - -CLanguageSettingsPage::~CLanguageSettingsPage() { -} - -void CLanguageSettingsPage::save() { - for (QMap::Iterator it = m_fontMap.begin(); it != m_fontMap.end(); ++it ) { - const CLanguageMgr::Language* const lang = languageMgr()->languageForTranslatedName(it.key()); - if (!lang->isValid()) { //we possibly use a language, for which we have only the abbrev - if (!lang->abbrev().isEmpty()) { - CLanguageMgr::Language l(it.key(), it.key(), it.key()); //create a temp language - CBTConfig::set(&l, it.value()); - } - } - else { - CBTConfig::set(lang, it.value()); - } - } - - - QString languageAbbrev; - - const QString currentLanguageName = m_swordLocaleCombo->currentText(); - const CLanguageMgr::Language* const l = CPointers::languageMgr()->languageForTranslatedName( currentLanguageName ); - - if (l && l->isValid()) { - languageAbbrev = l->abbrev(); - } - else { //it can be the lang abbrev like de_abbrev or the Sword description - std::list locales = sword::LocaleMgr::getSystemLocaleMgr()->getAvailableLocales(); - - for (std::list ::iterator it = locales.begin(); it != locales.end(); it++) { - sword::SWLocale* locale = sword::LocaleMgr::getSystemLocaleMgr()->getLocale((*it).c_str()); - Q_ASSERT(locale); - - if ( locale && (QString::fromLatin1(locale->getDescription()) == currentLanguageName) ) { - languageAbbrev = QString::fromLatin1(locale->getName()); //we found the abbrevation for the current language - break; - } - } - - if (languageAbbrev.isEmpty()) { - languageAbbrev = currentLanguageName; //probably a non-standard locale name like de_abbrev - } - } - - if (!languageAbbrev.isEmpty()) { - CBTConfig::set(CBTConfig::language, languageAbbrev); - } -} - -/** */ -void CLanguageSettingsPage::newDisplayWindowFontSelected(const QFont &newFont) { - //belongs to the languages/fonts page - CBTConfig::FontSettingsPair oldSettings = m_fontMap[ m_usageCombo->currentText() ]; - m_fontMap.insert( m_usageCombo->currentText(), CBTConfig::FontSettingsPair(oldSettings.first, newFont) ); -} - -/** Called when the combobox contents is changed */ -void CLanguageSettingsPage::newDisplayWindowFontAreaSelected(const QString& usage) { - //belongs to fonts/languages - useOwnFontClicked( m_fontMap[usage].first ); - m_useOwnFontCheck->setChecked( m_fontMap[usage].first ); - - m_fontChooser->setFont( m_fontMap[usage].second ); -} - - -/** This slot is called when the "Use own font for language" bo was clicked. */ -void CLanguageSettingsPage::useOwnFontClicked(bool isOn) { - namespace DU = util::directory; - - //belongs to fonts/languages - - m_fontChooser->setEnabled(isOn); - m_fontMap[ m_usageCombo->currentText() ].first = isOn; - - if (isOn) { //show font icon - m_usageCombo->setItemIcon(m_usageCombo->currentIndex(), DU::getIcon("fonts.svg")); - } - else { //don't show - m_usageCombo->setItemText(m_usageCombo->currentIndex(), m_usageCombo->currentText() ); /// \todo should this change icon to empty? - } -} - - -QString CLanguageSettingsPage::iconName() { - return CResMgr::settings::fonts::icon; -} -QString CLanguageSettingsPage::label() { - //: Empty string, don't translate - return tr(""); -} -QString CLanguageSettingsPage::header() { - return tr("Languages"); -} diff --git a/src/frontend/settingsdialogs/clanguagesettings.h b/src/frontend/settingsdialogs/clanguagesettings.h deleted file mode 100644 index 4d55cda..0000000 --- a/src/frontend/settingsdialogs/clanguagesettings.h +++ /dev/null @@ -1,58 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2009 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CLANGUAGESETTINGS_H -#define CLANGUAGESETTINGS_H - -#include "frontend/bookshelfmanager/btconfigdialog.h" -#include "util/cpointers.h" - -#include -#include -#include "backend/config/cbtconfig.h" - - -class CFontChooser; -class QCheckBox; -class QComboBox; - -/** - @author The BibleTime team -*/ -class CLanguageSettingsPage : public BtConfigPage, CPointers { - Q_OBJECT - public: - CLanguageSettingsPage(QWidget *parent); - ~CLanguageSettingsPage(); - void save(); - QString iconName(); - QString label(); - QString header(); - - protected slots: - - // This slot is called when the "Use own font for language" button was clicked. - void useOwnFontClicked(bool); - - // Called when a new font in the fonts page was selected. - void newDisplayWindowFontSelected(const QFont &); - - // Called when the combobox contents is changed - void newDisplayWindowFontAreaSelected(const QString&); - - private: - QComboBox* m_swordLocaleCombo; - QComboBox* m_usageCombo; - QCheckBox* m_useOwnFontCheck; - CFontChooser* m_fontChooser; - - QMap m_fontMap; -}; - -#endif diff --git a/src/frontend/settingsdialogs/clistwidget.cpp b/src/frontend/settingsdialogs/clistwidget.cpp index 44cc246..3a2a4c7 100644 --- a/src/frontend/settingsdialogs/clistwidget.cpp +++ b/src/frontend/settingsdialogs/clistwidget.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/clistwidget.h b/src/frontend/settingsdialogs/clistwidget.h index 0011f93..ecd5f98 100644 --- a/src/frontend/settingsdialogs/clistwidget.h +++ b/src/frontend/settingsdialogs/clistwidget.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/frontend/settingsdialogs/cswordsettings.cpp b/src/frontend/settingsdialogs/cswordsettings.cpp index c6a5bcc..39e48e8 100644 --- a/src/frontend/settingsdialogs/cswordsettings.cpp +++ b/src/frontend/settingsdialogs/cswordsettings.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -21,16 +21,18 @@ #include #include "backend/config/cbtconfig.h" #include "util/cresmgr.h" +#include "util/directory.h" #include "util/tool.h" -#include "util/cpointers.h" -CSwordSettingsPage::CSwordSettingsPage(QWidget* /*parent*/) - : BtConfigPage() { - QVBoxLayout* vbox = new QVBoxLayout(this); +CSwordSettingsPage::CSwordSettingsPage(QWidget *parent) + : BtConfigPage(parent) +{ + Q_ASSERT(qobject_cast(layout()) != 0); + QVBoxLayout *vbox = static_cast(layout()); + QTabWidget* tabWidget = new QTabWidget(); vbox->addWidget(tabWidget); - setLayout(vbox); m_worksTab = new StandardWorksTab(); m_filtersTab = new TextFiltersTab(); @@ -50,10 +52,9 @@ StandardWorksTab::StandardWorksTab() gridLayout->addWidget( util::tool::explanationLabel( - this, - tr(""), - tr("Standard works are used when no particular work is specified, \ - for example when a hyperlink into a Bible or lexicon was clicked .")), + this, "", + tr("Standard works are used when no particular work is specified, for example " + "when a hyperlink into a Bible or lexicon was clicked.")), 0, 0, 1, 2 /*fill the horizontal space*/ ); @@ -143,7 +144,7 @@ StandardWorksTab::StandardWorksTab() //fill the comboboxes with the right modules - const QList &modules(backend()->moduleList()); + const QList &modules(CSwordBackend::instance()->moduleList()); QString modDescript; for (MLCI it(modules.begin()); it != modules.end(); it++) { modDescript = (*it)->config(CSwordModuleInfo::Description); @@ -178,7 +179,7 @@ StandardWorksTab::StandardWorksTab() inserted = true; } - if (!inserted) { //daily dvotionals, striong lexicons etc. are not very useful for word lookups + if (!inserted) { //daily dvotionals, striong lexicons etc. are not very useful for word lookups m_standardLexiconCombo->addItem(modDescript); } break; @@ -258,11 +259,10 @@ TextFiltersTab::TextFiltersTab() { QVBoxLayout* layout = new QVBoxLayout(this); layout->setMargin(5); QWidget* eLabel = util::tool::explanationLabel( - this, - tr(""), - tr("Filters control the appearance of text. \ -Here you can specify default settings for all filters. \ -You can override these settings in each display window.") + this, "", + tr("Filters control the appearance of text. Here you can specify " + "default settings for all filters. You can override these " + "settings in each display window.") ); eLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); eLabel->setMaximumHeight(50); @@ -324,14 +324,11 @@ void CSwordSettingsPage::save() { m_filtersTab->save(); } -QString CSwordSettingsPage::iconName() { - return CResMgr::settings::sword::icon; -} -QString CSwordSettingsPage::label() { - //: Empty string, don't translate - return tr(""); +const QIcon &CSwordSettingsPage::icon() const { + return util::directory::getIcon(CResMgr::settings::sword::icon); } -QString CSwordSettingsPage::header() { + +QString CSwordSettingsPage::header() const { return tr("Desk"); } @@ -369,9 +366,8 @@ void StandardWorksTab::save() { qWarning("Unhandled module type."); }; - CSwordModuleInfo* const module = backend()->findModuleByDescription(moduleDescription); - CBTConfig::set - (moduleType, module); + CSwordModuleInfo * const module = CSwordBackend::instance()->findModuleByDescription(moduleDescription); + CBTConfig::set(moduleType, module); } } diff --git a/src/frontend/settingsdialogs/cswordsettings.h b/src/frontend/settingsdialogs/cswordsettings.h index 9af4c70..b4684db 100644 --- a/src/frontend/settingsdialogs/cswordsettings.h +++ b/src/frontend/settingsdialogs/cswordsettings.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -11,7 +11,6 @@ #define CSWORDSETTINGS_H #include "frontend/bookshelfmanager/btconfigdialog.h" -#include "util/cpointers.h" #include @@ -23,11 +22,15 @@ class TextFiltersTab; class CSwordSettingsPage : public BtConfigPage { Q_OBJECT public: - CSwordSettingsPage(QWidget* parent); + CSwordSettingsPage(QWidget *parent = 0); + void save(); - QString iconName(); - QString label(); - QString header(); + + /** Reimplemented from BtConfigPage. */ + virtual const QIcon &icon() const; + + /** Reimplemented from BtConfigPage. */ + virtual QString header() const; private: StandardWorksTab* m_worksTab; @@ -36,7 +39,7 @@ class CSwordSettingsPage : public BtConfigPage { //Tab pages. To be used only in Sword settings page. -class StandardWorksTab : public QWidget, CPointers { +class StandardWorksTab: public QWidget { Q_OBJECT public: StandardWorksTab(); diff --git a/src/frontend/tips/bttipdialog.cpp b/src/frontend/tips/bttipdialog.cpp new file mode 100644 index 0000000..ed0a409 --- /dev/null +++ b/src/frontend/tips/bttipdialog.cpp @@ -0,0 +1,193 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#include "bttipdialog.h" + +#include "backend/config/cbtconfig.h" +#include "util/cresmgr.h" +#include "util/directory.h" + +#include +#include +#include +#include +#include +#include +#include + + +namespace { + +inline QString vertical_align(const QString &text) { + return "
    " + text + "
    "; +} + +inline QString make_style(QWidget *widget) { + const QPalette &p = widget->palette(); + return ""; +} + +inline QString make_html(QWidget *widget, const QString &text) { + return "" + make_style(widget) + "" + + vertical_align(text) + ""; +} + +inline QString make_icon(const QString &icon) { + namespace DU = util::directory; + QString fileName = DU::getIconDir().filePath(icon); + QString iconUrl = QUrl::fromLocalFile(fileName).toString(); + return ""; +} + +} // anonymous namespace + + +BtTipDialog::BtTipDialog(QWidget *parent, Qt::WindowFlags wflags) + : QDialog(parent, wflags) +{ + namespace DU = util::directory; + + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowTitle(tr("Tip Of The Day")); + setWindowIcon(DU::getIcon(CResMgr::mainMenu::help::tipOfTheDay::icon)); + resize(450, 240); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + m_tipView = new QWebView; + m_tipView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_tipView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); + mainLayout->addWidget(m_tipView); + + QHBoxLayout* hLayout = new QHBoxLayout; + + m_showTipsCheckBox = new QCheckBox; + m_showTipsCheckBox->setText(tr("Show tips at startup")); + bool showTips = CBTConfig::get(CBTConfig::showTipAtStartup); + m_showTipsCheckBox->setChecked(showTips); + hLayout->addWidget(m_showTipsCheckBox); + + m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, + Qt::Horizontal, + this); + QPushButton *nextButton; + nextButton = m_buttonBox->addButton(tr("Next Tip"), + QDialogButtonBox::ActionRole); + hLayout->addWidget(m_buttonBox); + + mainLayout->addLayout(hLayout); + setLayout(mainLayout); + + bool ok; + ok = connect(m_showTipsCheckBox, SIGNAL(toggled(bool)), + this, SLOT(startupBoxChanged(bool))); + Q_ASSERT(ok); + + ok = connect(m_buttonBox, SIGNAL(rejected()), + this, SLOT(reject())); + Q_ASSERT(ok); + + ok = connect(nextButton, SIGNAL(clicked()), + this, SLOT(nextTip())); + Q_ASSERT(ok); + + ok = connect(m_tipView->page(), SIGNAL(linkClicked(const QUrl&)), + this, SLOT(linkClicked(const QUrl&))); + Q_ASSERT(ok); + + m_tipNumber = CBTConfig::get(CBTConfig::tipNumber); + initTips(); + displayTip(); +} + +void BtTipDialog::initTips() { + m_tips.clear(); + + m_tips << tr("To add multiple Bible works in parallel in your active Bible window" + " select this icon and choose another Bible work.") + + "
    " + make_icon(CResMgr::modules::bible::icon_add) + "
    "; + + m_tips << tr("To add multiple commentary works in parallel in your active commentary window" + " select this icon and choose another commentary work.") + + "
    " + make_icon(CResMgr::modules::commentary::icon_add) + "
    "; + + m_tips << tr("To learn more about the BibleTime project please go to our web site.") + + "
    www.bibletime.info
    "; + + m_tips << tr("To synchronize a commentary window with the active Bible window, activate the" + " commentary window and select this icon.") + "
    " + + make_icon(CResMgr::displaywindows::commentaryWindow::syncWindow::icon) + + "

    " + tr("Select the icon again to stop the synchronization."); + + m_tips << tr("To create a bookmark drag any verse reference from a Bible or commentary work" + " into the Bookmarks window. An arrow will indicate the position that the bookmark will" + " go when you release the cursor. Other works will have a reference in the upper left" + " corner that can be used to create a bookmark."); + + m_tips << tr("To change a bookmark title or description, right click on the bookmark" + " and select the Edit Bookmark menu. After finishing the edit the description can be" + " seen by hovering over the bookmark."); + + m_tips << tr("To load multiple installation sources for works, go to the Bookshelf Manager" + ", select the Add button, and then the Get List button."); + + m_tips << tr("To find more information about a work, go the the Bookshelf window, right" + " click on the work, and select the About menu."); + + m_tips << tr("The Bookshelf, Bookmark, and Mag windows can be moved to new locations by" + " dragging them from the title at the top of each window. They can be placed to the left," + " right, above, or below the works windows. They can be placed on top of each other and" + " tabs will appear so each window can be selected. They can be resized by dragging the" + " border between the window and another window."); + + m_tips << tr("You can search for Strong's numbers in a work. Start with a work that has Strong's" + " numbers and hover over a word. Right click the word and use the Strong's Search" + " menu. A search dialog will appear that allows you to see the use of the same" + " Strong's number in other locations of the work."); + + m_tips << tr("You can save personal notes for specific verses references. You must install" + " the Personal commentary. Open the Bookshelf Manager, choose Crosswire as the" + " source and look under Commentary and English. Once installed, use the" + " Bookshelf window and right click the Personal commentary. Use either the" + " Edit Plain Text menu or the Edit HTML menu to open the work in write mode."); + + m_tips << tr("You can view Strong's number information in the MAG window by hovering over" + " a word in a Bible work that has Strong's numbers. You should have the StrongsGreek" + " and StrongsHebrew lexicons from Crosswire installed."); +} + +void BtTipDialog::displayTip() { + m_tipView->setHtml(make_html(this, m_tips[m_tipNumber])); +} + +void BtTipDialog::startupBoxChanged(bool checked) { + CBTConfig::set(CBTConfig::showTipAtStartup, checked); +} + +void BtTipDialog::nextTip() { + m_tipNumber++; + if (m_tipNumber >= m_tips.count()) { + m_tipNumber = 0; + } + CBTConfig::set(CBTConfig::tipNumber, m_tipNumber); + displayTip(); +} + +void BtTipDialog::linkClicked(const QUrl& url) { + QDesktopServices::openUrl(url); +} diff --git a/src/frontend/tips/bttipdialog.h b/src/frontend/tips/bttipdialog.h new file mode 100644 index 0000000..cd00394 --- /dev/null +++ b/src/frontend/tips/bttipdialog.h @@ -0,0 +1,62 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTTIPDIALOG_H +#define BTTIPDIALOG_H + +#include +#include + + +class QAbstractButton; +class QCheckBox; +class QDialogButtonBox; +class QPushButton; +class QUrl; +class QWebView; + +/** + The Tip Of The Day dialog. +*/ +class BtTipDialog: public QDialog { + Q_OBJECT + + public: /* Methods: */ + + BtTipDialog(QWidget *parent = 0, Qt::WindowFlags wflags = Qt::Dialog); + + private: /* Methods: */ + + /** Enter tips in this function */ + void initTips(); + + /** Sends the current tip to the web view */ + void displayTip(); + + private slots: + + /** Called when the show tips at startup checkbox changes. */ + void startupBoxChanged(bool checked); + + /** Called when the next tip button is pressed. */ + void nextTip(); + + /** Called when any link in a tip is clicked. */ + void linkClicked(const QUrl& url); + + private: /* Fields: */ + + QDialogButtonBox* m_buttonBox; + QWebView* m_tipView; + QCheckBox* m_showTipsCheckBox; + int m_tipNumber; + QStringList m_tips; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp index 3064522..6f2c9b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,41 +2,122 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ -#include -#include -#include +#include #ifndef NO_DBUS #include #endif -#include #include #include #include -#include #include "backend/bookshelfmodel/btbookshelftreemodel.h" #include "backend/config/cbtconfig.h" -#include "backend/managers/cswordbackend.h" #include "bibletime.h" #include "bibletime_dbus_adaptor.h" #include "bibletimeapp.h" -#include "util/cresmgr.h" #include "util/directory.h" -#include "util/migrationutil.h" -#ifdef BT_ENABLE_TESTING -#include -#include "tests/bibletime_test.h" -#endif +/// \todo Reimplement signal handler which handles consecutive crashes. namespace { -bool showDebugMessages; +/******************************************************************************* + Printing command-line help. +*******************************************************************************/ + +/** + Prints command-line help text for BibleTime when --help is used. + \param[in] executable The executed file name (argv[0]). +*/ +void printHelp(const QString &executable) { + std::cout << qPrintable(executable) << std::endl << std::endl + << " --help, -h" << std::endl << " " + << qPrintable(QObject::tr("Show this help message and exit")) + << std::endl << std::endl + << " --version, -V" << std::endl << " " + << qPrintable(QObject::tr("Output BibleTime version and exit")) + << std::endl << std::endl + << " --ignore-session" << std::endl << " " + << qPrintable(QObject::tr("Open a clean session")) + << std::endl << std::endl + << " --open-default-bible " << std::endl << " " + << qPrintable(QObject::tr("Open the default Bible with the " + "reference ")) + << std::endl << std::endl + << qPrintable(QObject::tr("For command-line arguments parsed by the" + " Qt toolkit, see %1.") + .arg("http://doc.qt.nokia.com/latest/qapplication.html")) + << std::endl; +} + +/******************************************************************************* + Parsing command-line arguments +*******************************************************************************/ + +/** + Parses all command-line arguments. + \param[out] showDebugMessages Whether --debug was specified. + \param[out] ignoreSession Whether --ignore-session was specified. + \param[out] openBibleKey Will be set to --open-default-bible if specified. + \retval -1 Parsing was successful, the application should exit with + EXIT_SUCCESS. + \retval 0 Parsing was successful. + \retval 1 Parsing failed, the application should exit with EXIT_FAILURE. +*/ +int parseCommandLine(bool &showDebugMessages, bool &ignoreSession, + QString &openBibleKey) +{ + QStringList args = BibleTimeApp::arguments(); + for (int i = 1; i < args.size(); i++) { + const QString &arg = args.at(i); + if (arg == "--help" + || arg == "-h" + || arg == "/?" + || arg == "/h") + { + printHelp(args.at(0)); + return -1; + } else if (arg == "--version" + || arg == "-V") + { + std::cout << "BibleTime " BT_VERSION << std::endl; + return -1; + } else if (arg == "--debug") { + showDebugMessages = true; + } else if (arg == "--ignore-session") { + ignoreSession = true; + } else if (arg == "--open-default-bible") { + i++; + if (i < args.size()) { + openBibleKey = args.at(i); + } else { + std::cerr << qPrintable(QObject::tr( + "Error: %1 expects an argument.") + .arg("--open-default-bible")) << ' ' + << qPrintable(QObject::tr("See --help for details.")) + << std::endl; + return 1; + } + } else { + std::cerr << qPrintable(QObject::tr( + "Error: Invalid command-line argument: %1") + .arg(arg)) << std::endl; + return 1; + } + } + return 0; +} + +/******************************************************************************* + Console messaging. +*******************************************************************************/ + +bool showDebugMessages = false; #ifdef Q_WS_WIN @@ -52,9 +133,6 @@ FILE *out_fd = 0; #endif -} // anonymous namespace - - void myMessageOutput( QtMsgType type, const char *msg ) { //we use this messagehandler to switch debugging off in final releases FILE* outFd = 0; @@ -85,13 +163,22 @@ void myMessageOutput( QtMsgType type, const char *msg ) { } } +/******************************************************************************* + Handle Qt's meta type system. +*******************************************************************************/ + void registerMetaTypes() { - qRegisterMetaType(); - qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaTypeStreamOperators("BtBookshelfTreeModel::Grouping"); } -/// \todo Reimplement signal handler which handles consecutive crashes. +} // anonymous namespace + + +/******************************************************************************* + Program main entry point. +*******************************************************************************/ int main(int argc, char* argv[]) { namespace DU = util::directory; @@ -100,28 +187,21 @@ int main(int argc, char* argv[]) { app.setApplicationName("bibletime"); app.setApplicationVersion(BT_VERSION); - showDebugMessages = QCoreApplication::arguments().contains("--debug"); + // Parse command line arguments: + bool ignoreSession = false; + QString openBibleKey; + int r = parseCommandLine(showDebugMessages, ignoreSession, openBibleKey); + if (r != 0) { + if (r < 0) return EXIT_SUCCESS; + return EXIT_FAILURE; + } #ifdef Q_WS_WIN // Use the default Qt message handler if --debug is not specified // This works with Visual Studio debugger Output Window if (showDebugMessages) - qInstallMsgHandler( myMessageOutput ); -#else - qInstallMsgHandler( myMessageOutput ); #endif - -#ifdef BT_ENABLE_TESTING - if (QString(argv[1]) == QString("--run-tests")) { - BibleTimeTest testClass; - return QTest::qExec(&testClass); - } -#endif - - /** - \todo Reimplement "--ignore-session" and "--open-default-bible " - command line argument handling. - */ + qInstallMsgHandler(myMessageOutput); #ifdef Q_WS_WIN @@ -141,6 +221,8 @@ int main(int argc, char* argv[]) { return EXIT_FAILURE; } + app.startInit(); + #ifdef Q_WS_WIN // change directory to the Sword or .sword directory in the $HOME dir so that // the sword.conf is found. It points to the sword/locales.d directory @@ -149,6 +231,14 @@ int main(int argc, char* argv[]) { dir.setCurrent(homeSwordDir); #endif +#ifdef Q_WS_MAC + // change to the user's sword dir containing the sword.conf config file, so that + // Sword will correctly find it. + QString homeSwordDir = util::directory::getUserHomeSwordDir().absolutePath(); + QDir dir; + dir.setCurrent(homeSwordDir); +#endif + // This is needed for languagemgr language names to work, they use \uxxxx escape sequences in string literals QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); //first install QT's own translations @@ -162,32 +252,37 @@ int main(int argc, char* argv[]) { app.setProperty("--debug", QVariant(showDebugMessages)); - //Migrate configuration data, if neccessary - util::migration::checkMigration(); +// setSignalHandler(signalHandler); -// setSignalHandler(signalHandler); + if (!app.initDisplayTemplateManager()) return EXIT_FAILURE; - BibleTime bibleTime; + BibleTime *mainWindow = new BibleTime(); + mainWindow->setAttribute(Qt::WA_DeleteOnClose); // a new BibleTime version was installed (maybe a completely new installation) if (CBTConfig::get(CBTConfig::bibletimeVersion) != BT_VERSION) { CBTConfig::set(CBTConfig::bibletimeVersion, BT_VERSION); - bibleTime.saveConfigSettings(); + mainWindow->saveConfigSettings(); } // restore the workspace and process command line options //app.setMainWidget(bibletime_ptr); //no longer used in qt4 (QApplication) - bibleTime.show(); - bibleTime.processCommandline(); //must be done after the bibletime window is visible + mainWindow->show(); + + // The following must be done after the bibletime window is visible: + mainWindow->processCommandline(ignoreSession, openBibleKey); #ifndef NO_DBUS - new BibleTimeDBusAdaptor(&bibleTime); + new BibleTimeDBusAdaptor(mainWindow); // connect to D-Bus and register as an object: QDBusConnection::sessionBus().registerService("info.bibletime.BibleTime"); - QDBusConnection::sessionBus().registerObject("/BibleTime", &bibleTime); + QDBusConnection::sessionBus().registerObject("/BibleTime", mainWindow); #endif - int r = app.exec(); + if (CBTConfig::get(CBTConfig::showTipAtStartup)) + mainWindow->slotOpenTipDialog(); + + r = app.exec(); CLOSE_DEBUG_STREAM; return r; } diff --git a/src/tests/backend/config/cbtconfig_test.cpp b/src/tests/backend/config/cbtconfig_test.cpp deleted file mode 100644 index 7e75ce4..0000000 --- a/src/tests/backend/config/cbtconfig_test.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "tests/bibletime_test.h" - -#include -#include "backend/config/cbtconfig.h" - - -void BibleTimeTest::frontend_cbtconfig_test() { - QList value1; - value1 << -1 << 0 << 1 << 993738; - QString value1String("-1,0,1,993738"); - QList emptyValue; - QString emptyValueString(""); - - //conversion checks int-string - QCOMPARE(CBTConfig::IntListToString(value1), value1String); - QCOMPARE(CBTConfig::IntListToString(emptyValue), emptyValueString); - - //conversion checks string-int - QCOMPARE(CBTConfig::StringToIntList(value1String), value1); - QCOMPARE(CBTConfig::StringToIntList(emptyValueString), emptyValue); - - //roundtrip checks - QCOMPARE(CBTConfig::StringToIntList(CBTConfig::IntListToString(value1)), value1); - QCOMPARE(CBTConfig::StringToIntList(CBTConfig::IntListToString(emptyValue)), emptyValue); -} diff --git a/src/tests/bibletime_test.cpp b/src/tests/bibletime_test.cpp deleted file mode 100644 index d26ca67..0000000 --- a/src/tests/bibletime_test.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "bibletime_test.h" - -#include - - -void BibleTimeTest::dummyTest() { - QCOMPARE(QString("Hello").toUpper(), QString("HELLO")); -} - - - diff --git a/src/tests/bibletime_test.h b/src/tests/bibletime_test.h deleted file mode 100644 index 3847f1a..0000000 --- a/src/tests/bibletime_test.h +++ /dev/null @@ -1,28 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef BIBLETIME_TEST_H -#define BIBLETIME_TEST_H - -#include - - -class BibleTimeTest: public QObject { - Q_OBJECT - - private slots: - //frontend - void frontend_cbtconfig_test(); - - //dummy test - void dummyTest(); -}; - - -#endif diff --git a/src/util/btsignal.h b/src/util/btsignal.h new file mode 100644 index 0000000..ff4afa1 --- /dev/null +++ b/src/util/btsignal.h @@ -0,0 +1,40 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef BTSIGNAL_H +#define BTSIGNAL_H + +#include + + +/** +* BtSignal +* The purpose of this class is to emit Qt signals for other classes +* that are not derived from QObject. It can be used as a member +* variable of those classes. +* +* There are some classes it is not possible to derive from QObject and +* have the signals work. Certain multiple inheritance classes which cannot +* have QObject as the first derived class, cannot use Qt signals. +*/ +class BtSignal : public QObject { + Q_OBJECT + + public: + inline BtSignal(QObject *parent = 0) : QObject(parent) {}; + + /** + Immediately emits the changed() signal. + */ + inline void emitChanged() { emit changed(); } + + signals: + void changed(); +}; +#endif diff --git a/src/util/cpointers.cpp b/src/util/cpointers.cpp deleted file mode 100644 index a0d715a..0000000 --- a/src/util/cpointers.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "util/cpointers.h" - -#include "frontend/cprinter.h" -#include "backend/managers/cdisplaytemplatemgr.h" -#include "backend/managers/cswordbackend.h" - - -CPointers::PointerCache m_pointerCache; - -void CPointers::setBackend(CSwordBackend* const backend) { - Q_ASSERT( m_pointerCache.backend == 0); - CPointers::deleteBackend(); - m_pointerCache.backend = backend; -} - -void CPointers::setInfoDisplay(InfoDisplay::CInfoDisplay* const infoDisplay) { - Q_ASSERT( m_pointerCache.infoDisplay == 0); - m_pointerCache.infoDisplay = infoDisplay; -} - -void CPointers::deleteBackend() { - delete m_pointerCache.backend; - m_pointerCache.backend = 0; -} - -void CPointers::deleteLanguageMgr() { - delete m_pointerCache.langMgr; - m_pointerCache.langMgr = 0; -} - -void CPointers::deleteDisplayTemplateMgr() { - delete m_pointerCache.displayTemplateMgr; - m_pointerCache.displayTemplateMgr = 0; -} - -/** Returns a pointer to the printer object. */ -CDisplayTemplateMgr* CPointers::displayTemplateManager() { - if (!m_pointerCache.displayTemplateMgr) { - m_pointerCache.displayTemplateMgr = new CDisplayTemplateMgr(); - } - - return m_pointerCache.displayTemplateMgr; -} - diff --git a/src/util/cpointers.h b/src/util/cpointers.h deleted file mode 100644 index 5005672..0000000 --- a/src/util/cpointers.h +++ /dev/null @@ -1,115 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef CPOINTERS_H -#define CPOINTERS_H - -#include "backend/managers/clanguagemgr.h" - - -class CSwordBackend; -class CLanguageMgr; -class CDisplayTemplateMgr; - -namespace InfoDisplay { -class CInfoDisplay; -} - -/** Holds the pointers to important classes like modules, backend etc. -*/ -class CPointers { - protected: - friend class BibleTime; //BibleTime may initialize this object - friend class BibleTimeApp; //BibleTimeApp may initialize this object - friend int main(int argc, char* argv[]); //main may set the printer - - //Empty virtuaual destructor - virtual ~CPointers() {} - - /** Set the backend. - * @param backend Pointer to the new application-wide Sword backend - */ - static void setBackend(CSwordBackend* const backend); - /** Set the info display. - * @param iDisplay The pointer to the new info display. - */ - static void setInfoDisplay(InfoDisplay::CInfoDisplay* const iDisplay); - - /** Delete the backend. Should be called by BibleTimeApp, - * because the backend should be deleted as late as possible. - */ - static void deleteBackend(); - /** Delete the printer. Should be called by BibleTimeApp, - * because the printer should be deleted as late as possible. - */ - static void deletePrinter(); - /** Delete the language manager. Should be called by BibleTimeApp, - * because the language manager should be deleted as late as possible. - */ - static void deleteLanguageMgr(); - /** Delete the display template manager. Should be called by BibleTimeApp, - * because the template manager should be deleted as late as possible. - */ - static void deleteDisplayTemplateMgr(); - - public: // Public methods - /** Returns a pointer to the backend - * @return The backend pointer. - */ - inline static CSwordBackend* backend(); - /** Returns a pointer to the language manager - * @return The language manager - */ - inline static CLanguageMgr* languageMgr(); - /** Returns a pointer to the info display. - * @return The backend pointer. - */ - inline static InfoDisplay::CInfoDisplay* infoDisplay(); - /** Returns a pointer to the application's display template manager - * @return The backend pointer. - */ - static CDisplayTemplateMgr* displayTemplateManager(); - - struct PointerCache { - PointerCache() { - backend = 0; - langMgr = 0; - infoDisplay = 0; - displayTemplateMgr = 0; - }; - - CSwordBackend* backend; - CLanguageMgr* langMgr; - InfoDisplay::CInfoDisplay* infoDisplay; - CDisplayTemplateMgr* displayTemplateMgr; - }; -}; - -extern CPointers::PointerCache m_pointerCache; - -/** Returns a pointer to the backend ... */ -inline CSwordBackend* CPointers::backend() { - return m_pointerCache.backend; -} - -/** Returns a pointer to the backend ... */ -inline CLanguageMgr* CPointers::languageMgr() { - if (!m_pointerCache.langMgr) { - m_pointerCache.langMgr = new CLanguageMgr(); - } - return m_pointerCache.langMgr; -} - -/** Returns a pointer to the printer object. */ -inline InfoDisplay::CInfoDisplay* CPointers::infoDisplay() { - return m_pointerCache.infoDisplay; -} - - -#endif diff --git a/src/util/cresmgr.cpp b/src/util/cresmgr.cpp index 56fe5b1..2fc26d4 100644 --- a/src/util/cresmgr.cpp +++ b/src/util/cresmgr.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -41,28 +41,28 @@ const QString icon_add = "book_add.svg"; namespace categories { namespace bibles { -const QString icon = "bible.svg"; +const QString icon = "bible.svg"; } namespace commentaries { -const QString icon = "commentary.svg"; +const QString icon = "commentary.svg"; } namespace lexicons { -const QString icon = "lexicon.svg"; +const QString icon = "lexicon.svg"; } namespace dailydevotional { -const QString icon = "calendar.svg"; +const QString icon = "calendar.svg"; } namespace books { -const QString icon = "books.svg"; +const QString icon = "books.svg"; } namespace glossary { -const QString icon = "dictionary.svg"; +const QString icon = "dictionary.svg"; } namespace images { -const QString icon = "map.svg"; +const QString icon = "map.svg"; } namespace cults { -const QString icon = "questionable.svg"; +const QString icon = "questionable.svg"; } }//categories namespace mainMenu { //Main menu @@ -141,6 +141,11 @@ const QString icon = "tile_auto.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_I); const char* actionName = "windowAutoTile_action"; } +namespace autoTabbed { +const QString icon = "tabbed.svg"; +const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_T); +const char* actionName = "windowAutoTabbed_action"; +} namespace autoCascade { const QString icon = "cascade_auto.svg"; const QKeySequence accel(Qt::CTRL + Qt::ALT + Qt::Key_J); @@ -199,6 +204,11 @@ const QString icon = "contents2.svg"; const QKeySequence accel(Qt::Key_F2); const char* actionName = "helpHowTo_action"; } +namespace tipOfTheDay { +const QString icon = "light_bulb.svg"; +const QKeySequence accel(Qt::Key_F3); +const char* actionName = "tipOfTheDay_action"; +} }//mainMenu::help } //end of mainMenu @@ -238,9 +248,9 @@ const QString icon = "print.svg"; } //searchDialog namespace displaywindows { -/* namespace transliteration { - const QString icon = "bt_displaytranslit"; - }*/ +/* namespace transliteration { + const QString icon = "bt_displaytranslit"; + }*/ namespace displaySettings { const QString icon = "displayconfig.svg"; } @@ -306,7 +316,7 @@ const QString icon = "print.svg"; namespace commentaryWindow { namespace syncWindow { const QString icon = "sync.svg"; -const QKeySequence accel; +const QKeySequence accel(Qt::SHIFT + Qt::Key_S); const char* actionName = "commentary_syncWindow"; } } @@ -411,6 +421,9 @@ const QString icon = "startconfig.svg"; namespace fonts { const QString icon = "fonts.svg"; } +namespace languages { +const QString icon = "flag.svg"; +} namespace profiles { const QString icon = "view_profile.svg"; } @@ -445,7 +458,13 @@ const QString icon = "folder.svg"; namespace bookmark { const QString icon = "bookmark.svg"; } -namespace changeBookmark { +namespace editBookmark { +const QString icon = "bookmark.svg"; +} +namespace sortFolderBookmarks { +const QString icon = "bookmark.svg"; +} +namespace sortAllBookmarks { const QString icon = "bookmark.svg"; } namespace importBookmarks { @@ -505,13 +524,5 @@ const QString add_icon = "plus"; const QString edit_icon = "pencil"; const QString remove_icon = "trash"; } -} - -} - - - -namespace CResMgr { -void init_tr() { -} //init_tr() -} //CResMgr +} // namespace bookshelfmgr +} // namespace CResMgr diff --git a/src/util/cresmgr.h b/src/util/cresmgr.h index 0d239f0..7ba8760 100644 --- a/src/util/cresmgr.h +++ b/src/util/cresmgr.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -14,7 +14,6 @@ #include namespace CResMgr { -void init_tr(); namespace mainWindow { extern const QString icon; @@ -145,6 +144,11 @@ extern const QString icon; extern const QKeySequence accel; extern const char* actionName; } +namespace autoTabbed { +extern const QString icon; +extern const QKeySequence accel; +extern const char* actionName; +} namespace autoCascade { extern const QString icon; extern const QKeySequence accel; @@ -206,6 +210,11 @@ extern const QString icon; extern const QKeySequence accel; extern const char* actionName; } +namespace tipOfTheDay { +extern const QString icon; +extern const QKeySequence accel; +extern const char* actionName; +} } } //end of main menu @@ -426,6 +435,9 @@ extern const QString icon; namespace fonts { extern const QString icon; } +namespace languages { +extern const QString icon; +} namespace profiles { extern const QString icon; } @@ -460,7 +472,13 @@ extern const QString icon; namespace bookmark { extern const QString icon; } -namespace changeBookmark { +namespace editBookmark { +extern const QString icon; +} +namespace sortFolderBookmarks { +extern const QString icon; +} +namespace sortAllBookmarks { extern const QString icon; } namespace importBookmarks { diff --git a/src/util/dialogutil.cpp b/src/util/dialogutil.cpp index 2d84a8b..39672d3 100644 --- a/src/util/dialogutil.cpp +++ b/src/util/dialogutil.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -29,6 +29,7 @@ void replaceText(QDialogButtonBox *box, QDialogButtonBox::StandardButton flag, QMessageBox::StandardButton bt_messageBox(QMessageBox::Icon icon, QWidget * parent, const QString & title, const QString & text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) { qDebug() << "BT message box warning/information/critical"; QMessageBox messageBox(icon, title, text, QMessageBox::Ok, parent); + messageBox.setTextFormat(Qt::RichText); //We need the button box to translate the strings (the idea of this whole function) QDialogButtonBox* box = dynamic_cast(messageBox.button(QMessageBox::Ok)->parent()); Q_ASSERT(box); diff --git a/src/util/dialogutil.h b/src/util/dialogutil.h index 62b3bbd..ea597cb 100644 --- a/src/util/dialogutil.h +++ b/src/util/dialogutil.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2009 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/util/directory.cpp b/src/util/directory.cpp index 809b435..ddbbaaf 100644 --- a/src/util/directory.cpp +++ b/src/util/directory.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -39,18 +39,30 @@ QDir cachedUserHomeSwordModsDir; QDir cachedUserSessionsDir; QDir cachedUserCacheDir; QDir cachedUserIndexDir; +QDir cachedSwordPathDir; #ifdef Q_WS_WIN QDir cachedApplicationSwordDir; // Only Windows installs the sword directory which contains locales.d QDir cachedSharedSwordDir; #endif +#ifdef Q_WS_MAC +QDir cachedSwordLocalesDir; +#endif + #ifdef Q_WS_WIN static const char* BIBLETIME = "Bibletime"; static const char* SWORD_DIR = "Sword"; #else +#ifdef Q_WS_MAC +static const char* BIBLETIME = "Library/Application Support/BibleTime"; +static const char* SWORD_DIR = "Library/Application Support/Sword"; +#else static const char* BIBLETIME = ".bibletime"; static const char* SWORD_DIR = ".sword"; #endif +#endif +static const char* SWORD_PATH = "SWORD_PATH"; +static const char* UNSET_SWORD_PATH = "SWORD_PATH="; } // anonymous namespace bool initDirectoryCache() { @@ -83,6 +95,22 @@ bool initDirectoryCache() { } #endif +#ifdef Q_WS_MAC + cachedSwordLocalesDir = wDir; // application sword dir for Windows only + if (!cachedSwordLocalesDir.cd("share/sword/locales.d") || !cachedSwordLocalesDir.isReadable()) { + qWarning() << "Cannot find sword locales directory relative to" << QCoreApplication::applicationDirPath(); + return false; + } +#endif + + cachedSwordPathDir = QDir(); + char* swordPath = getenv(SWORD_PATH); + if (swordPath != 0) { + cachedSwordPathDir = QDir(swordPath); + // We unset the SWORD_PATH so libsword finds paths correctly + putenv((char*)UNSET_SWORD_PATH); + } + cachedIconDir = wDir; // Icon dir if (!cachedIconDir.cd("share/bibletime/icons") || !cachedIconDir.isReadable()) { qWarning() << "Cannot find icon directory relative to" << QCoreApplication::applicationDirPath(); @@ -146,7 +174,7 @@ bool initDirectoryCache() { cachedUserBaseDir = cachedUserHomeDir; if (!cachedUserBaseDir.cd(BIBLETIME)) { - if (!cachedUserBaseDir.mkdir(BIBLETIME) || !cachedUserBaseDir.cd(BIBLETIME)) { + if (!cachedUserBaseDir.mkpath(BIBLETIME) || !cachedUserBaseDir.cd(BIBLETIME)) { qWarning() << "Could not create user setting directory."; return false; } @@ -154,7 +182,7 @@ bool initDirectoryCache() { cachedUserHomeSwordDir = cachedUserHomeDir; if (!cachedUserHomeSwordDir.cd(SWORD_DIR)) { - if (!cachedUserHomeSwordDir.mkdir(SWORD_DIR) || !cachedUserHomeSwordDir.cd(SWORD_DIR)) { + if (!cachedUserHomeSwordDir.mkpath(SWORD_DIR) || !cachedUserHomeSwordDir.cd(SWORD_DIR)) { qWarning() << "Could not create user home " << SWORD_DIR << " directory."; return false; } @@ -188,6 +216,7 @@ bool initDirectoryCache() { if (!cachedUserIndexDir.cd("indices")) { if (!cachedUserIndexDir.mkdir("indices") || !cachedUserIndexDir.cd("indices")) { qWarning() << "Could not create user indices directory."; + return false; } } @@ -195,6 +224,7 @@ bool initDirectoryCache() { if (!cachedUserDisplayTemplatesDir.cd("display-templates")) { if (!cachedUserDisplayTemplatesDir.mkdir("display-templates") || !cachedUserDisplayTemplatesDir.cd("display-templates")) { qWarning() << "Could not create user display templates directory."; + return false; } } @@ -288,113 +318,125 @@ QString convertDirSeparators(const QString& path) { } #ifdef Q_WS_WIN -QDir getApplicationSwordDir() { +const QDir &getApplicationSwordDir() { return cachedApplicationSwordDir; } -QDir getSharedSwordDir() { +const QDir &getSharedSwordDir() { return cachedSharedSwordDir; } #endif -QDir getIconDir() { +#ifdef Q_WS_MAC +const QDir &getSwordLocalesDir() { + return cachedSwordLocalesDir; +} +#endif + +const QDir &getSwordPathDir() { + return cachedSwordPathDir; +} + +const QDir &getIconDir() { return cachedIconDir; } -QDir getJavascriptDir() { +const QDir &getJavascriptDir() { return cachedJavascriptDir; } -QDir getLicenseDir() { +const QDir &getLicenseDir() { return cachedLicenseDir; } -QIcon getIcon(const QString &name) { +const QIcon &getIcon(const QString &name) { static QMap iconCache; - //error if trying to use name directly... - QString name2(name); - QString plainName = name2.remove(".svg", Qt::CaseInsensitive); - if (iconCache.contains(plainName)) { - return iconCache.value(plainName); + static QIcon nullIcon; + + QString plainName = name; + if (plainName.endsWith(".svg", Qt::CaseInsensitive)) { + plainName.chop(4); + } + + QMap::const_iterator i = iconCache.find(plainName); + if (i != iconCache.end()) { + return *i; } QString iconDir = getIconDir().canonicalPath(); QString iconFileName = iconDir + "/" + plainName + ".svg"; if (QFile(iconFileName).exists()) { - QIcon ic = QIcon(iconFileName); - iconCache.insert(plainName, ic); - return ic; + return *iconCache.insert(plainName, QIcon(iconFileName)); } else { iconFileName = iconDir + "/" + plainName + ".png"; if (QFile(iconFileName).exists()) { - QIcon ic = QIcon(iconFileName); - iconCache.insert(plainName, ic); - return ic; + return *iconCache.insert(plainName, QIcon(iconFileName)); } else { - qWarning() << "Cannot find icon file" << iconFileName << ", using default icon."; - iconFileName = iconDir + "/" + "/default.svg"; - if (QFile(iconFileName).exists()) { - return QIcon(iconDir + "/default.svg"); - } - else { - return QIcon(iconDir + "default.png"); + if (plainName != "default") { + qWarning() << "Cannot find icon file" << iconFileName + << ", using default icon."; + return getIcon("default"); + } else { + qWarning() << "Cannot find default icon" << iconFileName + << ", using null icon."; + return nullIcon; } } } } -QDir getPicsDir() { +const QDir &getPicsDir() { return cachedPicsDir; } -QDir getLocaleDir() { +const QDir &getLocaleDir() { return cachedLocaleDir; } -QDir getHandbookDir() { +const QDir &getHandbookDir() { return cachedHandbookDir; } -QDir getHowtoDir() { +const QDir &getHowtoDir() { return cachedHowtoDir; } -QDir getDisplayTemplatesDir() { +const QDir &getDisplayTemplatesDir() { return cachedDisplayTemplatesDir; } -QDir getUserBaseDir() { +const QDir &getUserBaseDir() { return cachedUserBaseDir; } -QDir getUserHomeDir() { +const QDir &getUserHomeDir() { return cachedUserHomeDir; } -QDir getUserHomeSwordDir() { +const QDir &getUserHomeSwordDir() { return cachedUserHomeSwordDir; } -QDir getUserHomeSwordModsDir() { +const QDir &getUserHomeSwordModsDir() { return cachedUserHomeSwordModsDir; } -QDir getUserSessionsDir() { +const QDir &getUserSessionsDir() { return cachedUserSessionsDir; } -QDir getUserCacheDir() { +const QDir &getUserCacheDir() { return cachedUserCacheDir; } -QDir getUserIndexDir() { +const QDir &getUserIndexDir() { return cachedUserIndexDir; } -QDir getUserDisplayTemplatesDir() { +const QDir &getUserDisplayTemplatesDir() { return cachedUserDisplayTemplatesDir; } diff --git a/src/util/directory.h b/src/util/directory.h index 1b460d0..6b64759 100644 --- a/src/util/directory.h +++ b/src/util/directory.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -65,69 +65,81 @@ QString convertDirSeparators(const QString& path); /** Return the path to the sword dir., Windows only C:\Program Files\BibleTime\share\sword */ -QDir getApplicationSwordDir(); +const QDir &getApplicationSwordDir(); /** Return the path to the %ALLUSERSPROFILE%\Sword directory */ -QDir getSharedSwordDir(); +const QDir &getSharedSwordDir(); #endif +#ifdef Q_WS_MAC // Mac only directories + +/** + * Path to the Sword locales + */ +const QDir &getSwordLocalesDir(); + +#endif + +/** Return the path to the SWORD_PATH env var directory */ +const QDir &getSwordPathDir(); + /** Return the path to the icons. */ -QDir getIconDir(); +const QDir &getIconDir(); /** Return the path to the javascript. */ -QDir getJavascriptDir(); +const QDir &getJavascriptDir(); /** Return the path to the license. */ -QDir getLicenseDir(); +const QDir &getLicenseDir(); /** Returns an icon with the given name */ -QIcon getIcon(const QString &name); +const QIcon &getIcon(const QString &name); /** Return the path to the pictures. */ -QDir getPicsDir(); +const QDir &getPicsDir(); /** Return the path to the translation files. */ -QDir getLocaleDir(); +const QDir &getLocaleDir(); /** Return the path to the handbook files, either of the current locale or en as fallback. */ -QDir getHandbookDir(); +const QDir &getHandbookDir(); /** Return the path to the bible study howto files, either of the current locale or en as fallback. */ -QDir getHowtoDir(); +const QDir &getHowtoDir(); /** Return the path to the default display template files. */ -QDir getDisplayTemplatesDir(); +const QDir &getDisplayTemplatesDir(); /** Return the path to the user's home directory. %APPDATA% on Windows - $HOME on linux */ -QDir getUserHomeDir(); + $HOME on linux */ +const QDir &getUserHomeDir(); /** Return the path to the user's home .sword (or Sword) directory. %APPDATA%\Sword on Windows - $HOME\.sword on linux */ -QDir getUserHomeSwordDir(); + $HOME\.sword on linux */ +const QDir &getUserHomeSwordDir(); /** Return the path to the user's home .sword (or Sword) mods.d directory. %APPDATA%\Sword\mods.d on Windows - $HOME\.sword\mods.d on linux */ -QDir getUserHomeSwordModsDir(); + $HOME\.sword\mods.d on linux */ +const QDir &getUserHomeSwordModsDir(); /** Return the path to the user's settings directory.*/ -QDir getUserBaseDir(); +const QDir &getUserBaseDir(); /** Return the path to the user's sessions directory.*/ -QDir getUserSessionsDir(); +const QDir &getUserSessionsDir(); /** Return the path to the user's cache directory.*/ -QDir getUserCacheDir(); +const QDir &getUserCacheDir(); /** Return the path to the user's indices directory.*/ -QDir getUserIndexDir(); +const QDir &getUserIndexDir(); /** Return the path to the user's custom display templates directory.*/ -QDir getUserDisplayTemplatesDir(); +const QDir &getUserDisplayTemplatesDir(); } // namespace directory } // namespace util diff --git a/src/util/exceptions.h b/src/util/exceptions.h index 2ba8ff3..d89ba06 100644 --- a/src/util/exceptions.h +++ b/src/util/exceptions.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ diff --git a/src/util/macros.h b/src/util/macros.h new file mode 100644 index 0000000..aa451fd --- /dev/null +++ b/src/util/macros.h @@ -0,0 +1,61 @@ +/********* +* +* This file is part of BibleTime's source code, http://www.bibletime.info/. +* +* Copyright 1999-2011 by the BibleTime developers. +* The BibleTime source code is licensed under the GNU General Public License version 2.0. +* +**********/ + +#ifndef MACROS_H +#define MACROS_H + + +/** + \file macros.h + \brief This file is for listing reusable macros used in the BibleTime source code. +*/ + + +/** + \def DEPRECATED(func) + \brief Macro for declaring functions and methods as deprecated. +*/ + +#ifdef __GNUC__ + #define DEPRECATED(func) func __attribute__ ((deprecated)) +#elif defined(_MSC_VER) + #define DEPRECATED(func) __declspec(deprecated) func +#else + #define DEPRECATED(func) func +#endif + + +/** + \def LIKELY(c) + \brief Gives the compiler a hint that the given conditional is likely to + evaluate to true. + + This helps GCC to generate code which is optimized in respect to branch + prediction. +*/ + +/** + \def UNLIKELY(c) + \brief Gives the compiler a hint that the given conditional is likely to + evaluate to false. + + This helps GCC to generate code which is optimized in respect to branch + prediction. +*/ + +#ifdef __GNUC__ + #define LIKELY(c) __builtin_expect(!!(c),true) + #define UNLIKELY(c) __builtin_expect(!!(c),false) +#else + #define LIKELY(c) !!(c) + #define UNLIKELY(c) !!(c) +#endif + + +#endif // #ifdef MACROS_H diff --git a/src/util/migrationutil.cpp b/src/util/migrationutil.cpp deleted file mode 100644 index 84d38a5..0000000 --- a/src/util/migrationutil.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#include "util/migrationutil.h" - -#include -#include -#include "backend/config/cbtconfig.h" -#include "util/directory.h" - -// Sword includes: -#include "swversion.h" - - -namespace util { -namespace migration { - -void checkMigration() { - if (CBTConfig::get(CBTConfig::bibletimeVersion) != BT_VERSION) { - sword::SWVersion lastVersion(CBTConfig::get(CBTConfig::bibletimeVersion).toUtf8()); - //lastVersion will be 0.0, if it was an old KDE install, - //because the config could not be found yet - if (lastVersion < sword::SWVersion("1.7.0") ) { - tryMigrationFromKDE3(); // - } - } -} - -// Migration code for KDE 4 port, moves from old config dir to ~/.bibletime/ -void tryMigrationFromKDE3() { - namespace DU = util::directory; - - //List of potential old KDE directories to load data from. - QStringList searchDirs; - searchDirs << "/.kde" << "/.kde3" << "/.kde3.5"; - searchDirs << "/.kde3.4" << "/.kde3.3" << "/.kde3.2"; - searchDirs << "/.kde3.1" << "/.kde3.0"; - - foreach (QString searchDir, searchDirs) { - QString currSearch = QDir::homePath() + searchDir; - QDir searchHome(currSearch); - QFile oldRc(currSearch + "/share/config/bibletimerc"); - //Copy our old bibletimerc into the new KDE4 directory. - QString newRcLoc(DU::getUserBaseDir().absolutePath() + "/bibletimerc"); - QFile newRc(newRcLoc); - - //Migrate only if the old config exists and the new doesn't - if (oldRc.exists() && !newRc.exists()) { - QMessageBox msg (QMessageBox::Question, QObject::tr("Settings Migration"), - QObject::tr("It appears you have a BibleTime configuration from KDE 3 stored in %1, and you have not migrated it to this version. Would you like to import it?").arg(currSearch), QMessageBox::Yes | QMessageBox::No); - int result = msg.exec(); - if (result != QMessageBox::Yes) { - break; - } - oldRc.copy(newRcLoc); - QFile oldBookmarks(currSearch + "/share/apps/bibletime/bookmarks.xml"); - if (oldBookmarks.exists()) { - QString newBookmarksLoc(DU::getUserBaseDir().absolutePath() + "/" + "bookmarks.xml"); - QFile newBookmarks(newBookmarksLoc); - newBookmarks.remove(); - oldBookmarks.copy(newBookmarksLoc); - } - QDir sessionDir(currSearch + "/share/apps/bibletime/sessions"); - if (sessionDir.exists()) { - DU::copyRecursive( - sessionDir.absolutePath(), - DU::getUserSessionsDir().absolutePath()); - } - else { - QDir oldSessionDir(currSearch + "/share/apps/bibletime/profiles"); - if (oldSessionDir.exists()) { - DU::copyRecursive( - oldSessionDir.absolutePath(), - DU::getUserSessionsDir().absolutePath()); - } - } - //We found at least a config file, so we are done - //searching for migration data. - break; - } - } - CBTConfig::syncConfig(); -} - -} // namespace migration -} // namespace util diff --git a/src/util/migrationutil.h b/src/util/migrationutil.h deleted file mode 100644 index 8686978..0000000 --- a/src/util/migrationutil.h +++ /dev/null @@ -1,38 +0,0 @@ -/********* -* -* This file is part of BibleTime's source code, http://www.bibletime.info/. -* -* Copyright 1999-2008 by the BibleTime developers. -* The BibleTime source code is licensed under the GNU General Public License version 2.0. -* -**********/ - -#ifndef UTIL_MIGRATIONUTIL_H -#define UTIL_MIGRATIONUTIL_H - -namespace util { - -/** - * Tools for handling settings migration automatically. - * @author The BibleTime team - */ -namespace migration { - -/** -* Performs any and all applicable migration actions, if neccessary -*/ -void checkMigration(); - -/* - * Performs a migration from a KDE 3 version of BibleTime. It supports all - * KDE 3 versions of BibleTime, including versions older than 1.3. Its - * only alteration is to move files to the new location, and to rename the - * sessions directory from pre-1.3 versions if necessary. It does not - * change any settings. - */ -void tryMigrationFromKDE3(); - -} // namespace migration -} // namespace util - -#endif diff --git a/src/util/tool.cpp b/src/util/tool.cpp index 8e8bb00..b8ee486 100644 --- a/src/util/tool.cpp +++ b/src/util/tool.cpp @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -23,29 +23,6 @@ #include "util/dialogutil.h" -/** Converts HTML text to plain text */ -QString util::tool::htmlToText(const QString& html) { - QString newText = html; - // convert some tags we need in code - newText.replace( QRegExp(" "), "#SPACE#" ); - newText.replace( QRegExp("\\s*"), "
    \n" ); - newText.replace( QRegExp("#SPACE#"), " " ); - - QRegExp re("<.+>"); - re.setMinimal(true); - newText.replace( re, "" ); - return newText; -} - -/** Converts text to HTML (\n to
    ) */ -QString util::tool::textToHTML(const QString& text) { - QString newText = text; - newText.replace( QRegExp("\n"), "#NEWLINE#" ); - newText.replace( QRegExp("\n"), "
    \n" ); - newText.replace( QRegExp("#NEWLINE#"), "
    \n"); - return newText; -} - /** Creates the file filename and put text into the file. */ bool util::tool::savePlainFile( const QString& filename, const QString& text, const bool& forceOverwrite, QTextCodec* fileCodec) { @@ -86,45 +63,43 @@ bool util::tool::savePlainFile( const QString& filename, const QString& text, co } -/** Returns the icon used for the module given as aparameter. */ -QIcon util::tool::getIconForModule( CSwordModuleInfo* module_info ) { +QIcon util::tool::getIconForModule(const CSwordModuleInfo *module) { namespace DU = util::directory; - return DU::getIcon(getIconNameForModule(module_info)); + return DU::getIcon(getIconNameForModule(module)); } -/** Returns the name for the icon used for the module given as aparameter. */ -QString util::tool::getIconNameForModule( CSwordModuleInfo* module_info ) { +QString util::tool::getIconNameForModule(const CSwordModuleInfo *module) { //qDebug() << "util::tool::getIconNameForModule"; - if (!module_info) return CResMgr::modules::book::icon_locked; + if (!module) return CResMgr::modules::book::icon_locked; - if (module_info->category() == CSwordModuleInfo::Cult) { + if (module->category() == CSwordModuleInfo::Cult) { return "stop.svg"; } - switch (module_info->type()) { + switch (module->type()) { case CSwordModuleInfo::Bible: - if (module_info->isLocked()) + if (module->isLocked()) return CResMgr::modules::bible::icon_locked; else return CResMgr::modules::bible::icon_unlocked; break; case CSwordModuleInfo::Lexicon: - if (module_info->isLocked()) + if (module->isLocked()) return CResMgr::modules::lexicon::icon_locked; else return CResMgr::modules::lexicon::icon_unlocked; break; case CSwordModuleInfo::Commentary: - if (module_info->isLocked()) + if (module->isLocked()) return CResMgr::modules::commentary::icon_locked; else return CResMgr::modules::commentary::icon_unlocked; break; case CSwordModuleInfo::GenericBook: - if (module_info->isLocked()) + if (module->isLocked()) return CResMgr::modules::book::icon_locked; else return CResMgr::modules::book::icon_unlocked; @@ -132,7 +107,7 @@ QString util::tool::getIconNameForModule( CSwordModuleInfo* module_info ) { case CSwordModuleInfo::Unknown: //fallback default: - if (module_info->isLocked()) + if (module->isLocked()) return CResMgr::modules::book::icon_locked; else return CResMgr::modules::book::icon_unlocked; @@ -141,17 +116,31 @@ QString util::tool::getIconNameForModule( CSwordModuleInfo* module_info ) { return CResMgr::modules::book::icon_unlocked; } -QLabel* util::tool::explanationLabel(QWidget* parent, const QString& heading, const QString& text ) { - QString br; +QLabel* util::tool::explanationLabel(QWidget *parent, const QString &heading, const QString &text) { + QLabel *label = new QLabel(parent); + initExplanationLabel(label, heading, text); + return label; +} + +void util::tool::initExplanationLabel(QLabel *label, const QString &heading, const QString &text) { + QString labelText; + if (!heading.isEmpty()) { + labelText += ""; + labelText += heading; + labelText += ""; + } if (!heading.isEmpty() && !text.isEmpty()) { - br = QString::fromLatin1(" - "); + labelText += " - "; } - QLabel* label = new QLabel( QString::fromLatin1("%1%2%3").arg(heading).arg(br).arg(text), parent ); - + if (!text.isEmpty()) { + labelText += ""; + labelText += text; + labelText += ""; + } + label->setText(labelText); label->setWordWrap(true); label->setMargin(1); label->setFrameStyle(QFrame::Box | QFrame::Sunken); - return label; } /** No descriptions */ @@ -176,99 +165,57 @@ bool util::tool::inHTMLTag(int pos, QString & text) { return false; } -QString util::tool::moduleToolTip(CSwordModuleInfo* module) { - Q_ASSERT(module); - if (!module) { - return QString::null; - } - - QString text; - - text = QString("%1 ").arg( module->name() ) - + ((module->category() == CSwordModuleInfo::Cult) ? QString::fromLatin1("%1
    ").arg(QObject::tr("Take care, this work contains cult / questionable material!")) : QString::null); +QString util::tool::remoteModuleToolTip(const CSwordModuleInfo &module, + const QString &localVer) +{ + QString text = "

    "; + text += module.name(); + text += " "; - text += QString("(") + module->config(CSwordModuleInfo::Description) + QString(")


    "); - - text += QObject::tr("Language") + QString(": %1
    ").arg( module->language()->translatedName() ); - - if (module->isEncrypted()) { - text += QObject::tr("Unlock key") + QString(": %1
    ") - .arg(!module->config(CSwordModuleInfo::CipherKey).isEmpty() ? module->config(CSwordModuleInfo::CipherKey) : QString("%1").arg(QObject::tr("not set"))); + if (module.category() == CSwordModuleInfo::Cult) { + text += ""; + text += QObject::tr("Take care, this work contains cult / questionable " + "material!"); + text += "
    "; } - if (module->hasVersion()) { - text += QObject::tr("Version") + QString(": %1
    ").arg( module->config(CSwordModuleInfo::ModuleVersion) ); - } + text += "("; + text += module.config(CSwordModuleInfo::Description); + text += ")
    "; - QString options; - unsigned int opts; - for (opts = CSwordModuleInfo::filterTypesMIN; opts <= CSwordModuleInfo::filterTypesMAX; ++opts) { - if (module->has( static_cast(opts) )) { - if (!options.isEmpty()) { - options += QString::fromLatin1(", "); - } - - options += CSwordBackend::translatedOptionName( - static_cast(opts) - ); - } - } - - if (!options.isEmpty()) { - text += QObject::tr("Options") + QString::fromLatin1(": ") + options + QString(""); - } - - if (text.right(4) == QString::fromLatin1("
    ")) { - text = text.left(text.length() - 4); - } - - return text; -} - -QString util::tool::remoteModuleToolTip(CSwordModuleInfo* module, QString localVer) { - Q_ASSERT(module); - if (!module) { - return QString::null; - } - - QString text; - - text = QString("

    %1 ").arg( module->name() ) - + ((module->category() == CSwordModuleInfo::Cult) ? QString::fromLatin1("%1
    ").arg(QObject::tr("Take care, this work contains cult / questionable material!")) : QString::null); - - text += QString("(") + module->config(CSwordModuleInfo::Description) + QString(")


    "); - - if (module->isEncrypted()) { - text += QObject::tr("Encrypted - needs unlock key") + QString("
    "); + if (module.isEncrypted()) { + text += QObject::tr("Encrypted - needs unlock key"); + text += "
    "; } if (!localVer.isEmpty()) { - text += QString("") + QObject::tr("Updated version available!") + QString("
    "); + text += ""; + text += QObject::tr("Updated version available!"); + text += "
    "; } - if (module->hasVersion()) { - text += QObject::tr("Version") + QString(": %1").arg( module->config(CSwordModuleInfo::ModuleVersion) ); + if (module.hasVersion()) { + text += QObject::tr("Version"); + text += ": "; + text += module.config(CSwordModuleInfo::ModuleVersion); } + // if installed already if (!localVer.isEmpty()) { - text += QString(" ") + QObject::tr("Installed version") + QString(": %1").arg(localVer); - } - text += QString("
    "); - - text += QString("(") + QObject::tr("Double click for more information") + QString(")

    "); - - - if (text.right(4) == QString::fromLatin1("
    ")) { - text = text.left(text.length() - 4); + text += " "; + text += QObject::tr("Installed version"); + text += ": "; + text += localVer; } + text += "
    ("; + text += QObject::tr("Double click for more information"); + text += ")

    "; return text; } int util::tool::mWidth(const QWidget* widget, int m) { - if (widget) { - return widget->fontMetrics().width(QString().fill('M', m)); - } - return QApplication::fontMetrics().width(QString().fill('M', m)); + if (widget) return widget->fontMetrics().width(QString(m, 'M')); + return QApplication::fontMetrics().width(QString(m, 'M')); } diff --git a/src/util/tool.h b/src/util/tool.h index 9dc753f..0d1981b 100644 --- a/src/util/tool.h +++ b/src/util/tool.h @@ -2,7 +2,7 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2011 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ @@ -22,52 +22,49 @@ class QWidget; namespace util { namespace tool { -/** - * Converts HTML text to plain text. - * This function converts some HTML tags in text (e.g.
    to \n) - * @return The text withput HTML tags and with converted
    to \n - */ -QString htmlToText(const QString&); -/** -* Converts text to HTML converting some text commands into HTML tags (e.g. \n to
    ) -* @return The HTML formatted text we got after changing \n to
    -*/ -QString textToHTML(const QString&); /** * Creates the file filename and put the text of parameter "text" into the file. * @return True if saving was sucessful, otherwise false */ bool savePlainFile( const QString& filename, const QString& text, const bool& forceOverwrite = false, QTextCodec* fileCodec = QTextCodec::codecForLocale()); + +/** + \param[in] module the module whose icon to return. + \returns the icon used for the a module. +*/ +QIcon getIconForModule(const CSwordModuleInfo *module); + /** -* Returns the icon used for the module given as aparameter. + \param[in] module the module whose icon name to return. + \returns the icon name used for the a module. */ -QIcon getIconForModule( CSwordModuleInfo* ); +QString getIconNameForModule(const CSwordModuleInfo *module); + /** -* Returns the name for the icon used for the module given as aparameter. + Returns a new QLabel initialized by initExplanationLabel(). */ -QString getIconNameForModule( CSwordModuleInfo* ); +QLabel *explanationLabel(QWidget *parent, const QString &heading, const QString &text); -/** Returns a label to explain difficult things of dialogs. -* This function returns a label with heading "heading" and explanation "text". This label should be used to -* explain difficult things of the GUI, e.g. in the optionsdialog. +/** + Initializes a QLabel to explain difficult things of dialogs. The label should be used to + explain difficult things of the GUI, e.g. in the options dialog pages. + \param[in] label The label to initialize + \param[in] heading The heading for the label. + \param[in] text The text for the label. */ -QLabel* explanationLabel(QWidget* parent, const QString& heading, const QString& text ); +void initExplanationLabel(QLabel *label, const QString &heading, const QString &text); + /** * Returns true if the character at position "pos" of text is inside an HTML tag. Returns false if it's not inside an HTML tag. */ bool inHTMLTag(int pos, QString & text); -/** Return the module's tooltip text -* @param module The module required for the tooltip -* @return The tooltip text for the passed module -*/ -QString moduleToolTip(CSwordModuleInfo* module); - /** Return the module's tooltip text for a remote module * @param module The module required for the tooltip * @return The tooltip text for the passed module */ -QString remoteModuleToolTip(CSwordModuleInfo* module, QString localVer); +QString remoteModuleToolTip(const CSwordModuleInfo &module, + const QString &localVer); /** * Returns the width in pixels for a string which has mCount 'M' letters, using the specified widget's font. -- cgit v1.2.3