diff options
-rw-r--r-- | src/header.cc | 10 | ||||
-rw-r--r-- | src/mods.cc | 7 | ||||
-rw-r--r-- | src/readerview.cc | 192 | ||||
-rw-r--r-- | src/readerview.h | 45 | ||||
-rw-r--r-- | src/sword.cc | 168 | ||||
-rw-r--r-- | src/sword.h | 29 |
6 files changed, 184 insertions, 267 deletions
diff --git a/src/header.cc b/src/header.cc index c40e44e..69e0742 100644 --- a/src/header.cc +++ b/src/header.cc @@ -10,7 +10,7 @@ Header::Header(ReaderView *reader, Gtk::Window *window) this->reader = reader; this->window = window; set_show_close_button(true); - set_title ("Bible Reader"); + set_title("Bible Reader"); set_has_subtitle(false); //this->override_background_color(*(new Gdk::RGBA("#1d1f21"))); //this->override_color(*(new Gdk::RGBA("#c5c8c6"))); @@ -143,7 +143,7 @@ void Header::updateMenus() { }); versionBox->add(*scale); - vector<string> versions = reader->getAllVersions(); + vector<string> versions = libbible::getModuleNames(); if(versions.size() > 8) { Gtk::ScrolledWindow *sw = Gtk::manage(new Gtk::ScrolledWindow); sw->set_propagate_natural_width(true); @@ -158,7 +158,8 @@ void Header::updateMenus() { item->set_relief(Gtk::ReliefStyle::RELIEF_NONE); item->signal_clicked().connect([version, this]() { menuMenu.popdown(); - this->reader->setVersion(version); + libbible::settingsWrite("biblereader::currMod", version); + this->reader->refresh(); updateButtons(); updateMenus(); showText(); @@ -170,7 +171,7 @@ void Header::updateMenus() { menuMenu.popdown(); std::vector<std::string> toDel {version}; this->mods->uninstallMods(toDel); - reader->modsUpdated(); + reader->refresh(); updateButtons(); updateMenus(); }); @@ -205,6 +206,5 @@ void Header::showMods() { void Header::showText() { window->remove(); window->add(*this->reader); - //this->reader->setChapter(1); window->show_all_children(); } diff --git a/src/mods.cc b/src/mods.cc index 405b316..0f6f498 100644 --- a/src/mods.cc +++ b/src/mods.cc @@ -37,7 +37,7 @@ void Mods::onNotify() { if(isComplete) { if(worker && worker->joinable()) { worker->join(); - header->reader->modsUpdated(); + header->reader->refresh(); header->updateButtons(); header->updateMenus(); endProgress(); @@ -114,10 +114,7 @@ void Mods::displayMain() { add->set_filter(filter); add->signal_file_set().connect([this, add]() { installMods(add->get_filenames()); - auto newMods = this->header->reader->modsUpdated(); - if(! newMods.empty()) { - this->header->reader->setVersion(newMods[0]); - } + this->header->reader->refresh(); this->header->updateMenus(); this->header->updateButtons(); this->header->showText(); diff --git a/src/readerview.cc b/src/readerview.cc index aef003d..d008be6 100644 --- a/src/readerview.cc +++ b/src/readerview.cc @@ -1,12 +1,50 @@ #include "readerview.h" -#include "sword.h" #include <libbible.h> #include <gdkmm/rgba.h> +#include <algorithm> + +using namespace std; + +std::string getCurrMod() { + auto mods = libbible::getModuleNames(); + std::string currMod = libbible::settingsRead("biblereader::currMod"); + if(std::find(mods.begin(), mods.end(), currMod) == mods.end()) { + currMod = libbible::settingsRead("module"); + if(std::find(mods.begin(), mods.end(), currMod) == mods.end()) { + if(! mods.empty()) { + // New default mod (previous was deleted) + currMod = *mods.begin(); + libbible::settingsWrite("module", currMod); + libbible::settingsWrite("biblereader::currMod", currMod); + } else { + currMod = std::string(); + } + } + } + return currMod; +} + +void updateConfig(string book, int chapter, struct config *conf) { + string currMod = getCurrMod(); + if(currMod.empty()) { + conf->chapter = 0; + conf->book = ""; + conf->bookFull = ""; + conf->maxChapter = 0; + conf->version = ""; + } else { + auto passages = libbible::getPassages(currMod, book); + conf->chapter = chapter; + conf->book = passages[0].bookShort; + conf->bookFull = passages[0].book; + conf->maxChapter = passages.back().chapterStart; + conf->version = currMod; + } +} ReaderView::ReaderView() -: text() + : text() { - this->sword = new Sword(); this->conf = new struct config; text.set_editable(false); text.set_cursor_visible(false); @@ -17,43 +55,18 @@ ReaderView::ReaderView() scroll->add(text); add(*scroll); // Open the passage we had last time - string book = libbible::settingsRead("book"); + std::string book = libbible::settingsRead("book"); int chapter = libbible::settingsReadInt("chapter"); if(book.empty() || chapter == 0) { book = "Genesis"; chapter = 1; } - sword->getConfig(book, chapter, conf); + updateConfig(book, chapter, conf); refresh(); } ReaderView::~ReaderView() {} -// Returns all new mods -std::vector<std::string> ReaderView::modsUpdated() { - auto oldMods = getAllVersions(); - std::sort(oldMods.begin(), oldMods.end()); - sword = new Sword(); - auto newMods = getAllVersions(); - std::sort(newMods.begin(), newMods.end()); - std::vector<std::string> justNew; - std::set_difference(newMods.begin(), newMods.end(), oldMods.begin(), oldMods.end(), std::back_inserter(justNew)); - refresh(); - return justNew; -} - -void ReaderView::refresh() { - auto textBuffer = text.get_buffer(); - libbible::settingsWrite("book", conf->book); - libbible::settingsWriteInt("chapter", conf->chapter); - sword->getConfig(conf->book, conf->chapter, conf); - // Get passage back - string passage = conf->book + " " + std::to_string(conf->chapter); - textBuffer->set_text(""); // Clear contents - //auto iter = textBuffer->get_iter_at_offset(0); - sword->fillBuffer(passage, textBuffer); -} - void ReaderView::setChapter(int chapter) { conf->chapter = chapter; refresh(); @@ -81,18 +94,121 @@ std::string ReaderView::getBookFull() { } std::vector<std::string> ReaderView::getAllBooks() { - return sword->getBooks(); -} - -void ReaderView::setVersion(std::string version) { - sword->setModule(version); - refresh(); + string currMod = getCurrMod(); + if(currMod.empty()) { + return vector<string>(); + } + return libbible::getBooks(currMod); } std::string ReaderView::getVersion() { return conf->version; } -std::vector<std::string> ReaderView::getAllVersions() { - return sword->getModules(); +void ReaderView::refresh() { + auto buf = text.get_buffer(); + libbible::settingsWrite("book", conf->book); + libbible::settingsWriteInt("chapter", conf->chapter); + updateConfig(conf->book, conf->chapter, conf); + // Get passage back + string ref = conf->book + " " + std::to_string(conf->chapter); + buf->set_text(""); // Clear contents + + string currMod = getCurrMod(); + if(currMod.empty()) { + auto iter = buf->get_iter_at_offset(0); + iter = buf->insert_markup(iter, "<big><b>No modules installed.</b></big>\n"); + iter = buf->insert_markup(iter, "Please download some modules at:\n"); + iter = buf->insert_markup(iter, "\thttp://crosswire.org/sword/modules/ModDisp.jsp?modType=Bibles\n"); + iter = buf->insert_markup(iter, "Then install them using the menu in the upper right corner, or use the built-in installer to download and install modules."); + return; + } + + auto texts = libbible::getText(libbible::getPassage(currMod, ref)); + + auto iter = buf->get_iter_at_offset(0); + + auto verseSize = buf->create_tag(); + verseSize->property_size() = libbible::settingsReadInt("fontsize"); + if(verseSize->property_size() == 0) { + verseSize->property_size() = 12000; + } + + auto verseScale = buf->create_tag(); + verseScale->property_scale() = 0.8; + auto titleScale = buf->create_tag(); + titleScale->property_scale() = 1.5; + titleScale->property_weight() = 600; + auto verseOffset = buf->create_tag(); + verseOffset->property_rise() = 3000; + auto indent = buf->create_tag(); + indent->property_left_margin() = 40; + auto redletter = buf->create_tag(); + redletter->property_foreground_gdk() = Gdk::Color("red"); + + int verse = 0; + string indentString = " "; + bool isNewline = true; + for(auto tex : texts) { + std::vector<Glib::RefPtr<Gtk::TextBuffer::Tag>> tags = {verseSize}; + bool isParagraph = false; + bool isIndent = false; + bool isDivineName = false; + bool isPreverse = false; + for(string modifier : tex.modifiers) { + if(modifier == "paragraph") { + isParagraph = true; + } else if (modifier == "line indent0") { + isIndent = true; + } else if (modifier == "divineName") { + isDivineName = true; + } else if (modifier == "wordsOfJesus") { + tags.push_back(redletter); + } else if (modifier == "title") { + tags.push_back(titleScale); + // Ensure newline + if(!tex.text.empty() and tex.text.back() != '\n') { + tex.text.push_back('\n'); + } + } else if (modifier == "preverse") { + isPreverse = true; + } else if (modifier == "parallel") { + // We don't support this (yet) + tex.text = ""; + } + } + if(isIndent) { + isParagraph = false; + if(isNewline) { + tags.push_back(indent); + } + } + if(isParagraph) { + iter = buf->insert_with_tags(iter, indentString, tags); + } + if(tex.verse != verse && ! isPreverse) { + std::vector<Glib::RefPtr<Gtk::TextBuffer::Tag>> verseTags(tags.begin(), tags.end()); + verseTags.push_back(verseScale); + verseTags.push_back(verseOffset); + iter = buf->insert_with_tags(iter, " " + std::to_string(tex.verse), verseTags); + verse = tex.verse; + } + if(isDivineName) { + // There's no small caps support. Sigh. We do fake small caps instead. + // Because i lazy, first letter is normal caps and rest small caps, always. + transform(tex.text.begin(), tex.text.end(), tex.text.begin(), ::toupper); + iter = buf->insert_with_tags(iter, tex.text.substr(0, 1), tags); + auto tag = buf->create_tag(); + tag->property_scale() = 0.75; + tags.push_back(tag); + iter = buf->insert_with_tags(iter, tex.text.substr(1), tags); + } else { + iter = buf->insert_with_tags(iter, tex.text, tags); + } + if(!tex.text.empty() and tex.text.back() == '\n') { + isNewline = true; + } else { + isNewline = false; + } + } } diff --git a/src/readerview.h b/src/readerview.h index 0ea631e..7c0436b 100644 --- a/src/readerview.h +++ b/src/readerview.h @@ -1,32 +1,33 @@ #pragma once #include <gtkmm.h> -class Sword; - class ReaderView : public Gtk::Frame { -public: - ReaderView(); - virtual ~ReaderView(); - - void setChapter(int chapter); - int getChapter(void); - int getChapterMax(void); - void setBook(std::string book); - std::string getBook(void); - std::string getBookFull(void); - std::vector<std::string> getAllBooks(void); + public: + ReaderView(); + virtual ~ReaderView(); - void setVersion(std::string version); - std::string getVersion(void); - std::vector<std::string> getAllVersions(void); + void setChapter(int chapter); + int getChapter(void); + int getChapterMax(void); + void setBook(std::string book); + std::string getBook(void); + std::string getBookFull(void); + std::vector<std::string> getAllBooks(void); - void refresh(void); + std::string getVersion(void); + + void refresh(void); - std::vector<std::string> modsUpdated(void); + protected: + Gtk::TextView text; + struct config *conf; +}; -protected: - Sword *sword; - Gtk::TextView text; - struct config *conf; +struct config { + int chapter; + std::string book; + std::string bookFull; + int maxChapter; + std::string version; }; diff --git a/src/sword.cc b/src/sword.cc deleted file mode 100644 index 936100a..0000000 --- a/src/sword.cc +++ /dev/null @@ -1,168 +0,0 @@ -#include "sword.h" -#include <libbible.h> -#include <sstream> -#include <wctype.h> - -using namespace std; - -bool isNoMods; - -Sword::Sword() { - auto mods = libbible::getModules(); - isNoMods = mods.empty(); - string defaultMod = libbible::settingsRead("module"); - currMod = libbible::settingsRead("biblereader::currMod"); - if(mods.find(currMod) == mods.end()) { - currMod = defaultMod; - } - if(mods.find(currMod) == mods.end()) { - currMod = string(); - if(! mods.empty()) { - // New default mod (previous was deleted) - defaultMod = mods.begin()->first; - libbible::settingsWrite("module", defaultMod); - currMod = defaultMod; - } - } -} - -Sword::~Sword() {} - -vector<string> Sword::getModules() { - vector<string> mods; - auto modsInstalled = libbible::getModules(); - for(auto pair : modsInstalled) { - mods.push_back(pair.first); - } - return mods; -} - -void Sword::setModule(string version) { - currMod = version; - libbible::settingsWrite("biblereader::currMod", currMod); -} - -void Sword::fillBuffer(string ref, Glib::RefPtr<Gtk::TextBuffer> buf) { - buf->set_text(""); // Clear contents - - if(isNoMods) { - auto iter = buf->get_iter_at_offset(0); - iter = buf->insert_markup(iter, "<big><b>No modules installed.</b></big>\n"); - iter = buf->insert_markup(iter, "Please download some modules at:\n"); - iter = buf->insert_markup(iter, "\thttp://crosswire.org/sword/modules/ModDisp.jsp?modType=Bibles\n"); - iter = buf->insert_markup(iter, "Then install them using the menu in the upper right corner, or use the built-in installer to download and install modules."); - return; - } - - auto texts = libbible::getText(libbible::getPassage(currMod, ref)); - - auto iter = buf->get_iter_at_offset(0); - - auto verseSize = buf->create_tag(); - verseSize->property_size() = libbible::settingsReadInt("fontsize"); - if(verseSize->property_size() == 0) { - verseSize->property_size() = 12000; - } - - auto verseScale = buf->create_tag(); - verseScale->property_scale() = 0.8; - auto titleScale = buf->create_tag(); - titleScale->property_scale() = 1.5; - titleScale->property_weight() = 600; - auto verseOffset = buf->create_tag(); - verseOffset->property_rise() = 3000; - auto indent = buf->create_tag(); - indent->property_left_margin() = 40; - auto redletter = buf->create_tag(); - redletter->property_foreground_gdk() = Gdk::Color("red"); - - int verse = 0; - string indentString = " "; - bool isNewline = true; - for(auto tex : texts) { - std::vector<Glib::RefPtr<Gtk::TextBuffer::Tag>> tags = {verseSize}; - bool isParagraph = false; - bool isIndent = false; - bool isDivineName = false; - bool isPreverse = false; - for(string modifier : tex.modifiers) { - if(modifier == "paragraph") { - isParagraph = true; - } else if (modifier == "line indent0") { - isIndent = true; - } else if (modifier == "divineName") { - isDivineName = true; - } else if (modifier == "wordsOfJesus") { - tags.push_back(redletter); - } else if (modifier == "title") { - tags.push_back(titleScale); - // Ensure newline - if(!tex.text.empty() and tex.text.back() != '\n') { - tex.text.push_back('\n'); - } - } else if (modifier == "preverse") { - isPreverse = true; - } else if (modifier == "parallel") { - // We don't support this (yet) - tex.text = ""; - } - } - if(isIndent) { - isParagraph = false; - if(isNewline) { - tags.push_back(indent); - } - } - if(isParagraph) { - iter = buf->insert_with_tags(iter, indentString, tags); - } - if(tex.verse != verse && ! isPreverse) { - std::vector<Glib::RefPtr<Gtk::TextBuffer::Tag>> verseTags(tags.begin(), tags.end()); - verseTags.push_back(verseScale); - verseTags.push_back(verseOffset); - iter = buf->insert_with_tags(iter, " " + std::to_string(tex.verse), verseTags); - verse = tex.verse; - } - if(isDivineName) { - // There's no small caps support. Sigh. We do fake small caps instead. - // Because i lazy, first letter is normal caps and rest small caps, always. - transform(tex.text.begin(), tex.text.end(), tex.text.begin(), ::toupper); - iter = buf->insert_with_tags(iter, tex.text.substr(0, 1), tags); - auto tag = buf->create_tag(); - tag->property_scale() = 0.75; - tags.push_back(tag); - iter = buf->insert_with_tags(iter, tex.text.substr(1), tags); - } else { - iter = buf->insert_with_tags(iter, tex.text, tags); - } - if(!tex.text.empty() and tex.text.back() == '\n') { - isNewline = true; - } else { - isNewline = false; - } - } -} - -void Sword::getConfig(string book, int chapter, struct config *conf) { - if(isNoMods) { - conf->chapter = 0; - conf->book = ""; - conf->bookFull = ""; - conf->maxChapter = 0; - conf->version = ""; - } else { - auto passages = libbible::getPassages(currMod, book); - conf->chapter = chapter; - conf->book = passages[0].bookShort; - conf->bookFull = passages[0].book; - conf->maxChapter = passages.back().chapterStart; - conf->version = currMod; - } -} - -vector<string> Sword::getBooks() { - if(isNoMods) { - return vector<string>(); - } - return libbible::getModules()[currMod]; -} diff --git a/src/sword.h b/src/sword.h deleted file mode 100644 index 1cd7f61..0000000 --- a/src/sword.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include <gtkmm.h> -#include <vector> - -using namespace::std; - -class Sword { -public: - Sword(); - virtual ~Sword(); - - std::vector<std::string> getModules(void); - std::vector<std::string> getBooks(void); - void setModule(std::string modName); - void fillBuffer(std::string ref, Glib::RefPtr<Gtk::TextBuffer> buf); - void getConfig(std::string book, int chapter, struct config *conf); - -protected: - std::string currMod; - -}; - -struct config { - int chapter; - std::string book; - std::string bookFull; - int maxChapter; - std::string version; -}; |