aboutsummaryrefslogtreecommitdiff
path: root/src/readerview.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/readerview.cc')
-rw-r--r--src/readerview.cc192
1 files changed, 154 insertions, 38 deletions
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;
+ }
+ }
}