aboutsummaryrefslogtreecommitdiff
path: root/src/sword.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/sword.cc')
-rw-r--r--src/sword.cc168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/sword.cc b/src/sword.cc
new file mode 100644
index 0000000..a693085
--- /dev/null
+++ b/src/sword.cc
@@ -0,0 +1,168 @@
+#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.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.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];
+}