Beispiel #1
0
string bible_abbreviations (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Abbreviations"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  header.addBreadCrumb (bible_manage_url (), menu_logic_bible_manage_text ());
  page = header.run ();
  
  Assets_View view;
  
  string success_message;
  string error_message;
  
  // The name of the Bible.
  string bible = access_bible_clamp (request, request->query ["bible"]);
  view.set_variable ("bible", filter_string_sanitize_html (bible));
  
  // Data submission.
  if (request->post.count ("submit")) {
    string data = request->post ["data"];
    data = filter_string_trim (data);
    if (data != "") {
      if (unicode_string_is_valid (data)) {
        Database_Config_Bible::setBookAbbreviations (bible, data);
        success_message = translate("The abbreviations were saved.");
      } else {
        error_message = translate("Please supply valid Unicode UTF-8 text.");
      }
    } else {
      success_message = translate("Nothing was saved.");
    }
  }

  string data = Database_Config_Bible::getBookAbbreviations (bible);
  data = filter_abbreviations_display (data);
  view.set_variable ("data", data);
  
  view.set_variable ("success_message", success_message);
  view.set_variable ("error_message", error_message);
  
  page += view.render ("bible", "abbreviations");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #2
0
string resource_admin (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  
  string page;
  Assets_Header header = Assets_Header (translate("Resources"), request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();
  Assets_View view;

  
  vector <string> resources = resource_external_names ();
  string resourceblock;
  for (auto & resource : resources) {
    resourceblock.append ("<p>");
    resourceblock.append ("<a href=\"download?name=" + resource + "\" title=\"" + translate("Download resource") + "\">" + resource + "</a>");
    resourceblock.append ("</p>\n");
  }
  view.set_variable ("resourceblock", resourceblock);

  
  page += view.render ("resource", "admin");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #3
0
string editone_preview (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  bool touch = request->session_logic ()->touchEnabled ();

  string page;
  
  Assets_Header header = Assets_Header (translate("Preview"), request);
  header.setNavigator ();
  header.setEditorStylesheet ();
  if (touch) header.jQueryTouchOn ();
  header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ());
  header.refresh (5, "index");
  page = header.run ();
  
  Assets_View view;
  
  // Get active Bible, and check read access to it.
  // If needed, change Bible to one it has read access to.
  string bible = access_bible_clamp (request, request->database_config_user()->getBible ());
  
  string cls = Filter_Css::getClass (bible);
  string font = Fonts_Logic::getTextFont (bible);
  int direction = Database_Config_Bible::getTextDirection (bible);
  int lineheight = Database_Config_Bible::getLineHeight (bible);
  int letterspacing = Database_Config_Bible::getLetterSpacing (bible);
  view.set_variable ("custom_class", cls);
  view.set_variable ("custom_css", Filter_Css::getCss (cls,
                                                       Fonts_Logic::getFontPath (font),
                                                       direction,
                                                       lineheight,
                                                       letterspacing));
  
  int book = Ipc_Focus::getBook (webserver_request);
  int chapter = Ipc_Focus::getChapter (webserver_request);
  //int verse = Ipc_Focus::getVerse (webserver_request);
  
  string stylesheet = request->database_config_user()->getStylesheet ();
  
  string usfm = request->database_bibles()->getChapter (bible, book, chapter);
  
  Editor_Usfm2Html editor_usfm2html;
  editor_usfm2html.load (usfm);
  editor_usfm2html.stylesheet (stylesheet);
  editor_usfm2html.run ();
  
  string html = editor_usfm2html.get ();
  view.set_variable ("html", html);
 
  page += view.render ("editone", "preview");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #4
0
string mapping_map (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  Database_Mappings database_mappings;
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Verse mappings"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  header.addBreadCrumb (mapping_index_url (), menu_logic_mapping_index_text ());

  page = header.run ();

  Assets_View view;
  string success;
  
  string name = request->query["name"];
  view.set_variable ("name", name);

  if (request->post.count ("submit")) {
    string data = request->post["data"];
    database_mappings.import (name, data);
    success = translate("The verse mapping was saved");
  }

  view.set_variable ("success", success);

  string data = database_mappings.output (name);
  view.set_variable ("data", data);
  
  page += view.render ("mapping", "map");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #5
0
string search_replace2 (void * webserver_request)
{
  // Build the advanced replace page.
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  string bible = request->database_config_user()->getBible ();
  string page;
  Assets_Header header = Assets_Header (translate("Replace"), request);
  header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ());
  page = header.run ();
  Assets_View view;
  view.set_variable ("bible", bible);
  string script = "var searchBible = \"" + bible + "\";";
  view.set_variable ("script", script);
  page += view.render ("search", "replace2");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #6
0
string administration_timezone (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  string page;

  Assets_Header header = Assets_Header (translate("Timezone"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();

  Assets_View view;

  string success;
  string error;
  if (request->post.count ("submit")) {
    string input = request->post ["timezone"];
    input = filter_string_str_replace ("UTC", "", input);
    int timezone = convert_to_int (input);
    bool clipped = false;
    if (timezone < MINIMUM_TIMEZONE) {
      timezone = MINIMUM_TIMEZONE;
      clipped = true;
    }
    if (timezone > MAXIMUM_TIMEZONE) {
      timezone = MAXIMUM_TIMEZONE;
      clipped = true;
    }
    if (clipped) error = translate ("The timezone was clipped");
    Database_Config_General::setTimezone (timezone);
    success = translate ("The timezone was saved");
  }

  int timezone = Database_Config_General::getTimezone();
  view.set_variable ("timezone", convert_to_string (timezone));
  view.set_variable ("success", success);
  view.set_variable ("error", error);
  
  page += view.render ("administration", "timezone");

  page += Assets_Page::footer ();

  return page;
}
Beispiel #7
0
string editverse_index (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  bool touch = request->session_logic ()->touchEnabled ();

  if (request->query.count ("switchbook") && request->query.count ("switchchapter")) {
    int switchbook = convert_to_int (request->query ["switchbook"]);
    int switchchapter = convert_to_int (request->query ["switchchapter"]);
    Ipc_Focus::set (request, switchbook, switchchapter, 1);
    Navigation_Passage::recordHistory (request, switchbook, switchchapter, 1);
  }
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Edit USFM"), request);
  header.setNavigator ();
  if (touch) header.jQueryTouchOn ();
  header.notifItOn ();
  header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ());
  page = header.run ();
  
  Assets_View view;
  
  if (request->query.count ("changebible")) {
    string changebible = request->query ["changebible"];
    if (changebible == "") {
      Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to open in the editor"), "", "");
      vector <string> bibles = access_bible_bibles (request);
      for (auto bible : bibles) {
        dialog_list.add_row (bible, "changebible", bible);
      }
      page += dialog_list.run();
      return page;
    } else {
      request->database_config_user()->setBible (changebible);
    }
  }
  
  // Get active Bible, and check read access to it.
  // If needed, change Bible to one it has read access to.
  string bible = access_bible_clamp (request, request->database_config_user()->getBible ());
  if (request->query.count ("bible")) bible = access_bible_clamp (request, request->query ["bible"]);
  view.set_variable ("bible", bible);
  
  // Store the active Bible in the page's javascript.
  view.set_variable ("navigationCode", Navigation_Passage::code (bible));
  
  string chapterLoaded = locale_logic_text_loaded ();
  string chapterSaving = locale_logic_text_saving ();
  string chapterSaved = locale_logic_text_saved ();
  string chapterRetrying = locale_logic_text_retrying ();
  string script =
  "var verseEditorVerseLoaded = '" + chapterLoaded + "';\n"
  "var verseEditorVerseSaving = '" + chapterSaving + "';\n"
  "var verseEditorVerseSaved = '" + chapterSaved + "';\n"
  "var verseEditorChapterRetrying = '" + chapterRetrying + "';\n"
  "var verseEditorWriteAccess = true;"
  "var unsentBibleDataTimeoutWarning = '" + bible_logic_unsent_unreceived_data_warning (false) + "';\n";
  config_logic_swipe_enabled (webserver_request, script);
  view.set_variable ("script", script);
  
  string cls = Filter_Css::getClass (bible);
  string font = Fonts_Logic::getTextFont (bible);
  int direction = Database_Config_Bible::getTextDirection (bible);
  int lineheight = Database_Config_Bible::getLineHeight (bible);
  int letterspacing = Database_Config_Bible::getLetterSpacing (bible);
  view.set_variable ("custom_class", cls);
  view.set_variable ("custom_css", Filter_Css::getCss (cls,
                                                             Fonts_Logic::getFontPath (font),
                                                             direction,
                                                             lineheight,
                                                             letterspacing));
  
  // Whether to enable fast Bible editor switching.
  if (request->database_config_user ()->getFastEditorSwitchingAvailable ()) {
    view.enable_zone ("fastswitcheditor");
  }
  
  page += view.render ("editverse", "index");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #8
0
string edit_index (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  
  bool touch = request->session_logic ()->touchEnabled ();

  
  if (request->query.count ("switchbook") && request->query.count ("switchchapter")) {
    int switchbook = convert_to_int (request->query ["switchbook"]);
    int switchchapter = convert_to_int (request->query ["switchchapter"]);
    int switchverse = 1;
    if (request->query.count ("switchverse")) switchverse = convert_to_int (request->query ["switchverse"]);
    Ipc_Focus::set (request, switchbook, switchchapter, switchverse);
    Navigation_Passage::recordHistory (request, switchbook, switchchapter, switchverse);
  }

  
  string page;
  
  
  Assets_Header header = Assets_Header (translate("Edit"), request);
  header.setNavigator ();
  header.setEditorStylesheet ();
  if (touch) header.jQueryTouchOn ();
  header.notifItOn ();
  header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ());
  page = header.run ();
  
  
  if (request->query.count ("changebible")) {
    string changebible = request->query ["changebible"];
    if (changebible == "") {
      Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to open in the editor"), "", "");
      vector <string> bibles = access_bible_bibles (request);
      for (auto & bible : bibles) {
        dialog_list.add_row (bible, "changebible", bible);
      }
      page += dialog_list.run();
      return page;
    } else {
      request->database_config_user()->setBible (changebible);
      // Going to another Bible, ensure that the focused book exists there.
      int book = Ipc_Focus::getBook (request);
      vector <int> books = request->database_bibles()->getBooks (changebible);
      if (find (books.begin(), books.end(), book) == books.end()) {
        if (!books.empty ()) book = books [0];
        else book = 0;
        Ipc_Focus::set (request, book, 1, 1);
      }
    }
  }
  
  
  Assets_View view;
  
  
  // Active Bible, and check access.
  string bible = access_bible_clamp (request, request->database_config_user()->getBible ());
  if (request->query.count ("bible")) bible = access_bible_clamp (request, request->query ["bible"]);
  view.set_variable ("bible", bible);
  
  
  // Store the active Bible in the page's javascript.
  view.set_variable ("navigationCode", Navigation_Passage::code (bible));
  

  int verticalCaretPosition = request->database_config_user ()->getVerticalCaretPosition ();
  string script =
  "var editorChapterLoaded = '" + locale_logic_text_loaded () + "';\n"
  "var editorChapterSaving = '" + locale_logic_text_saving () + "';\n"
  "var editorChapterSaved = '" + locale_logic_text_saved () + "';\n"
  "var editorChapterRetrying = '" + locale_logic_text_retrying () + "';\n"
  "var editorChapterReformat = '" + locale_logic_text_reformat () + "';\n"
  "var editorWriteAccess = true;\n"
  "var verticalCaretPosition = " + convert_to_string (verticalCaretPosition) + ";\n"
  "var unsentBibleDataTimeoutWarning = '" + bible_logic_unsent_unreceived_data_warning (false) + "';\n";
  config_logic_swipe_enabled (webserver_request, script);
  view.set_variable ("script", script);
  
  
  string clss = Filter_Css::getClass (bible);
  string font = Fonts_Logic::getTextFont (bible);
  int direction = Database_Config_Bible::getTextDirection (bible);
  int lineheight = Database_Config_Bible::getLineHeight (bible);
  int letterspacing = Database_Config_Bible::getLetterSpacing (bible);
  view.set_variable ("custom_class", clss);
  view.set_variable ("custom_css", Filter_Css::getCss (clss,
                                                       Fonts_Logic::getFontPath (font),
                                                       direction,
                                                       lineheight,
                                                       letterspacing));
  
 
  // In basic mode the editor has no controls and fewer indicators.
  // In basic mode, the user can just edit text, and cannot style it.
  bool basic_mode = config_logic_basic_mode (webserver_request);
  if (!basic_mode) view.enable_zone ("advancedmode");
  
  
  // Whether to enable fast Bible editor switching.
  if (!basic_mode && request->database_config_user ()->getFastEditorSwitchingAvailable ()) {
    view.enable_zone ("fastswitcheditor");
  }

  
  // Whether to enable the styles button.
  if (request->database_config_user ()->getEnableStylesButtonVisualEditors ()) {
    view.enable_zone ("stylesbutton");
  }
  
  
  page += view.render ("edit", "index");
  
  
  page += Assets_Page::footer ();
  
  
  return page;
}
Beispiel #9
0
string bible_book (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Book"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  header.addBreadCrumb (bible_manage_url (), menu_logic_bible_manage_text ());
  page = header.run ();
  
  Assets_View view;
  
  string success_message;
  string error_message;
  
  // The name of the Bible.
  string bible = access_bible_clamp (request, request->query["bible"]);
  view.set_variable ("bible", filter_string_sanitize_html (bible));
  
  // The book.
  int book = convert_to_int (request->query ["book"]);
  view.set_variable ("book", convert_to_string (book));
  string book_name = Database_Books::getEnglishFromId (book);
  view.set_variable ("book_name", filter_string_sanitize_html (book_name));
  
  // Whether the user has write access to this Bible book.
  bool write_access = access_bible_book_write (request, "", bible, book);
  if (write_access) view.enable_zone ("write_access");
  
  // Delete chapter.
  string deletechapter = request->query ["deletechapter"];
  if (deletechapter != "") {
    string confirm = request->query ["confirm"];
    if (confirm == "") {
      Dialog_Yes dialog_yes = Dialog_Yes ("book", translate("Would you like to delete this chapter?"));
      dialog_yes.add_query ("bible", bible);
      dialog_yes.add_query ("book", convert_to_string (book));
      dialog_yes.add_query ("deletechapter", deletechapter);
      page += dialog_yes.run ();
      return page;
    } if (confirm == "yes") {
      if (write_access) Bible_Logic::deleteChapter (bible, book, convert_to_int (deletechapter));
    }
  }
  
  // Add chapter.
  if (request->query.count ("createchapter")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("book", translate("Please enter the number for the new chapter"), "", "createchapter", "");
    dialog_entry.add_query ("bible", bible);
    dialog_entry.add_query ("book", convert_to_string (book));
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count ("createchapter")) {
    int createchapter = convert_to_int (request->post ["entry"]);
    vector <int> chapters = request->database_bibles ()->getChapters (bible, book);
    // Only create the chapters if it does not yet exist.
    if (find (chapters.begin(), chapters.end(), createchapter) == chapters.end()) {
      vector <string> feedback;
      bool result = true;
      if (write_access) result = book_create (bible, book, createchapter, feedback);
      string message = filter_string_implode (feedback, " ");
      if (result) success_message = message;
      else error_message = message;
    } else {
      error_message = translate ("This chapter already exists");
    }
  }
  
  // Available chapters.
  vector <int> chapters = request->database_bibles ()->getChapters (bible, book);
  string chapterblock;
  for (auto & chapter : chapters) {
    chapterblock.append ("<a href=\"chapter?bible=");
    chapterblock.append (bible);
    chapterblock.append ("&book=");
    chapterblock.append (convert_to_string (book));
    chapterblock.append ("&chapter=");
    chapterblock.append (convert_to_string (chapter));
    chapterblock.append ("\">");
    chapterblock.append (convert_to_string (chapter));
    chapterblock.append ("</a>\n");
  }
  view.set_variable ("chapterblock", chapterblock);
  
  view.set_variable ("success_message", success_message);
  view.set_variable ("error_message", error_message);
  
  if (!client_logic_client_enabled ()) view.enable_zone ("server");

  page += view.render ("bible", "book");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #10
0
string resource_manage (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  
  string page;
  Assets_Header header = Assets_Header (translate("USFM Resources"), request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();
  Assets_View view;
  
  
  Database_UsfmResources database_usfmresources = Database_UsfmResources ();

  
  // Delete resource.
  string remove = request->query ["delete"];
  if (remove != "") {
    string confirm = request->query ["confirm"];
    if (confirm == "") {
      Dialog_Yes dialog_yes = Dialog_Yes ("manage", translate("Would you like to delete this resource?"));
      dialog_yes.add_query ("delete", remove);
      page += dialog_yes.run ();
      return page;
    } if (confirm == "yes") {
      if (access_bible_write (request, remove)) {
        database_usfmresources.deleteResource (remove);
        // The Cloud updates the list of available USFM resources for the clients.
        tasks_logic_queue (LISTUSFMRESOURCES);
      } else {
        view.set_variable ("error", translate("You do not have write access to this resource"));
      }
    }
  }
  
  
  // Convert resource.
  string convert = request->query ["convert"];
  if (convert != "") {
    string confirm = request->query ["confirm"];
    if (confirm == "") {
      Dialog_Yes dialog_yes = Dialog_Yes ("manage", translate("Would you like to convert this resource to a Bible?"));
      dialog_yes.add_query ("convert", convert);
      page += dialog_yes.run ();
      return page;
    } if (confirm == "yes") {
      if (access_bible_write (request, convert)) {
        tasks_logic_queue (CONVERTRESOURCE2BIBLE, {convert});
        redirect_browser (request, journal_index_url ());
        return "";
      } else {
        view.set_variable ("error", translate("Insufficient privileges"));
      }
    }
  }
  
  
  vector <string> resources = database_usfmresources.getResources ();
  vector <string> resourceblock;
  for (auto & resource : resources) {
    resourceblock.push_back ("<p>");
    resourceblock.push_back ("<a href=\"?delete=" + resource + "\" class=\"deleteresource\" title=\"" + translate("Remove") + "\">");
    resourceblock.push_back (emoji_wastebasket ());
    resourceblock.push_back ("</a>");
    resourceblock.push_back ("<a href=\"?convert=" + resource + "\" class=\"convertresource\" title=\"" + translate("Convert") + "\">");
    resourceblock.push_back ("♻");
    resourceblock.push_back ("</a>");
    resourceblock.push_back (resource);
    resourceblock.push_back ("</p>");
  }
  view.set_variable ("resourceblock", filter_string_implode (resourceblock, "\n"));

  
  page += view.render ("resource", "manage");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #11
0
string user_account (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  string page;

  Assets_Header header = Assets_Header (translate("Account"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();

  Assets_View view;

  string username = request->session_logic()->currentUser ();
  string email = request->database_users()->get_email (username);

  bool actions_taken = false;
  vector <string> success_messages;

  // Form submission handler.
  if (request->post.count ("submit")) {
    bool form_is_valid = true;
    string currentpassword = request->post ["currentpassword"];
    string newpassword     = request->post ["newpassword"];
    string newpassword2    = request->post ["newpassword2"];
    string newemail        = request->post ["newemail"];
  
    if ((newpassword != "") || (newpassword2 != "")) {
      if (newpassword.length () < 4) {
        form_is_valid = false;
        view.set_variable ("new_password_invalid_message", translate("Password should be at least four characters long"));
      }
      if (newpassword2.length () < 4) {
        form_is_valid = false;
        view.set_variable ("new_password2_invalid_message", translate("Password should be at least four characters long"));
      }
      if (newpassword2 != newpassword) {
        form_is_valid = false;
        view.set_variable ("new_password2_invalid_message", translate("Passwords do not match"));
      }
      if (!request->database_users()->matchUserPassword (username, currentpassword)) {
        form_is_valid = false;
        view.set_variable ("current_password_invalid_message", translate("Current password is not valid"));
      }
      if (form_is_valid) {
        request->database_users()->set_password (username, newpassword);
        actions_taken = true;
        success_messages.push_back (translate("The new password was saved"));
      }
    }
  
    if (newemail != "") {
      if (!filter_url_email_is_valid (newemail)) {
        form_is_valid = false;
        view.set_variable ("new_email_invalid_message", translate("Email address is not valid"));
      }
      if (!request->database_users()->matchUserPassword (username, currentpassword)) {
        form_is_valid = false;
        view.set_variable ("current_password_invalid_message", translate("Current password is not valid"));
      }
      if (form_is_valid) {
        Confirm_Worker confirm_worker = Confirm_Worker (webserver_request);
        string initial_subject = translate("Email address verification");
        string initial_body = translate("Somebody requested to change the email address that belongs to your account.");
        string query = request->database_users()->updateEmailQuery (username, newemail);
        string subsequent_subject = translate("Email address change");
        string subsequent_body = translate("The email address that belongs to your account has been changed successfully.");
        confirm_worker.setup (newemail, initial_subject, initial_body, query, subsequent_subject, subsequent_body);
        actions_taken = true;
        success_messages.push_back (translate("A verification email was sent to ") + newemail);
      }
    }
  
    if (!actions_taken) {
      success_messages.push_back (translate("No changes were made"));
    }
  
  }

  view.set_variable ("username", filter_string_sanitize_html (username));
  view.set_variable ("email", filter_string_sanitize_html (email));
  string success_message = filter_string_implode (success_messages, "\n");
  view.set_variable ("success_messages", success_message);
  if (!actions_taken) view.enable_zone ("no_actions_taken");

  page += view.render ("user", "account");

  page += Assets_Page::footer ();

  return page;
}
Beispiel #12
0
string styles_sheetm (void * webserver_request)
{
    Webserver_Request * request = (Webserver_Request *) webserver_request;

    string page;

    Assets_Header header = Assets_Header (translate("Stylesheet"), webserver_request);
    header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
    header.addBreadCrumb (styles_indexm_url (), menu_logic_styles_indexm_text ());
    page = header.run ();

    Assets_View view;

    string name = request->query["name"];
    view.set_variable ("name", filter_string_sanitize_html (name));

    Database_Styles database_styles;

    string username = request->session_logic ()->currentUser ();
    int userlevel = request->session_logic ()->currentLevel ();
    bool write = database_styles.hasWriteAccess (username, name);
    if (userlevel >= Filter_Roles::admin ()) write = true;

    if (request->post.count ("new")) {
        string newstyle = request->post["entry"];
        vector <string> existing_markers = database_styles.getMarkers (name);
        if (find (existing_markers.begin(), existing_markers.end(), newstyle) != existing_markers.end()) {
            page += Assets_Page::error (translate("This style already exists"));
        } else {
            database_styles.addMarker (name, newstyle);
            styles_sheets_create_all ();
            page += Assets_Page::success (translate("The style has been created"));
        }
    }
    if (request->query.count("new")) {
        Dialog_Entry dialog_entry = Dialog_Entry ("sheetm", translate("Please enter the name for the new style"), "", "new", "");
        dialog_entry.add_query ("name", name);
        page += dialog_entry.run ();
        return page;
    }

    string del = request->query["delete"];
    if (del != "") {
        if (write) database_styles.deleteMarker (name, del);
    }

    vector <string> markerblock;
    map <string, string> markers_names = database_styles.getMarkersAndNames (name);
    for (auto & item : markers_names) {
        string marker = item.first;
        string marker_name = item.second;
        markerblock.push_back ("<tr>");
        markerblock.push_back ("<td><a href=\"view?sheet=" + name + "&style=" + marker + "\">" + marker + "</a></td>");
        markerblock.push_back ("<td>" + marker_name + "</td>");
        markerblock.push_back ("<td>[<a href=\"?name=" + name + "&delete=" + marker + "\">" + translate("delete") + "]</a></td>");
        markerblock.push_back ("</tr>");
    }
    view.set_variable ("markerblock", filter_string_implode (markerblock, "\n"));

    page += view.render ("styles", "sheetm");

    page += Assets_Page::footer ();

    return page;
}
Beispiel #13
0
string manage_users (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  
  bool user_updated = false;
  bool privileges_updated = false;
  
  
  string page;
  Assets_Header header = Assets_Header (translate("Users"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();

  
  Assets_View view;


  int myLevel = request->session_logic ()->currentLevel ();
  
  
  // New user creation.
  if (request->query.count ("new")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("users", translate("Please enter a name for the new user"), "", "new", "");
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count ("new")) {
    string user = request->post["entry"];
    if (request->database_users ()->usernameExists (user)) {
      page += Assets_Page::error (translate("User already exists"));
    } else {
      request->database_users ()->addNewUser(user, user, Filter_Roles::member (), "");
      user_updated = true;
      page += Assets_Page::success (translate("User created"));
    }
  }
  
  
  // The user to act on.
  string objectUsername = request->query["user"];
  int objectUserLevel = request->database_users ()->getUserLevel (objectUsername);
  
  
  // Delete a user.
  if (request->query.count ("delete")) {
    string role = Filter_Roles::text (objectUserLevel);
    string email = request->database_users ()->getUserToEmail (objectUsername);
    string message = "Deleted user " + objectUsername + " with role " + role + " and email " + email;
    Database_Logs::log (message, Filter_Roles::admin ());
    request->database_users ()->removeUser (objectUsername);
    user_updated = true;
    database_privileges_client_remove (objectUsername);
    page += Assets_Page::success (message);
    // Also remove any privileges for this user.
    // In particular for the Bible privileges this is necessary,
    // beause if old users remain in the privileges storage,
    // then a situation where no user has any privileges to any Bible,
    // and thus all relevant users have all privileges,
    // can never be achieved again.
    Database_Privileges::removeUser (objectUsername);
    // Remove any login tokens the user might have had: Just to clean things up.
    Database_Login::removeTokens (objectUsername);
    // Remove any settings for the user.
    // The advantage of this is that when a user is removed, all settings are gone,
    // so when the same user would be created again, all settings will go back to their defaults.
    request->database_config_user ()->remove (objectUsername);
  }
  
  
  // The user's role.
  if (request->query.count ("level")) {
    string level = request->query ["level"];
    if (level == "") {
      Dialog_List dialog_list = Dialog_List ("users", translate("Select a role for") + " " + objectUsername, "", "");
      dialog_list.add_query ("user", objectUsername);
      for (int i = Filter_Roles::lowest (); i <= Filter_Roles::highest (); i++) {
        if (i <= myLevel) {
          dialog_list.add_row (Filter_Roles::text (i), "level", convert_to_string (i));
        }
      }
      page += dialog_list.run ();
      return page;
    } else {
      request->database_users ()->updateUserLevel (objectUsername, convert_to_int (level));
      user_updated = true;
    }
  }
  
  
  // User's email address.
  if (request->query.count ("email")) {
    string email = request->query ["email"];
    if (email == "") {
      string question = translate("Please enter an email address for") + " " + objectUsername;
      string value = request->database_users ()->getUserToEmail (objectUsername);
      Dialog_Entry dialog_entry = Dialog_Entry ("users", question, value, "email", "");
      dialog_entry.add_query ("user", objectUsername);
      page += dialog_entry.run ();
      return page;
    }
  }
  if (request->post.count ("email")) {
    string email = request->post["entry"];
    if (filter_url_email_is_valid (email)) {
      page += Assets_Page::success (translate("Email address was updated"));
      request->database_users ()->updateUserEmail (objectUsername, email);
      user_updated = true;
    } else {
      page += Assets_Page::error (translate("The email address is not valid"));
    }
  }
  
  
  // Fetch all available Bibles.
  vector <string> allbibles = request->database_bibles ()->getBibles ();
  
  
  // Add Bible to user account.
  if (request->query.count ("addbible")) {
    string addbible = request->query["addbible"];
    if (addbible == "") {
      Dialog_List dialog_list = Dialog_List ("users", translate("Would you like to grant the user access to a Bible?"), "", "");
      dialog_list.add_query ("user", objectUsername);
      for (auto bible : allbibles) {
        dialog_list.add_row (bible, "addbible", bible);
      }
      page += dialog_list.run ();
      return page;
    } else {
      Assets_Page::success (translate("The user has been granted access to this Bible"));
      // Write access depends on whether it's a translator role or higher.
      bool write = (objectUserLevel >= Filter_Roles::translator ());
      Database_Privileges::setBible (objectUsername, addbible, write);
      user_updated = true;
      privileges_updated = true;
    }
  }
  
  
  // Remove Bible from user.
  if (request->query.count ("removebible")) {
    string removebible = request->query ["removebible"];
    Database_Privileges::removeBibleBook (objectUsername, removebible, 0);
    user_updated = true;
    privileges_updated = true;
    Assets_Page::success (translate("The user no longer has access to this Bible"));
  }
  
  
  // Login on behalf of another user.
  if (request->query.count ("login")) {
    request->session_logic ()->switchUser (objectUsername);
    redirect_browser (request, session_switch_url ());
    return "";
  }
  
  
  // User accounts to display.
  vector <string> tbody;
  // Retrieve assigned users.
  vector <string> users = access_user_assignees (webserver_request);
  for (auto & username : users) {
    // Gather details for this user account.
    objectUserLevel = request->database_users ()->getUserLevel (username);
    string namedrole = Filter_Roles::text (objectUserLevel);
    string email = request->database_users ()->getUserToEmail (username);
    if (email == "") email = "--";
    tbody.push_back ("<tr>");
    tbody.push_back ("<td><a href=\"?user="******"&delete\">✗</a> " + username + "</td>");
    tbody.push_back ("<td>│</td>");
    tbody.push_back ("<td><a href=\"?user="******"&level\">" + namedrole + "</a></td>");
    tbody.push_back ("<td>│</td>");
    tbody.push_back ("<td><a href=\"?user="******"&email\">" + email + "</a></td>");
    tbody.push_back ("<td>│</td>");
    tbody.push_back ("<td>");

    if (objectUserLevel < Filter_Roles::manager ()) {
      for (auto & bible : allbibles) {
        bool exists = Database_Privileges::getBibleBookExists (username, bible, 0);
        if (exists) {
          bool read, write;
          Database_Privileges::getBible (username, bible, read, write);
          if  (objectUserLevel >= Filter_Roles::translator ()) write = true;
          tbody.push_back ("<a href=\"?user="******"&removebible=" + bible + "\">✗</a>");
          tbody.push_back ("<a href=\"/bible/settings?bible=" + bible + "\">" + bible + "</a>");
          tbody.push_back ("<a href=\"write?user="******"&bible=" + bible + "\">");
          int readwritebooks = 0;
          vector <int> books = request->database_bibles ()->getBooks (bible);
          for (auto book : books) {
            Database_Privileges::getBibleBook (username, bible, book, read, write);
            if (write) readwritebooks++;
          }
          tbody.push_back ("(" + convert_to_string (readwritebooks) + "/" + convert_to_string (books.size ()) + ")");
          tbody.push_back ("</a>");
          tbody.push_back ("|");
        }
      }
    }
    if (objectUserLevel >= Filter_Roles::manager ()) {
      // Managers and higher roles have access to all Bibles.
      tbody.push_back ("(" + translate ("all") + ")");
    } else {
      tbody.push_back ("<a href=\"?user="******"&addbible=\">➕</a>");
    }
    tbody.push_back ("</td>");

    tbody.push_back ("<td>│</td>");

    tbody.push_back ("<td>");
    if (objectUserLevel >= Filter_Roles::manager ()) {
      // Managers and higher roles have all privileges.
      tbody.push_back ("(" + translate ("all") + ")");
    } else {
      tbody.push_back ("<a href=\"privileges?user="******"\">" + translate ("edit") + "</a>");
    }
    tbody.push_back ("</td>");
    
    // Logging for another user.
    if (myLevel > objectUserLevel) {
      tbody.push_back ("<td>│</td>");
      tbody.push_back ("<td>");
      tbody.push_back ("<a href=\"?user="******"&login\">" + translate ("Login") + "</a>");
      tbody.push_back ("</td>");
    }
    
    tbody.push_back ("</tr>");
  }

  view.set_variable ("tbody", filter_string_implode (tbody, "\n"));

  page += view.render ("manage", "users");

  page += Assets_Page::footer ();
  
  if (user_updated) notes_logic_maintain_note_assignees (true);
  if (privileges_updated) database_privileges_client_create (objectUsername, true);

  return page;
}
Beispiel #14
0
string bible_manage (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Bibles"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();
  
  Assets_View view;
  
  string success_message;
  string error_message;
  
  // New Bible handler.
  if (request->query.count ("new")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("manage", translate("Please enter a name for the new empty Bible"), "", "new", "");
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count ("new")) {
    string bible = request->post ["entry"];
    vector <string> bibles = request->database_bibles ()->getBibles ();
    if (find (bibles.begin(), bibles.end(), bible) != bibles.end()) {
      error_message = translate("This Bible already exists");
    } else {
      request->database_bibles ()->createBible (bible);
      // Check / grant access.
      if (!access_bible_write (request, bible)) {
        string me = request->session_logic ()->currentUser ();
        Database_Privileges::setBible (me, bible, true);
      }
      success_message = translate("The Bible was created");
      // Creating a Bible removes any Sample Bible that might have been there.
      if (!config_logic_demo_enabled ()) {
        request->database_bibles ()->deleteBible (demo_sample_bible_name ());
        search_logic_delete_bible (demo_sample_bible_name ());
      }
    }
  }
  
  // Copy Bible handler.
  if (request->query.count ("copy")) {
    string copy = request->query["copy"];
    Dialog_Entry dialog_entry = Dialog_Entry ("manage", translate("Please enter a name for where to copy the Bible to"), "", "", "A new Bible will be created with the given name, and the current Bible copied to it");
    dialog_entry.add_query ("origin", copy);
    page += dialog_entry.run ();
    return page;
  }
  if (request->query.count ("origin")) {
    string origin = request->query["origin"];
    if (request->post.count ("entry")) {
      string destination = request->post["entry"];
      vector <string> bibles = request->database_bibles ()->getBibles ();
      if (find (bibles.begin(), bibles.end(), destination) != bibles.end()) {
        error_message = translate("Cannot copy the Bible because the destination Bible already exists.");
      } else {
        // User needs read access to the original.
        if (access_bible_read (request, origin)) {
          request->database_bibles ()->createBible (destination);
          vector <int> books = request->database_bibles ()->getBooks (origin);
          for (auto & book : books) {
            vector <int> chapters = request->database_bibles ()->getChapters (origin, book);
            for (auto & chapter : chapters) {
              string data = request->database_bibles ()->getChapter (origin, book, chapter);
              Bible_Logic::storeChapter (destination, book, chapter, data);
            }
          }
          success_message = translate("The Bible was copied.");
          // Check / grant access to destination Bible.
          if (!access_bible_write (request, destination)) {
            string me = request->session_logic ()->currentUser ();
            Database_Privileges::setBible (me, destination, true);
          }
          // Creating a Bible removes any Sample Bible that might have been there.
          if (!config_logic_demo_enabled ()) {
            request->database_bibles ()->deleteBible (demo_sample_bible_name ());
            search_logic_delete_bible (demo_sample_bible_name ());
          }
        }
      }
    }
  }

  // Delete Bible handler.
  if (request->query.count ("delete")) {
    string bible = request->query ["delete"];
    string confirm = request->query ["confirm"];
    if (confirm == "yes") {
      // User needs write access for delete operation.
      if (access_bible_write (request, bible)) {
        Bible_Logic::deleteBible (bible);
        string gitdirectory = filter_git_directory (bible);
        if (file_exists (gitdirectory)) {
          filter_url_rmdir (gitdirectory);
        }
        // Remove associated settings and privileges.
        Database_Privileges::removeBible (bible);
        Database_Config_Bible::remove (bible);
      } else {
        page += Assets_Page::error ("Insufficient privileges to complete action");
      }
    }
    if (confirm == "") {
      Dialog_Yes dialog_yes = Dialog_Yes ("manage", translate("Would you like to delete this Bible?") + " (" + bible + ")");
      dialog_yes.add_query ("delete", bible);
      page += dialog_yes.run ();
      return page;
    }
  }

  view.set_variable ("success_message", success_message);
  view.set_variable ("error_message", error_message);
  vector <string> bibles = access_bible_bibles (request);
  string bibleblock;
  for (auto & bible : bibles) {
    bibleblock.append ("<li><a href=\"settings?bible=" + bible + "\">" + bible + "</a></li>\n");
  }
  view.set_variable ("bibleblock", bibleblock);

  if (!client_logic_client_enabled ()) view.enable_zone ("server");

  page += view.render ("bible", "manage");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #15
0
string search_strong (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;


  Database_Kjv database_kjv = Database_Kjv ();
  
  
  string bible = request->database_config_user()->getBible ();
  if (request->query.count ("b")) {
    bible = request->query ["b"];
  }
  
  
  if (request->query.count ("load")) {

    int book = Ipc_Focus::getBook (request);
    int chapter = Ipc_Focus::getChapter (request);
    int verse = Ipc_Focus::getVerse (request);
    
    // Get Strong's numbers, plus English snippets.
    string html = "<table>\n";
    vector <Database_Kjv_Item> details = database_kjv.getVerse (book, chapter, verse);
    for (auto & detail : details) {
      string strong = detail.strong;
      string english = detail.english;
      html += "<tr><td><a href=\"" + strong + "\">" + strong + "</a></td><td>" + english + "</td></tr>\n";
    }
    html += "</table>\n";
    
    return html;
  }
  
  
  if (request->query.count ("strong")) {
    
    string strong = request->query ["strong"];
    strong = filter_string_trim (strong);
    
    vector <int> passages;
    
    vector <Passage> details = database_kjv.searchStrong (strong);
    
    for (auto & passage : details) {
      int i_passage = filter_passage_to_integer (passage);
      passages.push_back (i_passage);
    }
    
    passages = array_unique (passages);
    sort (passages.begin(), passages.end());
    
    string output;
    for (auto & passage : passages) {
      if (!output.empty()) output.append ("\n");
      output.append (convert_to_string (passage));
    }
    return output;
  }
  
  
  if (request->query.count ("id")) {
    int id = convert_to_int (request->query ["id"]);
    
    // Get the and passage for this identifier.
    Passage passage = filter_integer_to_passage (id);
    int book = passage.book;
    int chapter = passage.chapter;
    string verse = passage.verse;
    
    // Get the plain text.
    string text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse));
    
    // Format it.
    string link = filter_passage_link_for_opening_editor_at (book, chapter, verse);
    string output = "<div>" + link + " " + text + "</div>";
    
    // Output to browser.
    return output;
  }
  
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Search"), request);
  header.setNavigator ();
  header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ());
  page = header.run ();
  
  Assets_View view;
  
  view.set_variable ("bible", bible);
  
  string script = "var searchBible = \"" + bible + "\";";
  view.set_variable ("script", script);

  page += view.render ("search", "strong");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #16
0
string changes_changes (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  Database_Modifications database_modifications;
  

  bool touch = request->session_logic ()->touchEnabled ();
  
  
  string page;
  Assets_Header header = Assets_Header (translate("Changes"), request);
  header.setStylesheet ();
  header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ());
  if (touch) header.jQueryTouchOn ();
  page += header.run ();
  Assets_View view;
  
  
  string username = request->session_logic()->currentUser ();
  
  
  // Handle AJAX call to remove a change notification.
  if (request->post.count ("remove")) {
    int remove = convert_to_int (request->post["remove"]);
    trash_change_notification (request, remove);
    database_modifications.deleteNotification (remove);
#ifdef HAVE_CLIENT
    request->database_config_user ()->addRemovedChange (remove);
#endif
    request->database_config_user ()->setChangeNotificationsChecksum ("");
    return "";
  }
  
  
  // Handle AJAX call to navigate to the passage belonging to the change notification.
  if (request->post.count ("navigate")) {
    string navigate = request->post["navigate"];
    int id = convert_to_int (navigate);
    Passage passage = database_modifications.getNotificationPassage (id);
    if (passage.book) {
      Ipc_Focus::set (request, passage.book, passage.chapter, convert_to_int (passage.verse));
      Navigation_Passage::recordHistory (request, passage.book, passage.chapter, convert_to_int (passage.verse));
    }
    // Set the correct default Bible for the user.
    string bible = database_modifications.getNotificationBible (id);
    if (!bible.empty ()) request->database_config_user()->setBible (bible);
    return "";
  }
  
  
  // Remove a user's personal changes notifications and their matching change notifications in the Bible.
  string matching = request->query ["matching"];
  if (!matching.empty ()) {
    vector <int> ids = database_modifications.clearNotificationMatches (username, matching, changes_bible_category ());
#ifdef HAVE_CLIENT
    // Client records deletions for sending to the Cloud.
    for (auto & id : ids) {
      request->database_config_user ()->addRemovedChange (id);
    }
#endif
    // Clear checksum cache.
    request->database_config_user ()->setChangeNotificationsChecksum ("");
  }
  
  
  // Remove all the personal change notifications.
  if (request->query.count ("personal")) {
    vector <int> ids = database_modifications.getNotificationTeamIdentifiers (username, changes_personal_category (), true);
    for (auto id : ids) {
      trash_change_notification (request, id);
      database_modifications.deleteNotification (id);
#ifdef HAVE_CLIENT
      request->database_config_user ()->addRemovedChange (id);
#endif
      request->database_config_user ()->setChangeNotificationsChecksum ("");
    }
  }
  
  
  // Remove all the Bible change notifications.
  if (request->query.count ("bible")) {
    vector <int> ids = database_modifications.getNotificationTeamIdentifiers (username, changes_bible_category (), true);
    for (auto id : ids) {
      trash_change_notification (request, id);
      database_modifications.deleteNotification (id);
#ifdef HAVE_CLIENT
      request->database_config_user ()->addRemovedChange (id);
#endif
      request->database_config_user ()->setChangeNotificationsChecksum ("");
    }
  }
  
  
  // Remove all the change notifications made by a certain user.
  if (request->query.count ("dismiss")) {
    string user = request->query ["dismiss"];
    vector <int> ids = database_modifications.getNotificationTeamIdentifiers (username, user, true);
    for (auto id : ids) {
      trash_change_notification (request, id);
      database_modifications.deleteNotification (id);
#ifdef HAVE_CLIENT
      request->database_config_user ()->addRemovedChange (id);
#endif
      request->database_config_user ()->setChangeNotificationsChecksum ("");
    }
  }
  
  
  // Read the identifiers.
  // Limit the number of results to keep the page reasonably fast even if there are many notifications.
  vector <int> personal_ids = database_modifications.getNotificationPersonalIdentifiers (username, changes_personal_category (), true);
  vector <int> bible_ids = database_modifications.getNotificationTeamIdentifiers (username, changes_bible_category (), true);
  vector <int> ids = database_modifications.getNotificationIdentifiers (username, true);

  
  string textblock;
  for (auto id : ids) {
    Passage passage = database_modifications.getNotificationPassage (id);
    string link = filter_passage_link_for_opening_editor_at (passage.book, passage.chapter, passage.verse);
    string category = database_modifications.getNotificationCategory (id);
    if (category == changes_personal_category ()) category = emoji_smiling_face_with_smiling_eyes ();
    if (category == changes_bible_category ()) category = emoji_open_book ();
    string modification = database_modifications.getNotificationModification (id);
    textblock.append ("<div id=\"entry" + convert_to_string (id) + "\">\n");
    textblock.append ("<a href=\"expand\" id=\"expand" + convert_to_string (id) + "\">" + emoji_file_folder () + "</a>\n");
    textblock.append ("<a href=\"remove\" id=\"remove" + convert_to_string (id) + "\">" + emoji_wastebasket () + "</a>\n");
    textblock.append (link + "\n");
    textblock.append (category + "\n");
    textblock.append (modification + "\n");
    textblock.append ("</div>\n");
  }
  view.set_variable ("textblock", textblock);
  
  
  string loading = "\"" + translate("Loading ...") + "\"";
  string script = "var loading = " + loading + ";";
  config_logic_swipe_enabled (webserver_request, script);
  view.set_variable ("script", script);

  
  // Enable links to dismiss categories of notifications depending on whether there's anything to dismiss.
  if (!personal_ids.empty ()) view.enable_zone ("personal");
  if (!bible_ids.empty ()) view.enable_zone ("bible");
  
  
  // Add links to clear the notifications from the individual contributors.
  string dismissblock;
  vector <string> categories = database_modifications.getCategories ();
  for (auto & category : categories) {
    if (category == changes_personal_category ()) continue;
    if (category == changes_bible_category ()) continue;
    string user = category;
    vector <int> ids = database_modifications.getNotificationTeamIdentifiers (username, user, true);
    if (!ids.empty ()) {
      dismissblock.append ("<p>* <a href=\"?dismiss=");
      dismissblock.append (user);
      dismissblock.append ("\">");
      dismissblock.append (user);
      dismissblock.append (": ");
      dismissblock.append (translate("all of them"));
      dismissblock.append (": ");
      dismissblock.append (convert_to_string (ids.size ()));
      dismissblock.append ("</a></p>\n");
    }
  }
  view.set_variable ("dismissblock", dismissblock);

  
  // Add links to clear matching notifications of the various users.
  for (auto & category : categories) {
    if (category == changes_bible_category ()) continue;
    string user = category;
    vector <int> personal_ids = database_modifications.getNotificationTeamIdentifiers (username, user, true);
    string icon = category;
    if (category == changes_personal_category ()) icon = emoji_smiling_face_with_smiling_eyes ();
    if (!personal_ids.empty () && !bible_ids.empty ()) {
      view.add_iteration ("matching", { make_pair ("user", user), make_pair ("icon", icon) } );
    }
  }
  
  
  view.set_variable ("VERSION", config_logic_version ());

  
  if (touch) view.enable_zone ("touch");

  
  view.set_variable ("interlinks", changes_interlinks (webserver_request, changes_changes_url ()));
  
  
  page += view.render ("changes", "changes");
  
  
  page += Assets_Page::footer ();
  return page;
}
Beispiel #17
0
string bible_import (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Import"), webserver_request);
  header.setNavigator ();
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  header.addBreadCrumb (bible_manage_url (), menu_logic_bible_manage_text ());
  page = header.run ();
  
  Assets_View view;
  
  string success_message;
  string error_message;
  
  // The name of the Bible.
  string bible = access_bible_clamp (request, request->query["bible"]);
  view.set_variable ("bible", filter_string_sanitize_html (bible));
  
  int book = Ipc_Focus::getBook (webserver_request);
  int chapter = Ipc_Focus::getChapter (webserver_request);

  // Whether the user has write access to this Bible.
  bool write_access = access_bible_write (request, bible);
  if (write_access) view.enable_zone ("write_access");

  // USFM data submission.
  if (request->post.count ("submit")) {
    // Submission may take long if there's a lot of data or the network is slow.
    string data = request->post ["data"];
    data = filter_url_tag_to_plus (data);
    data = filter_string_trim (data);
    if (data != "") {
      if (unicode_string_is_valid (data)) {
        string datafile = filter_url_tempfile ();
        filter_url_file_put_contents (datafile, data);
        success_message = translate("Import has started. See Journal for progress.");
        tasks_logic_queue (IMPORTBIBLE, { datafile, bible, convert_to_string (book), convert_to_string (chapter) });
      } else {
        error_message = translate("Please supply valid Unicode UTF-8 text.");
      }
    } else {
      success_message = translate("Nothing was imported.");
    }
    // User imported something into this Bible: Set it as the default Bible.
    request->database_config_user()->setBible (bible);
  }

  // File upload.
  if (request->post.count ("upload")) {
    string datafile = filter_url_tempfile () + request->post ["filename"];
    string data = request->post ["data"];
    if (!data.empty ()) {
      filter_url_file_put_contents (datafile, data);
      success_message = translate("Import has started. See Journal for progress.");
      tasks_logic_queue (IMPORTBIBLE, { datafile, bible, convert_to_string (book), convert_to_string (chapter) });
    } else {
      error_message = translate ("Nothing was uploaded");
    }
    // User imported something into this Bible: Set it as the default Bible.
    request->database_config_user()->setBible (bible);
  }
  
#ifdef HAVE_UPLOAD
  view.enable_zone ("enable_upload");
#else
  view.enable_zone ("disable_upload");
#endif
  
  view.set_variable ("success_message", success_message);
  view.set_variable ("error_message", error_message);
  
  page += view.render ("bible", "import");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #18
0
string search_search2 (void * webserver_request)
{
    Webserver_Request * request = (Webserver_Request *) webserver_request;


    Database_Volatile database_volatile = Database_Volatile ();


    string siteUrl = config_logic_site_url ();


    string bible = request->database_config_user()->getBible ();
    if (request->query.count ("bible")) bible = request->query ["bible"];


    bool hit_is_set = request->query.count ("h");
    bool query_is_set = request->query.count ("q");
    int identifier = convert_to_int (request->query ["i"]);
    string query = request->query ["q"];
    string hit = request->query ["h"];


    // Get one search hit.
    if (hit_is_set) {


        // Retrieve the search parameters from the volatile database.
        string query = database_volatile.getValue (identifier, "query");
        //bool casesensitive = convert_to_bool (database_volatile.getValue (identifier, "casesensitive"));
        bool plaintext = convert_to_bool (database_volatile.getValue (identifier, "plaintext"));


        // Get the Bible and passage for this identifier.
        Passage details = Passage::from_text (hit);
        string bible = details.bible;
        int book = details.book;
        int chapter = details.chapter;
        string verse = details.verse;


        // Get the plain text or USFM.
        string text;
        if (plaintext) {
            text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse));
        } else {
            text = search_logic_get_bible_verse_usfm (bible, book, chapter, convert_to_int (verse));
        }


        // Format it.
        string link = filter_passage_link_for_opening_editor_at (book, chapter, verse);
        text =  filter_string_markup_words ({query}, text);
        string output = "<div>" + link + " " + text + "</div>";


        // Output to browser.
        return output;
    }


    // Perform the initial search.
    if (query_is_set) {


        // Get extra search parameters and store them all in the volatile database.
        bool casesensitive = (request->query ["c"] == "true");
        bool plaintext = (request->query ["p"] == "true");
        bool currentbook = (request->query ["b"] == "true");
        string sharing = request->query ["s"];
        database_volatile.setValue (identifier, "query", query);
        database_volatile.setValue (identifier, "casesensitive", convert_to_string (casesensitive));
        database_volatile.setValue (identifier, "plaintext", convert_to_string (plaintext));


        // Deal with case sensitivity.
        // Deal with whether to search the plain text, or the raw USFM.
        // Fetch the initial set of hits.
        vector <Passage> passages;
        if (plaintext) {
            if (casesensitive) {
                passages = search_logic_search_bible_text_case_sensitive (bible, query);
            } else {
                passages = search_logic_search_bible_text (bible, query);
            }
        } else {
            if (casesensitive) {
                passages = search_logic_search_bible_usfm_case_sensitive (bible, query);
            } else {
                passages = search_logic_search_bible_usfm (bible, query);
            }
        }


        // Deal with possible searching in the current book only.
        if (currentbook) {
            int book = Ipc_Focus::getBook (request);
            vector <Passage> bookpassages;
            for (auto & passage : passages) {
                if (book == passage.book) {
                    bookpassages.push_back (passage);
                }
            }
            passages = bookpassages;
        }


        // Deal with how to share the results.
        vector <string> hits;
        for (auto & passage : passages) {
            hits.push_back (passage.to_text ());
        }
        if (sharing != "load") {
            vector <string> loaded_hits = filter_string_explode (database_volatile.getValue (identifier, "hits"), '\n');
            if (sharing == "add") {
                hits.insert (hits.end(), loaded_hits.begin(), loaded_hits.end());
            }
            if (sharing == "remove") {
                hits = filter_string_array_diff (loaded_hits, hits);
            }
            if (sharing == "intersect") {
                hits = array_intersect (loaded_hits, hits);
            }
            hits = array_unique (hits);
        }


        // Generate one string from the hits.
        string output = filter_string_implode (hits, "\n");


        // Store search hits in the volatile database.
        database_volatile.setValue (identifier, "hits", output);


        // Output results.
        return output;
    }


    // Build the advanced search page.
    string page;
    Assets_Header header = Assets_Header (translate("Search"), request);
    header.setNavigator ();
    header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ());
    page = header.run ();
    Assets_View view;
    view.set_variable ("bible", bible);
    string script = "var searchBible = \"" + bible + "\";";
    view.set_variable ("script", script);
    page += view.render ("search", "search2");
    page += Assets_Page::footer ();
    return page;
}
Beispiel #19
0
string manage_index (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  string page;

  Assets_Header header = Assets_Header (translate("Manage"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();

  Assets_View view;
  string success;
  string error;
  
  
  // Force re-index Bibles.
  if (request->query ["reindex"] == "bibles") {
    Database_Config_General::setIndexBibles (true);
    tasks_logic_queue (REINDEXBIBLES, {"1"});
    redirect_browser (request, journal_index_url ());
    return "";
  }
  
  
  // Re-index consultation notes.
  if (request->query ["reindex"] == "notes") {
    Database_Config_General::setIndexNotes (true);
    tasks_logic_queue (REINDEXNOTES);
    redirect_browser (request, journal_index_url ());
    return "";
  }

  
  // Delete a font.
  string deletefont = request->query ["deletefont"];
  if (!deletefont.empty ()) {
    string font = filter_url_basename (deletefont);
    bool font_in_use = false;
    vector <string> bibles = request->database_bibles ()->getBibles ();
    for (auto & bible : bibles) {
      if (font == Fonts_Logic::getTextFont (bible)) font_in_use = true;
    }
    if (!font_in_use) {
      // Only delete a font when it is not in use.
      Fonts_Logic::erase (font);
    } else {
      error = translate("The font could not be deleted because it is in use");
    }
  }
  
  
  // Upload a font.
  if (request->post.count ("uploadfont")) {
    string filename = request->post ["filename"];
    string path = filter_url_create_root_path ("fonts", filename);
    string fontdata = request->post ["fontdata"];
    filter_url_file_put_contents (path, fontdata);
    success = translate("The font has been uploaded.");
  }
  

  // Assemble the font block html.
  vector <string> fonts = Fonts_Logic::getFonts ();
  vector <string> fontsblock;
  for (auto & font : fonts) {
    fontsblock.push_back ("<p>");
#ifndef CLIENT_PREPARED
    fontsblock.push_back ("<a href=\"?deletefont=" + font+ "\" title=\"" + translate("Delete font") + "\"> ✗ </a>");
#endif
    fontsblock.push_back (font);
    fontsblock.push_back ("</p>");
  }
  view.set_variable ("fontsblock", filter_string_implode (fontsblock, "\n"));

  
#ifdef CLIENT_PREPARED
  view.enable_zone ("client");
  view.set_variable ("cloudlink", client_logic_link_to_cloud (manage_index_url (), ""));
#else
  view.enable_zone ("server");
#endif
  
  
  view.set_variable ("success", success);
  view.set_variable ("error", error);
  page += view.render ("manage", "index");

  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #20
0
string user_notifications (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  Database_Config_User database_config_user = Database_Config_User (webserver_request);
  
  string id = request->post ["id"];

  if (id == "editednotessubscription") {
    bool state = !database_config_user.getSubscribeToConsultationNotesEditedByMe ();
    database_config_user.setSubscribeToConsultationNotesEditedByMe (state);
    return get_tick_box (state);
  }

  if (id == "anynotessubscription") {
    bool state = !database_config_user.getNotifyMeOfAnyConsultationNotesEdits ();
    database_config_user.setNotifyMeOfAnyConsultationNotesEdits (state);
    return get_tick_box (state);
  }

  if (id == "emailconfirmationyourposts") {
    bool state = !database_config_user.getNotifyMeOfMyPosts ();
    database_config_user.setNotifyMeOfMyPosts (state);
    return get_tick_box (state);
  }

  if (id == "subscribednotenotification") {
    bool state = !database_config_user.getSubscribedConsultationNoteNotification ();
    database_config_user.setSubscribedConsultationNoteNotification (state);
    return get_tick_box (state);
  }

  if (id == "notesassignment") {
    bool state = !database_config_user.getAssignedToConsultationNotesChanges ();
    database_config_user.setAssignedToConsultationNotesChanges (state);
    return get_tick_box (state);
  }
  
  if (id == "assignednotenotification") {
    bool state = !database_config_user.getAssignedConsultationNoteNotification ();
    database_config_user.setAssignedConsultationNoteNotification (state);
    return get_tick_box (state);
  }
  
  if (id == "suppressemailsfromnotesyouupdated") {
    bool state = !database_config_user.getSuppressMailFromYourUpdatesNotes ();
    database_config_user.setSuppressMailFromYourUpdatesNotes (state);
    return get_tick_box (state);
  }

  if (id == "assignednotesnotification") {
    bool state = !database_config_user.getAssignedNotesStatisticsNotification ();
    database_config_user.setAssignedNotesStatisticsNotification (state);
    return get_tick_box (state);
  }

  if (id == "subscribednotesnotification") {
    bool state = !database_config_user.getSubscribedNotesStatisticsNotification ();
    database_config_user.setSubscribedNotesStatisticsNotification (state);
    return get_tick_box (state);
  }

  if (id == "deletednotenotification") {
    bool state = !database_config_user.getDeletedConsultationNoteNotification ();
    database_config_user.setDeletedConsultationNoteNotification (state);
    return get_tick_box (state);
  }

  if (id == "postponenewnotesmails") {
    bool state = !database_config_user.getPostponeNewNotesMails ();
    database_config_user.setPostponeNewNotesMails (state);
    return get_tick_box (state);
  }

  if (id == "anyonechangesemailnotification") {
    bool state = !database_config_user.getBibleChangesNotification ();
    database_config_user.setBibleChangesNotification (state);
    return get_tick_box (state);
  }

  if (id == "anyonechangesonlinenotifications") {
    bool state = !database_config_user.getGenerateChangeNotifications ();
    database_config_user.setGenerateChangeNotifications (state);
    return get_tick_box (state);
  }

  if (id == "pendingchangenotifications") {
    bool state = !database_config_user.getPendingChangesNotification ();
    database_config_user.setPendingChangesNotification (state);
    return get_tick_box (state);
  }
  
  if (id == "mychangesemailnotifications") {
    bool state = !database_config_user.getUserChangesNotification ();
    database_config_user.setUserChangesNotification (state);
    return get_tick_box (state);
  }
  
  if (id == "mychangesonlinenotifications") {
    bool state = !database_config_user.getUserChangesNotificationsOnline ();
    database_config_user.setUserChangesNotificationsOnline (state);
    return get_tick_box (state);
  }

  if (id == "contributorschangesonlinenotifications") {
    bool state = !database_config_user.getContributorChangesNotificationsOnline ();
    database_config_user.setContributorChangesNotificationsOnline (state);
    return get_tick_box (state);
  }

  if (id == "biblechecksnotification") {
    bool state = !database_config_user.getBibleChecksNotification ();
    database_config_user.setBibleChecksNotification (state);
    return get_tick_box (state);
  }

  if (id == "sprintprogressnotification") {
    bool state = !database_config_user.getSprintProgressNotification ();
    database_config_user.setSprintProgressNotification (state);
    return get_tick_box (state);
  }
  
  string page;

  Assets_Header header = Assets_Header (translate("Notifications"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();

  Assets_View view;

  view.set_variable ("edited_notes_subscription", get_tick_box (database_config_user.getSubscribeToConsultationNotesEditedByMe ()));
  
  view.set_variable ("any_notes_subscription", get_tick_box (database_config_user.getNotifyMeOfAnyConsultationNotesEdits ()));
  
  view.set_variable ("email_confirmation_your_posts", get_tick_box (database_config_user.getNotifyMeOfMyPosts ()));
  
  view.set_variable ("subscription_notification", get_tick_box (database_config_user.getSubscribedConsultationNoteNotification ()));
  
  view.set_variable ("notes_assignment", get_tick_box (database_config_user.getAssignedToConsultationNotesChanges ()));
  
  view.set_variable ("assignment_notification", get_tick_box (database_config_user.getAssignedConsultationNoteNotification ()));
  
  view.set_variable ("suppress_mails_from_your_updates", get_tick_box (database_config_user.getSuppressMailFromYourUpdatesNotes ()));
  
  view.set_variable ("assigned_notes_notifications", get_tick_box (database_config_user.getAssignedNotesStatisticsNotification ()));
  
  view.set_variable ("subscribed_notes_notifications", get_tick_box (database_config_user.getSubscribedNotesStatisticsNotification ()));
  
  view.set_variable ("deleted_note_notification", get_tick_box (database_config_user.getDeletedConsultationNoteNotification ()));
  
  view.set_variable ("postpone_new_notes_mails", get_tick_box (database_config_user.getPostponeNewNotesMails ()));
  
  view.set_variable ("anyone_changes_email_notification", get_tick_box (database_config_user.getBibleChangesNotification ()));
  
  view.set_variable ("anyone_changes_online_notifications", get_tick_box (database_config_user.getGenerateChangeNotifications ()));
  
  view.set_variable ("pending_changes_notifications", get_tick_box (database_config_user.getPendingChangesNotification ()));
  
  view.set_variable ("my_changes_email_notifications", get_tick_box (database_config_user.getUserChangesNotification ()));
  
  view.set_variable ("my_changes_online_notifications", get_tick_box (database_config_user.getUserChangesNotificationsOnline ()));
  
  view.set_variable ("contributors_changes_online_notifications", get_tick_box (database_config_user.getContributorChangesNotificationsOnline ()));
  
  view.set_variable ("bible_checks_notification", get_tick_box (database_config_user.getBibleChecksNotification ()));
  
  view.set_variable ("sprint_progress_notification", get_tick_box (database_config_user.getSprintProgressNotification ()));
  
#ifdef CLIENT_PREPARED
  view.enable_zone ("client");
#else
  view.enable_zone ("server");
#endif

  view.set_variable ("url", client_logic_link_to_cloud (user_notifications_url (), translate("You can set the notifications in Bibledit Cloud.")));

  // The bits accessible to the user depends on the user's privileges.
  bool read_bible, write_bible;
  access_a_bible (webserver_request, read_bible, write_bible);
  if (read_bible) view.enable_zone ("readbible");
  if (write_bible) view.enable_zone ("writebible");
  if (Filter_Roles::access_control (webserver_request, Filter_Roles::consultant ()))
    view.enable_zone ("consultant");

  
  page += view.render ("user", "notifications");

  page += Assets_Page::footer ();

  return page;
}
Beispiel #21
0
string checks_index (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  Database_Check database_check;

  
  string page;
  Assets_Header header = Assets_Header (translate("Checks"), webserver_request);
  header.addBreadCrumb (menu_logic_tools_menu (), menu_logic_tools_text ());
  page = header.run ();
  Assets_View view;
  

  if (request->query.count ("approve")) {
    int approve = convert_to_int (request->query["approve"]);
    database_check.approve (approve);
    view.set_variable ("success", translate("The entry was suppressed."));
  }
  
                        
  if (request->query.count ("delete")) {
    int erase = convert_to_int (request->query["delete"]);
    database_check.erase (erase);
    view.set_variable ("success", translate("The entry was deleted for just now."));
  }

  
  // Get the Bibles the user has write-access to.
  vector <int> bibleIDs;
  vector <string> bibles = request->database_bibles()->getBibles ();
  for (auto bible : bibles) {
    if (access_bible_write (webserver_request, bible)) {
      int id = request->database_bibles()->getID (bible);
      bibleIDs.push_back (id);
    }
  }
  
  
  string resultblock;
  vector <Database_Check_Hit> hits = database_check.getHits ();
  for (auto hit : hits) {
    int bibleID = hit.bible;
    if (find (bibleIDs.begin(), bibleIDs.end (), bibleID) != bibleIDs.end ()) {
      int id = hit.rowid;
      string bible = filter_string_sanitize_html (request->database_bibles()->getName (bibleID));
      int book = hit.book;
      int chapter = hit.chapter;
      int verse = hit.verse;
      string link = filter_passage_link_for_opening_editor_at (book, chapter, convert_to_string (verse));
      string information = filter_string_sanitize_html (hit.data);
      resultblock.append ("<p>\n");
      resultblock.append ("<a href=\"index?approve=" + convert_to_string (id) + "\"> ✔ </a>\n");
      resultblock.append ("<a href=\"index?delete=" + convert_to_string (id) + "\"> ✗ </a>\n");
      resultblock.append (bible);
      resultblock.append (" ");
      resultblock.append (link);
      resultblock.append (" ");
      resultblock.append (information);
      resultblock.append ("</p>\n");
    }
  }
  view.set_variable ("resultblock", resultblock);


  page += view.render ("checks", "index");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #22
0
string resource_sword (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  
  if (request->query.count ("refresh")) {
    tasks_logic_queue (REFRESHSWORDMODULES);
    redirect_browser (request, journal_index_url ());
  }

  
  if (request->query.count ("update")) {
    tasks_logic_queue (UPDATESWORDMODULES, {});
    redirect_browser (request, journal_index_url ());
  }
  
  
  /*
   It used to be possible to manually install or uninstall SWORD modules.
   However it was observed that on the open Bibledit demo, 
   there were bursts of installed SWORD modules.
   That made Bibledit unresponsive or just get stuck.
   Likely the web crawlers of the search engines click all links to install all modules.
   The answer to this problem was to remove manual install or uninstall of SWORD modules.
   */
  
  
  string page;
  Assets_Header header = Assets_Header (translate("Resources"), request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();
  Assets_View view;

  
  map <string, string> installed_modules;
  {
    vector <string> modules = sword_logic_get_installed ();
    for (auto module : modules) {
      string name = sword_logic_get_installed_module (module);
      string version = sword_logic_get_version (module);
      installed_modules [name] = version;
    }
  }
  
  vector <string> available_modules = sword_logic_get_available ();
  string moduleblock;
  for (auto & available_module : available_modules) {
    string source = sword_logic_get_source (available_module);
    string module = sword_logic_get_remote_module (available_module);
    moduleblock.append ("<p>");
    moduleblock.append (available_module);
    if (!installed_modules [module].empty ()) {
      moduleblock.append (" (" + translate ("installed") + ") ");
      string version = sword_logic_get_version (available_module);
      if (version != installed_modules[module]) {
        moduleblock.append (" (" + translate ("to be updated") + ")");
      }
    }
    moduleblock.append ("</p>\n");
  }
  view.set_variable ("moduleblock", moduleblock);

  
#ifdef HAVE_CLIENT
  view.enable_zone ("client");
#else
  view.enable_zone ("server");
#endif
  
  
  page += view.render ("resource", "sword");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #23
0
string checks_settings (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  
  string page;
  Assets_Header header = Assets_Header (translate("Manage Checks"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();
  Assets_View view;
  
  
  if (request->query.count ("bible")) {
    string bible = request->query["bible"];
    if (bible == "") {
      Dialog_List dialog_list = Dialog_List ("settings", translate("Select which Bible to manage"), "", "");
      vector <string> bibles = access_bible_bibles (webserver_request);
      for (auto bible : bibles) {
        dialog_list.add_row (bible, "bible", bible);
      }
      page += dialog_list.run();
      return page;
    } else {
      request->database_config_user()->setBible (bible);
    }
  }
  string bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible ());

  
  if (request->query.count ("run")) {
    checks_logic_start (bible);
    view.set_variable ("success", translate("Will run the checks. See the Journal for progress."));
  }
  
  
  string checkbox = request->post ["checkbox"];
  bool checked = convert_to_bool (request->post ["checked"]);
  
                        
  if (checkbox == "doublespacesusfm") {
    Database_Config_Bible::setCheckDoubleSpacesUsfm (bible, checked);
  }
  view.set_variable ("doublespacesusfm", get_checkbox_status (Database_Config_Bible::getCheckDoubleSpacesUsfm (bible)));
   
  
  if (checkbox == "fullstopheadings") {
    Database_Config_Bible::setCheckFullStopInHeadings (bible, checked);
  }
  view.set_variable ("fullstopheadings", get_checkbox_status (Database_Config_Bible::getCheckFullStopInHeadings (bible)));

  
  if (checkbox == "spacebeforepunctuation") {
    Database_Config_Bible::setCheckSpaceBeforePunctuation (bible, checked);
  }
  view.set_variable ("spacebeforepunctuation", get_checkbox_status (Database_Config_Bible::getCheckSpaceBeforePunctuation (bible)));
                      
                      
  if (checkbox == "sentencestructure") {
    Database_Config_Bible::setCheckSentenceStructure (bible, checked);
  }
  view.set_variable ("sentencestructure", get_checkbox_status (Database_Config_Bible::getCheckSentenceStructure (bible)));
                      
                      
  if (checkbox == "paragraphstructure") {
    Database_Config_Bible::setCheckParagraphStructure (bible, checked);
  }
  view.set_variable ("paragraphstructure", get_checkbox_status (Database_Config_Bible::getCheckParagraphStructure (bible)));
                      
                      
  if (checkbox == "booksversification") {
    Database_Config_Bible::setCheckBooksVersification (bible, checked);
  }
  view.set_variable ("booksversification", get_checkbox_status (Database_Config_Bible::getCheckBooksVersification (bible)));
  
  
  if (checkbox == "chaptersversesversification") {
    Database_Config_Bible::setCheckChaptesVersesVersification (bible, checked);
  }
  view.set_variable ("chaptersversesversification", get_checkbox_status (Database_Config_Bible::getCheckChaptesVersesVersification (bible)));
                      
                      
  if (checkbox == "wellformedusfm") {
    Database_Config_Bible::setCheckWellFormedUsfm (bible, checked);
  }
  view.set_variable ("wellformedusfm", get_checkbox_status (Database_Config_Bible::getCheckWellFormedUsfm (bible)));
                      
                      
  if (checkbox == "punctuationatendverse") {
    Database_Config_Bible::setCheckMissingPunctuationEndVerse (bible, checked);
  }
  view.set_variable ("punctuationatendverse", get_checkbox_status (Database_Config_Bible::getCheckMissingPunctuationEndVerse (bible)));
                      
                      
  if (checkbox == "patterns") {
    Database_Config_Bible::setCheckPatterns (bible, checked);
  }
  view.set_variable ("patterns", get_checkbox_status (Database_Config_Bible::getCheckPatterns (bible)));

  
  if (checkbox == "pairs") {
    Database_Config_Bible::setCheckMatchingPairs (bible, checked);
  }
  view.set_variable ("pairs", get_checkbox_status (Database_Config_Bible::getCheckMatchingPairs (bible)));

  
  view.set_variable ("bible", bible);

  
#ifdef HAVE_CLIENT
  view.enable_zone ("client");
#else
  view.enable_zone ("cloud");
#endif

  
  page += view.render ("checks", "settings");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #24
0
string styles_indexm (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Styles"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  header.addBreadCrumb (menu_logic_settings_styles_menu (), menu_logic_styles_text ());
  page = header.run ();
  
  Assets_View view;
  
  Database_Styles database_styles;
  
  string username = request->session_logic ()->currentUser ();
  int userlevel = request->session_logic ()->currentLevel ();
  
  if (request->post.count ("new")) {
    string name = request->post["entry"];
    // Remove spaces at the ends of the name for the new stylesheet.
    // Because predictive keyboards can add a space to the name,
    // and the stylesheet system is not built for whitespace at the start / end of the name of the stylesheet.
    name = filter_string_trim (name);
    vector <string> existing = database_styles.getSheets ();
    if (find (existing.begin(), existing.end (), name) != existing.end ()) {
      page += Assets_Page::error (translate("This stylesheet already exists"));
    } else {
      database_styles.createSheet (name);
      database_styles.grantWriteAccess (username, name);
      styles_sheets_create_all ();
      page += Assets_Page::success (translate("The stylesheet has been created"));
    }
  }
  if (request->query.count ("new")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("indexm", translate("Please enter the name for the new stylesheet"), "", "new", "");
    page += dialog_entry.run();
    return page;
  }
  
  if (request->query.count ("delete")) {
    string del = request->query ["delete"];
    if (del != "") {
      string confirm = request->query ["confirm"];
      if (confirm == "yes") {
        bool write = database_styles.hasWriteAccess (username, del);
        if (userlevel >= Filter_Roles::admin ()) write = true;
        if (write) {
          database_styles.deleteSheet (del);
          database_styles.revokeWriteAccess ("", del);
          page += Assets_Page::success (translate("The stylesheet has been deleted"));
        }
      } if (confirm == "") {
        Dialog_Yes dialog_yes = Dialog_Yes ("indexm", translate("Would you like to delete this stylesheet?"));
        dialog_yes.add_query ("delete", del);
        page += dialog_yes.run ();
        return page;
      }
    }
  
  }
  // Delete empty sheet that may have been there.
  database_styles.deleteSheet ("");

  vector <string> sheets = database_styles.getSheets();
  vector <string> sheetblock;
  for (auto & sheet : sheets) {
    sheetblock.push_back ("<p>");
    sheetblock.push_back (sheet);
    bool editable = database_styles.hasWriteAccess (username, sheet);
    if (userlevel >= Filter_Roles::admin ()) editable = true;
    // Cannot edit the Standard stylesheet.
    if (sheet == styles_logic_standard_sheet ()) editable = false;
    if (editable) {
      sheetblock.push_back ("<a href=\"sheetm?name=" + sheet + "\">[" + translate("edit") + "]</a>");
    }
    sheetblock.push_back ("</p>");
  }
  
  view.set_variable ("sheetblock", filter_string_implode (sheetblock, "\n"));

  page += view.render ("styles", "indexm");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #25
0
string resource_download (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  Database_UsfmResources database_usfmresources;
  
  
  string page;
  Assets_Header header = Assets_Header (translate("Download resource"), request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  header.addBreadCrumb (resource_cache_url (), menu_logic_resources_text ());
  page = header.run ();
  Assets_View view;

  
  string name = request->query["name"];
  view.set_variable ("name", name);
  
  
  
  bool old = request->query.count ("old");
  if (old) view.enable_zone ("old");
  else view.enable_zone ("current");
                        
                      
  if (request->query.count ("clear")) {
    // The client clears the two older storage locations just to be sure they are gone.
    database_usfmresources.deleteResource (name);
    // The client clears the installed resource.
    Database_Cache::remove (name);
  }
  if (request->query.count ("clearold")) {
    // The client clears the two older storage locations just to be sure they are gone.
    database_usfmresources.deleteResource (name);
    redirect_browser (request, resource_cache_url ());
    return "";
  }
  
  
  if (request->query.count ("download")) {
    // Trigger caching the resource.
    // Add the resource to the general configuration to be cached, if it is not already there.
    vector <string> resources = Database_Config_General::getResourcesToCache ();
    if (!in_array (name, resources)) {
      resources.push_back (name);
      Database_Config_General::setResourcesToCache (resources);
    }
    tasks_logic_queue (SYNCRESOURCES);
    redirect_browser (request, journal_index_url ());
    return "";
  }
  
  
  int count = 0;
  if (count == 0) {
    vector <int> books = database_usfmresources.getBooks (name);
    for (auto book : books) {
      vector <int> chapters = database_usfmresources.getChapters (name, book);
      // Rough average of 20 verses per chapter.
      count += (20 * chapters.size());
    }
  }
  if (count == 0) count = Database_Cache::count (name);
  view.set_variable ("count", convert_to_string (count));
                      
                      
  page += view.render ("resource", "download");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #26
0
string sprint_index (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  Database_Sprint database_sprint;

  
  string page;
  Assets_Header header = Assets_Header (translate("Sprint"), request);
  header.addBreadCrumb (menu_logic_tools_menu (), menu_logic_tools_text ());
  page = header.run ();
  Assets_View view;
  
  
  if (request->query.count ("previoussprint")) {
    int month = request->database_config_user()->getSprintMonth ();
    int year = request->database_config_user()->getSprintYear ();
    filter_date_get_previous_month (month, year);
    request->database_config_user()->setSprintMonth (month);
    request->database_config_user()->setSprintYear (year);
  }
  
  
  if (request->query.count ("currentprint")) {
    request->database_config_user()->setSprintMonth (filter_date_numerical_month (filter_date_seconds_since_epoch ()));
    request->database_config_user()->setSprintYear (filter_date_numerical_year (filter_date_seconds_since_epoch ()));
  }
  
  
  if (request->query.count ("nextsprint")) {
    int month = request->database_config_user()->getSprintMonth ();
    int year = request->database_config_user()->getSprintYear ();
    filter_date_get_next_month (month, year);
    request->database_config_user()->setSprintMonth (month);
    request->database_config_user()->setSprintYear (year);
  }
  
  
  string bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible ());
  int month = request->database_config_user()->getSprintMonth ();
  int year = request->database_config_user()->getSprintYear ();
  

  if (request->post.count ("id")) {
    string id = request->post ["id"];
    string checked = request->post ["checked"];
    if (id.length () >= 9) {
      // Remove "task".
      id.erase (0, 4);
      // Convert the fragment to an integer.
      int identifier = convert_to_int (id);
      // Find the fragment "box".
      size_t pos = id.find ("box");
      if (pos != string::npos) {
        // Remove the fragment "box".
        id.erase (0, pos + 3);
        // Convert the box to an integer.
        int box = convert_to_int (id);
        string categorytext = Database_Config_Bible::getSprintTaskCompletionCategories (bible);
        vector <string> categories = filter_string_explode (categorytext, '\n');
        int category_count = categories.size ();
        float category_percentage = 100 / category_count;
        int percentage;
        bool on = (checked == "true");
        if (on) percentage = round ((box + 1) * category_percentage);
        else percentage = round (box * category_percentage);
        database_sprint.updateComplete (identifier, percentage);
      }
    }
    return "";
  }
  
  
  if (request->post.count ("add")) {
    string title = request->post ["add"];
    database_sprint.storeTask (bible, year, month, title);
    view.set_variable ("success", translate("New task added"));
    // Focus the entry for adding tasks only in case a new task was added.
    view.set_variable ("autofocus", "autofocus");
  }
  
  
  if (request->query.count ("mail")) {
    string mail = request->query ["mail"];
    sprint_burndown (bible, true);
    view.set_variable ("success", translate("The information was mailed to the subscribers"));
  }
  
  
  if (request->query.count ("bible")) {
    bible = request->query ["bible"];
    if (bible == "") {
      Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to display the Sprint for"), "", "");
      vector <string> bibles = access_bible_bibles (request);
      for (auto & bible : bibles) {
        dialog_list.add_row (bible, "bible", bible);
      }
      page += dialog_list.run();
      return page;
    } else {
      request->database_config_user()->setBible (bible);
    }
  }
  
  
  bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible ());
  
  
  int id = convert_to_int (request->query ["id"]);
  
  
  if (request->query.count ("remove")) {
    database_sprint.deleteTask (id);
    view.set_variable ("success", translate("The task was removed"));
  }
  
  
  if (request->query.count ("moveback")) {
    filter_date_get_previous_month (month, year);
    database_sprint.updateMonthYear (id, month, year);
    view.set_variable ("success", translate("The task was moved to the previous sprint"));
    request->database_config_user()->setSprintMonth (month);
    request->database_config_user()->setSprintYear (year);
  }
                        
                        
  if (request->query.count ("moveforward")) {
    filter_date_get_next_month (month, year);
    database_sprint.updateMonthYear (id, month, year);
    view.set_variable ("success", translate("The task was moved to the next sprint"));
    request->database_config_user()->setSprintMonth (month);
    request->database_config_user()->setSprintYear (year);
  }

  
  if (request->post.count ("categories")) {
    string categories = request->post ["categories"];
    vector <string> categories2;
    categories = filter_string_trim (categories);
    vector <string> vcategories = filter_string_explode (categories, '\n');
    for (auto category : vcategories) {
      category = filter_string_trim (category);
      if (category != "") categories2.push_back (category);
    }
    categories = filter_string_implode (categories2, "\n");
    Database_Config_Bible::setSprintTaskCompletionCategories (bible, categories);
  }
  
  
  view.set_variable ("bible", bible);
  view.set_variable ("sprint", locale_logic_month (month) + " " + convert_to_string (year));

  
  string categorytext = Database_Config_Bible::getSprintTaskCompletionCategories (bible);
  view.set_variable ("categorytext", categorytext);
  vector <string> vcategories = filter_string_explode (categorytext, '\n');
  string categories;
  for (auto category : vcategories) {
    categories.append ("<td>" + category + "</td>\n");
  }
  view.set_variable ("categories", categories);
  
  
  string tasks;
  vector <int> vtasks = database_sprint.getTasks (bible, year, month);
  for (auto & id : vtasks) {
    string title = filter_string_sanitize_html (database_sprint.getTitle (id));
    int percentage = database_sprint.getComplete (id);
    tasks.append ("<tr id=\"a" + convert_to_string (id) + "\">\n");
    tasks.append ("<td><a href=\"?id=" + convert_to_string (id) + "&remove=\">" + emoji_wastebasket () + "</a></td>\n");
    tasks.append ("<td></td>\n");
    tasks.append ("<td><a href=\"?id=" + convert_to_string (id) + "&moveback=\"> « </a></td>\n");
    tasks.append ("<td>" + title + "</td>\n");
    int category_count = vcategories.size();
    float category_percentage = 100 / category_count;
    for (size_t i2 = 0; i2 < vcategories.size (); i2++) {
      int high = round ((i2 + 1) * category_percentage);
      tasks.append ("<td>\n");
      tasks.append ("<input type=\"checkbox\" id=\"task");
      tasks.append (convert_to_string (id));
      tasks.append ("box");
      tasks.append (convert_to_string (i2));
      tasks.append ("\"");
      if (percentage >= high)
        tasks.append (" checked");
      else
        tasks.append ("");
      tasks.append (">");
      
      tasks.append ("</td>\n");
    }
    tasks.append ("<td><a href=\"?id=" + convert_to_string (id) + "&moveforward=\"> » </a></td>\n");
    tasks.append ("</tr>\n");
  }
  view.set_variable ("tasks", tasks);

  
  view.set_variable ("chart", sprint_create_burndown_chart (bible, year, month));
                                                                                                                                                                                                                  

  page += view.render ("sprint", "index");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #27
0
string resource_cache (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  
  string resource = request->query ["resource"];
  
  
  string page;
  Assets_Header header = Assets_Header (menu_logic_resources_text (), request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  page = header.run ();
  Assets_View view;

  
  if (request->query.count ("clear")) {
    sendreceive_resources_clear_all ();
  }
  vector <string> resources = Database_Config_General::getResourcesToCache ();
  if (!resources.empty ()) {
    view.enable_zone ("scheduled");
    view.set_variable ("scheduled", filter_string_implode (resources, " | "));
  }
  
  
  vector <string> listed_resources;
  string block;
  
  // Display the available USFM resources.
  resources = client_logic_usfm_resources_get ();
  for (auto & resource : resources) {
    block.append ("<p>");
    block.append ("<a href=\"download?name=" + resource + "\">" + resource + "</a>");
    block.append ("</p>\n");
  }
  listed_resources.insert (listed_resources.end (), resources.begin (), resources.end ());
  // Display the available external resources.
  resources = resource_external_names ();
  for (auto & resource : resources) {
    block.append ("<p>");
    block.append ("<a href=\"download?name=" + resource + "\">" + resource + "</a>");
    block.append ("</p>\n");
  }
  listed_resources.insert (listed_resources.end (), resources.begin (), resources.end ());
  // Display the available SWORD resources.
  resources = sword_logic_get_available ();
  for (auto & resource : resources) {
    string source = sword_logic_get_source (resource);
    string module = sword_logic_get_remote_module (resource);
    string name = "[" + source + "][" + module + "]";
    block.append ("<p>");
    block.append ("<a href=\"download?name=" + name + "\">" + resource + "</a>");
    block.append ("</p>\n");
  }
  listed_resources.insert (listed_resources.end (), resources.begin (), resources.end ());
  // Display any old USFM resources still available on the client.
  Database_UsfmResources database_usfmresources;
  resources = database_usfmresources.getResources ();
  for (auto & resource : resources) {
    if (in_array (resource, listed_resources)) continue;
    block.append ("<p>");
    block.append ("<a href=\"download?name=" + resource + "&old=yes\">" + resource + "</a>");
    block.append ("</p>\n");
  }
  // Display any offline resources still available on the client.
  Database_OfflineResources database_offlineresources;
  resources = database_offlineresources.names ();
  for (auto & resource : resources) {
    if (in_array (resource, listed_resources)) continue;
    block.append ("<p>");
    block.append ("<a href=\"download?name=" + resource + "&old=yes\">" + resource + "</a>");
    block.append ("</p>\n");
  }
  // Display the list.
  view.set_variable ("block", block);

  
  page += view.render ("resource", "cache");
  page += Assets_Page::footer ();
  return page;
}
Beispiel #28
0
string search_all (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  
  string page;
  Assets_Header header = Assets_Header (translate("Search"), request);
  header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ());
  page = header.run ();

  
  Assets_View view;
  
  
  // The query: The word or string to search for.
  // Put the query string into the search box.
  string queryString;
  if (request->query.count ("q")) {
    queryString = request->query ["q"];
  }
  
  
  view.set_variable ("query", queryString);

  
  // Clean the query string up.
  queryString = filter_string_trim (queryString);
  
  
  // Generate search words for emphasizing the search passages.
  vector <string> queryWords = filter_string_explode (queryString, ' ');
  
  
  Database_Notes database_notes = Database_Notes (request);

  
  string siteUrl = config_logic_site_url ();

  
  vector <string> bibles = access_bible_bibles (request);


  // Search the notes.
  vector <int> identifiers = database_notes.searchNotes (queryString, bibles);
  
  
  int noteCount = identifiers.size();
  view.set_variable ("noteCount", convert_to_string (noteCount));
  
  
  // Assemble the block of search results for the consultation notes.
  string notesblock;
  for (auto identifier : identifiers) {
    
    // The title.
    string summary = database_notes.getSummary (identifier);
    string verses = filter_passage_display_inline (database_notes.getPassages (identifier));
    string title = summary + " | " + verses;
    title = filter_string_sanitize_html (title);
    
    // The url.
    string url = siteUrl + notes_note_url () + "?id=" + convert_to_string (identifier);
    
    // The excerpt.
    string stext = database_notes.getSearchField (identifier);
    vector <string> vtext = filter_string_explode (stext, '\n');
    string excerpt;
    // Go through each line of text separately.
    for (auto & line : vtext) {
      string markedLine = filter_string_markup_words (queryWords, line);
      // If the line is marked up, add it to the excerpts.
      if (!excerpt.empty()) excerpt.append ("\n");
      if (markedLine != line) {
        excerpt.append ("<p style=\"margin-top: 0em\">" + markedLine + "</p>");
      }
    }
    
    // The html to display.
    string html = "<p style=\"margin-top: 0.75em; margin-bottom: 0em\"><a href=\"";
    html.append (url);
    html.append ("\">");
    html.append (title);
    html.append ("</a></p>");
    html.append (excerpt);
    if (!notesblock.empty ()) notesblock.append ("\n");
    notesblock.append (html);
  }
 
  
  // Display the search results for the notes.
  view.set_variable ("notesblock", notesblock);
  
  
  // Search the Bible text.
  vector <Passage> passages = search_logic_search_text (queryString, bibles);
  
  
  int textCount = passages.size ();
  view.set_variable ("textCount", convert_to_string (textCount));
  
  
  // Assemble the search results for the Bible text.
  string textblock;
  for (auto & passage : passages) {
    string bible = passage.bible;
    int book = passage.book;
    int chapter = passage.chapter;
    string verse = passage.verse;
    // The title plus link.
    string link = bible + " | " + filter_passage_link_for_opening_editor_at (book, chapter, verse);
    // The excerpt.
    string stext = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse));
    vector <string> vtext = filter_string_explode (stext, '\n');
    string excerpt;
    // Go through each line of text separately.
    for (auto & line : vtext) {
      string markedLine = filter_string_markup_words (queryWords, line);
      if (markedLine != line) {
        // Store this bit of the excerpt.
        excerpt.append ("<p style=\"margin-top: 0em\">" + markedLine + "</p>\n");
      }
    }
    
    if (!textblock.empty ()) textblock.append ("\n");
    textblock.append ("<p style=\"margin-top: 0.75em; margin-bottom: 0em\">");
    textblock.append (link);
    textblock.append ("</p>");
    textblock.append (excerpt);
  }
  
  
  // Display the search results for the Bible text.
  view.set_variable ("textblock", textblock);
  
  
  page += view.render ("search", "all");
  
  
  page += Assets_Page::footer ();
  
  
  return page;
}
Beispiel #29
0
string styles_view (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  string page;
  
  Assets_Header header = Assets_Header (translate("Style"), webserver_request);
  header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ());
  header.addBreadCrumb (styles_indexm_url (), menu_logic_styles_indexm_text ());
  page = header.run ();
  
  Assets_View view;


  Database_Styles database_styles;
  
  
  string sheet = request->query ["sheet"];
  view.set_variable ("sheet", filter_string_sanitize_html (sheet));
  
  
  string style = request->query ["style"];
  view.set_variable ("style", filter_string_sanitize_html (style));

  
  Database_Styles_Item marker_data = database_styles.getMarkerData (sheet, style);
  
  
  // Whether the logged-in user has write access to the stylesheet.
  string username = request->session_logic ()->currentUser ();
  int userlevel = request->session_logic ()->currentLevel ();
  bool write = database_styles.hasWriteAccess (username, sheet);
  if (userlevel >= Filter_Roles::admin ()) write = true;
  

  // The style's name.
  string name = marker_data.name;
  if (request->query.count ("name")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter the name for the style"), name, "name", "");
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count ("name")) {
    name = request->post["entry"];
    if (write) database_styles.updateName (sheet, style, name);
  }
  view.set_variable ("name", filter_string_sanitize_html (name));
  

  // The style's info.
  string info = marker_data.info;
  if (request->query.count ("info")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter the description for the style"), info, "info", "");
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count("info")) {
    info = request->post["entry"];
    if (write) database_styles.updateInfo (sheet, style, info);
  }
  view.set_variable ("info", filter_string_sanitize_html (info));
  
  
  // The style's category.
  string category = marker_data.category;
  if (request->query.count("category")) {
    category = request->query["category"];
    if (category == "") {
      Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change the category of this style?"),translate("Here are the various categories:"), translate("Please pick one."));
      dialog_list.add_query ("sheet", sheet);
      dialog_list.add_query ("style", style);
      dialog_list.add_row (styles_logic_category_text ("id"),  "category", "id");
      dialog_list.add_row (styles_logic_category_text ("ith"), "category", "ith");
      dialog_list.add_row (styles_logic_category_text ("ipp"), "category", "ipp");
      dialog_list.add_row (styles_logic_category_text ("ioe"), "category", "ioe");
      dialog_list.add_row (styles_logic_category_text ("t"),   "category", "t");
      dialog_list.add_row (styles_logic_category_text ("h"),   "category", "h");
      dialog_list.add_row (styles_logic_category_text ("cv"),  "category", "cv");
      dialog_list.add_row (styles_logic_category_text ("p"),   "category", "p");
      dialog_list.add_row (styles_logic_category_text ("l"),   "category", "l");
      dialog_list.add_row (styles_logic_category_text ("pe"),  "category", "pe");
      dialog_list.add_row (styles_logic_category_text ("te"),  "category", "te");
      dialog_list.add_row (styles_logic_category_text ("f"),   "category", "f");
      dialog_list.add_row (styles_logic_category_text ("x"),   "category", "x");
      dialog_list.add_row (styles_logic_category_text ("xsn"), "category", "xsn");
      dialog_list.add_row (styles_logic_category_text ("st"),  "category", "st");
      dialog_list.add_row (styles_logic_category_text ("cs"),  "category", "cs");
      dialog_list.add_row (styles_logic_category_text ("sb"),  "category", "sb");
      dialog_list.add_row (styles_logic_category_text ("sf"),  "category", "sf");
      dialog_list.add_row (styles_logic_category_text ("pm"),  "category", "pm");
      dialog_list.add_row (styles_logic_category_text (""),    "category", "");
      page += dialog_list.run ();
      return page;
    } else {
      if (write) database_styles.updateCategory (sheet, style, category);
    }
  }
  view.set_variable ("category", styles_logic_category_text(category));

  
  // The style's type.
  int type = marker_data.type;
  if (request->query.count ("type")) {
    string s = request->query["type"];
    type = convert_to_int (s);
    if (s == "") {
      Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change the type of this style?"), translate("Here are the various types:"), translate("Please pick one."));
      dialog_list.add_query ("sheet", sheet);
      dialog_list.add_query ("style", style);
      for (int i = 0; i < 99; i++) {
        string text = styles_logic_type_text (i);
        if (text.length () > 2) {
          dialog_list.add_row (text, "type", convert_to_string (i));
        }
      }
      page += dialog_list.run ();
      return page;
    } else {
      if (write) database_styles.updateType (sheet, style, type);
    }
  }
  view.set_variable ("type", convert_to_string (type));
  view.set_variable ("type_text", styles_logic_type_text (type));
  

  // The style's subtype.
  int subtype = marker_data.subtype;
  if (request->query.count ("subtype")) {
    string s = request->query["subtype"];
    subtype = convert_to_int (s);
    if (s == "") {
      Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change the sub type of this style?"), "", "");
      dialog_list.add_query ("sheet", sheet);
      dialog_list.add_query ("style", style);
      Database_Styles_Item marker_data = database_styles.getMarkerData (sheet, style);
      int type = marker_data.type;
      for (int i = 0; i < 99; i++) {
        string text = styles_logic_subtype_text (type, i);
        if (text.length () > 2) {
          dialog_list.add_row (text, "subtype", convert_to_string (i));
        }
      }
      page += dialog_list.run ();
      return page;
    } else {
      if (write) database_styles.updateSubType (sheet, style, subtype);
    }
  }
  view.set_variable ("subtype",convert_to_string (subtype));
  string subtype_text = styles_logic_subtype_text (type, subtype);
  view.set_variable ("subtype_text", subtype_text);
  if (subtype_text.length () > 2) view.enable_zone ("subtype_text");
  
  
  // The fontsize.
  if (styles_logic_fontsize_is_relevant (type, subtype)) view.enable_zone ("fontsize_relevant");
  float fontsize = marker_data.fontsize;
  if (request->query.count ("fontsize")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter a fontsize between 5 and 60 points"), convert_to_string (fontsize), "fontsize", translate ("The value to enter is just a number, e.g. 12."));
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count("fontsize")) {
    float fs = convert_to_float (request->post["entry"]);
    if ((fs >= 5) && (fs <= 60)) {
      fontsize = fs;
      if (write) database_styles.updateFontsize (sheet, style, fontsize);
    }
  }
  view.set_variable ("fontsize", convert_to_string (fontsize));


  // Italics, bold, underline, small caps relevance.
  if (styles_logic_italic_bold_underline_smallcaps_are_relevant (type, subtype)) view.enable_zone ("ibus_relevant");

  
  // Italic.
  int italic = marker_data.italic;
  if (request->query.count ("italic")) {
    string s = request->query["italic"];
    if (s == "") {
      Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change whether this style is in italics?"), "", "");
      dialog_list.add_query ("sheet", sheet);
      dialog_list.add_query ("style", style);
      Database_Styles_Item marker_data = database_styles.getMarkerData (sheet, style);
      int last_value = ooitOn;
      if (styles_logic_italic_bold_underline_smallcaps_are_full (marker_data.type, marker_data.subtype))
        last_value = ooitToggle;
      for (int i = 0; i <= last_value; i++) {
        dialog_list.add_row (styles_logic_off_on_inherit_toggle_text (i), "italic", convert_to_string (i));
      }
      page += dialog_list.run ();
      return page;
    } else {
      italic = convert_to_int (s);
      if (write) database_styles.updateItalic (sheet, style, italic);
    }
  }
  view.set_variable ("italic", styles_logic_off_on_inherit_toggle_text (italic));
  

  // Bold.
  int bold = marker_data.bold;
  if (request->query.count ("bold")) {
    string s = request->query["bold"];
    if (s == "") {
      Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change whether this style is in bold?"), "", "");
      dialog_list.add_query ("sheet", sheet);
      dialog_list.add_query ("style", style);
      Database_Styles_Item marker_data = database_styles.getMarkerData (sheet, style);
      int last_value = ooitOn;
      if (styles_logic_italic_bold_underline_smallcaps_are_full (marker_data.type, marker_data.subtype))
        last_value = ooitToggle;
      for (int i = 0; i <= last_value; i++) {
        dialog_list.add_row (styles_logic_off_on_inherit_toggle_text (i), "bold", convert_to_string (i));
      }
      page += dialog_list.run ();
      return page;
    } else {
      bold = convert_to_int (s);
      if (write) database_styles.updateBold (sheet, style, bold);
    }
  }
  view.set_variable ("bold", styles_logic_off_on_inherit_toggle_text (bold));
  

  // Underline.
  int underline = marker_data.underline;
  if (request->query.count ("underline")) {
    string s = request->query["underline"];
    if (s == "") {
      Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change whether this style is underlined?"), "", "");
      dialog_list.add_query ("sheet", sheet);
      dialog_list.add_query ("style", style);
      Database_Styles_Item marker_data = database_styles.getMarkerData (sheet, style);
      int last_value = ooitOn;
      if (styles_logic_italic_bold_underline_smallcaps_are_full (type, subtype))
        last_value = ooitToggle;
      for (int i = 0; i <= last_value; i++) {
        dialog_list.add_row (styles_logic_off_on_inherit_toggle_text (i), "underline", convert_to_string (i));
      }
      page += dialog_list.run ();
      return page;
    } else {
      underline = convert_to_int (s);
      if (write) database_styles.updateUnderline (sheet, style, underline);
    }
  }
  view.set_variable ("underline", styles_logic_off_on_inherit_toggle_text (underline));

  
  // Small caps.
  int smallcaps = marker_data.smallcaps;
  if (request->query.count ("smallcaps")) {
    string s = request->query["smallcaps"];
    if (s == "") {
      Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change whether this style is in small caps?"), "", "");
      dialog_list.add_query ("sheet", sheet);
      dialog_list.add_query ("style", style);
      Database_Styles_Item marker_data = database_styles.getMarkerData (sheet, style);
      int last_value = ooitOn;
      if (styles_logic_italic_bold_underline_smallcaps_are_full (marker_data.type, marker_data.subtype))
        last_value = ooitToggle;
      for (int i = 0; i <= last_value; i++) {
        dialog_list.add_row (styles_logic_off_on_inherit_toggle_text (i), "smallcaps", convert_to_string (i));
      }
      page += dialog_list.run ();
      return page;
    } else {
      smallcaps = convert_to_int (s);
      if (write) database_styles.updateSmallcaps (sheet, style, smallcaps);
    }
  }
  view.set_variable ("smallcaps", styles_logic_off_on_inherit_toggle_text (smallcaps));
  
  
  // Superscript.
  if (styles_logic_superscript_is_relevant (type, subtype)) view.enable_zone ("superscript_relevant");
  int superscript = marker_data.superscript;
  if (request->query.count ("superscript")) {
    superscript = convert_to_int (request->query["superscript"]);
    if (write) database_styles.updateSuperscript (sheet, style, superscript);
  }
  view.set_variable ("superscript_value", styles_logic_off_on_inherit_toggle_text (superscript));
  view.set_variable ("superscript_toggle", convert_to_string (!(bool) superscript));
  

  // Whether a list of the following paragraph treats are relevant.
  if (styles_logic_paragraph_treats_are_relevant (type, subtype)) view.enable_zone ("paragraph_treats_relevant");

  
  // Text alignment.
  int justification = marker_data.justification;
  if (request->query.count ("alignment")) {
    Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change the text alignment of this style?"), "", "");
    dialog_list.add_query ("sheet", sheet);
    dialog_list.add_query ("style", style);
    for (int i = AlignmentLeft; i <= AlignmentJustify; i++) {
      dialog_list.add_row (styles_logic_alignment_text (i), "justification", convert_to_string (i));
    }
    page += dialog_list.run ();
    return page;
  }
  if (request->query.count ("justification")) {
    justification = convert_to_int (request->query["justification"]);
    if (write) database_styles.updateJustification (sheet, style, justification);
  }
  view.set_variable ("justification", styles_logic_alignment_text (justification));
  

  // Space before paragraph.
  float spacebefore = marker_data.spacebefore;
  if (request->query.count ("spacebefore")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter a space of between 0 and 100 mm before the paragraph"), convert_to_string (spacebefore), "spacebefore", translate ("This is the space before, or in other words, above the paragraph. The value to enter is just a number, e.g. 0."));
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count ("spacebefore")) {
    spacebefore = convert_to_float (request->post["entry"]);
    if (spacebefore < 0) spacebefore = 0;
    if (spacebefore > 100) spacebefore = 100;
    if (write) database_styles.updateSpaceBefore (sheet, style, spacebefore);
  }
  view.set_variable ("spacebefore", convert_to_string (spacebefore));
  

  // Space after paragraph.
  float spaceafter = marker_data.spaceafter;
  if (request->query.count ("spaceafter")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter a space of between 0 and 100 mm after the paragraph"), convert_to_string (spaceafter), "spaceafter", translate ("This is the space after, or in other words, below the paragraph. The value to enter is just a number, e.g. 0."));
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count("spaceafter")) {
    spaceafter = convert_to_float (request->post["entry"]);
    if (spaceafter < 0) spaceafter = 0;
    if (spaceafter > 100) spaceafter = 100;
    if (write) database_styles.updateSpaceAfter (sheet, style, spaceafter);
  }
  view.set_variable ("spaceafter", convert_to_string (spaceafter));
  

  // Left margin.
  float leftmargin = marker_data.leftmargin;
  if (request->query.count ("leftmargin")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter a left margin of between -100 and 100 mm"), convert_to_string (leftmargin), "leftmargin", translate ("This is the left margin of the paragraph. The value to enter is just a number, e.g. 0."));
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count("leftmargin")) {
    leftmargin = convert_to_float (request->post ["entry"]);
    if (leftmargin < 0) leftmargin = 0;
    if (leftmargin > 100) leftmargin = 100;
    if (write) database_styles.updateLeftMargin (sheet, style, leftmargin);
  }
  view.set_variable ("leftmargin", convert_to_string (leftmargin));

  
  // Right margin.
  float rightmargin = marker_data.rightmargin;
  if (request->query.count ("rightmargin")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter a right margin of between -100 and 100 mm"), convert_to_string (rightmargin), "rightmargin", translate ("This is the right margin of the paragraph. The value to enter is just a number, e.g. 0."));
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count("rightmargin")) {
    rightmargin = convert_to_float (request->post["entry"]);
    if (rightmargin < -100) rightmargin = -100;
    if (rightmargin > 100) rightmargin = 100;
    if (write) database_styles.updateRightMargin (sheet, style, rightmargin);
  }
  view.set_variable ("rightmargin", convert_to_string (rightmargin));
  
  
  // First line indent.
  float firstlineindent = marker_data.firstlineindent;
  if (request->query.count ("firstlineindent")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter a first line indent of between -100 and 100 mm"), convert_to_string (firstlineindent), "firstlineindent", translate ("This is the indent of the first line of the the paragraph. The value to enter is just a number, e.g. 0."));
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count ("firstlineindent")) {
    firstlineindent = convert_to_float (request->post["entry"]);
    if (firstlineindent < -100) firstlineindent = -100;
    if (firstlineindent > 100) firstlineindent = 100;
    if (write) database_styles.updateFirstLineIndent (sheet, style, firstlineindent);
  }
  view.set_variable ("firstlineindent", convert_to_string (firstlineindent));

  
  // Columns spanning.
  if (styles_logic_columns_are_relevant (type, subtype)) view.enable_zone ("columns_relevant");
  bool spancolumns = marker_data.spancolumns;
  if (request->query.count ("spancolumns")) {
    spancolumns = convert_to_bool (request->query["spancolumns"]);
    if (write) database_styles.updateSpanColumns (sheet, style, spancolumns);
  }
  view.set_variable ("spancolumns", styles_logic_off_on_inherit_toggle_text (spancolumns));
  view.set_variable ("spancolumns_toggle", convert_to_string (!spancolumns));

  
  // Color.
  if (styles_logic_color_is_relevant (type, subtype)) view.enable_zone ("color_relevant");
  
  string color = marker_data.color;
  if (request->query.count ("textcolor")) {
    color = request->query["color"];
    if (color == "") {
      Dialog_Color dialog_color = Dialog_Color ("view", translate("Please specify a new color"));
      dialog_color.add_query ("textcolor", "true");
      dialog_color.add_query ("sheet", sheet);
      dialog_color.add_query ("style", style);
      page += dialog_color.run ();
      return page;
    } else {
      if (color.find ("#") == string::npos) color.insert (0, "#");
      if (color.length () != 7) color = "#000000";
      if (write) database_styles.updateColor (sheet, style, color);
    }
  }
  view.set_variable ("color", color);

  string backgroundcolor = marker_data.backgroundcolor;
  if (request->query.count ("backgroundcolor")) {
    backgroundcolor = request->query["color"];
    if (backgroundcolor == "") {
      Dialog_Color dialog_color = Dialog_Color ("view", translate("Please specify a new color"));
      dialog_color.add_query ("backgroundcolor", "true");
      dialog_color.add_query ("sheet", sheet);
      dialog_color.add_query ("style", style);
      page += dialog_color.run ();
      return page;
    } else {
      if (backgroundcolor.find ("#") == string::npos) backgroundcolor.insert (0, "#");
      if (backgroundcolor.length () != 7) backgroundcolor = "#FFFFFF";
      if (write) {
        database_styles.updateBackgroundColor (sheet, style, backgroundcolor);
      }
    }
  }
  view.set_variable ("backgroundcolor", backgroundcolor);


  // Whether to print this style.
  if (styles_logic_print_is_relevant (type, subtype)) view.enable_zone ("print_relevant");
  bool print = marker_data.print;
  if (request->query.count ("print")) {
    print = convert_to_bool (request->query["print"]);
    if (write) database_styles.updatePrint (sheet, style, print);
  }
  view.set_variable ("print", styles_logic_off_on_inherit_toggle_text (print));
  view.set_variable ("print_toggle", convert_to_string (!print));
  

  // Userbool1
  string userbool1_function = styles_logic_get_userbool1_text (styles_logic_get_userbool1_function (type, subtype));
  if (userbool1_function.length () > 2) view.enable_zone ("userbool1_relevant");
  view.set_variable ("userbool1_function", userbool1_function);
  bool userbool1 = marker_data.userbool1;
  if (request->query.count ("userbool1")) {
    userbool1 = convert_to_bool (request->query["userbool1"]);
    if (write) database_styles.updateUserbool1 (sheet, style, userbool1);
  }
  view.set_variable ("userbool1_value", styles_logic_off_on_inherit_toggle_text (userbool1));
  view.set_variable ("userbool1_toggle", convert_to_string (!userbool1));

  
  // Userbool2
  string userbool2_function = styles_logic_get_userbool2_text (styles_logic_get_userbool2_function (type, subtype));
  if (userbool2_function.length () > 2) view.enable_zone ("userbool2_relevant");
  view.set_variable ("userbool2_function", userbool2_function);
  bool userbool2 = marker_data.userbool2;
  if (request->query.count ("userbool2")) {
    userbool2 = convert_to_bool (request->query["userbool2"]);
    if (write) database_styles.updateUserbool2 (sheet, style, userbool2);
  }
  view.set_variable ("userbool2_value", styles_logic_off_on_inherit_toggle_text (userbool2));
  view.set_variable ("userbool2_toggle", convert_to_string (!userbool2));

  
  // Userbool3
  string userbool3_function = styles_logic_get_userbool3_text (styles_logic_get_userbool3_function (type, subtype));
  if (userbool3_function.length () > 2) view.enable_zone ("userbool3_relevant");
  view.set_variable ("userbool3_function", userbool3_function);
  bool userbool3 = marker_data.userbool3;
  if (request->query.count ("userbool3")) {
    userbool3 = convert_to_bool (request->query["userbool3"]);
    if (write) database_styles.updateUserbool3 (sheet, style, userbool3);
  }
  view.set_variable ("userbool3_value", styles_logic_off_on_inherit_toggle_text (userbool3));
  view.set_variable ("userbool3_toggle", convert_to_string (!userbool3));

  
  // Userint1.
  int userint1 = marker_data.userint1;
  switch (styles_logic_get_userint1_function (type, subtype)) {
    case UserInt1None :
      break;
    case UserInt1NoteNumbering :
      view.enable_zone ("userint1_notenumbering");
      if (request->query.count ("notenumbering")) {
        Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change the numbering of the note?"), "", "");
        dialog_list.add_query ("sheet", sheet);
        dialog_list.add_query ("style", style);
        for (int i = NoteNumbering123; i <= NoteNumberingUser; i++) {
          dialog_list.add_row (styles_logic_note_numbering_text (i), "userint1", convert_to_string (i));
        }
        page += dialog_list.run ();
        return page;
      }
      if (request->query.count ("userint1")) {
        userint1 = convert_to_int (request->query["userint1"]);
        if (write) database_styles.updateUserint1 (sheet, style, userint1);
      }
      view.set_variable ("userint1", styles_logic_note_numbering_text (userint1));
      break;
    case UserInt1TableColumnNumber :
      view.enable_zone ("userint1_columnnumber");
      if (request->query.count ("userint1")) {
        Dialog_Entry dialog_entry = Dialog_Entry ("view", translate("Please enter a column number between 1 and 4"), convert_to_string (userint1), "userint1", translate ("This is the column number for the style. The first columm is number 1."));
        dialog_entry.add_query ("sheet", sheet);
        dialog_entry.add_query ("style", style);
        page += dialog_entry.run ();
        return page;
      }
      if (request->post.count ("userint1")) {
        int value = convert_to_int (request->post["entry"]);
        if ((value >= 1) && (value <= 4)) {
          userint1 = value;
          if (write) database_styles.updateUserint1 (sheet, style, userint1);
        }
      }
      view.set_variable ("userint1", convert_to_string (userint1));
      break;
  }
  
  
  // Userint2.
  int userint2 = marker_data.userint2;
  switch (styles_logic_get_userint2_function (type, subtype)) {
    case UserInt2None :
      break;
    case UserInt2NoteNumberingRestart :
      view.enable_zone ("userint2_notenumberingrestart");
      if (request->query.count ("notenumberingrestart")) {
        Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change when the note numbering restarts?"), "", "");
        dialog_list.add_query ("sheet", sheet);
        dialog_list.add_query ("style", style);
        for (int i = NoteRestartNumberingNever; i <= NoteRestartNumberingEveryChapter; i++) {
          dialog_list.add_row (styles_logic_note_restart_numbering_text (i), "userint2", convert_to_string (i));
        }
        page += dialog_list.run ();
        return page;
      }
      if (request->query.count ("userint2")) {
        userint2 = convert_to_int (request->query["userint2"]);
        if (write) database_styles.updateUserint2 (sheet, style, userint2);
      }
      view.set_variable ("userint2", styles_logic_note_restart_numbering_text (userint2));
      break;
    case UserInt2EndnotePosition :
      view.enable_zone ("userint2_endnoteposition");
      if (request->query.count ("endnoteposition")) {
        Dialog_List dialog_list = Dialog_List ("view", translate("Would you like to change the position where to dump the endnotes?"), "", "");
        dialog_list.add_query ("sheet", sheet);
        dialog_list.add_query ("style", style);
        for (int i = EndNotePositionAfterBook; i <= EndNotePositionAtMarker; i++) {
          dialog_list.add_row (styles_logic_end_note_position_text (i), "userint2", convert_to_string(i));
        }
        page += dialog_list.run ();
        return page;
      }
      if (request->query.count ("userint2")) {
        userint2 = convert_to_int (request->query["userint2"]);
        if (write) database_styles.updateUserint2 (sheet, style, userint2);
      }
      view.set_variable ("userint2", styles_logic_end_note_position_text (userint2));
      break;
  }

  
  // Userint3 not yet used.
  

  // Userstring1.
  string userstring1 = marker_data.userstring1;
  string userstring1_question;
  string userstring1_help;
  switch (styles_logic_get_userstring1_function (type, subtype)) {
    case UserString1None :
      break;
    case UserString1NoteNumberingSequence :
      if (userint1 == NoteNumberingUser) {
        view.enable_zone ("userstring1_numberingsequence");
        userstring1_question = translate("Please enter a new note numbering sequence");
        userstring1_help = translate("This gives a sequence for numbering the notes. When for example § † * is entered, the numbering goes like §, †, *, §, †, *, and so forth. Any sequence of characters can be used. Spaces should separate the characters");
      }
      break;
    case UserString1WordListEntryAddition :
      view.enable_zone ("userstring1_wordlistaddition");
      userstring1_question = translate("Please enter a new addition to the word list entry");
      userstring1_help = translate("This given an optional string to be added after each definition in the body of text. In some Bibles the unusual words are marked with an asterisk and then explained in a glossary. If you would enter the asterisk here, or indeed any string, Bibledit would include this in the exported documents.");
      break;
  }
  if (request->query.count ("userstring1")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", userstring1_question, userstring1, "userstring1", userstring1_help);
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count ("userstring1")) {
    userstring1 = request->post["entry"];
    if (write) database_styles.updateUserstring1 (sheet, style, userstring1);
  }
  if (userstring1 == "") userstring1 = "--";
  view.set_variable ("userstring1", filter_string_sanitize_html (userstring1));
  

  // Userstring2
  string userstring2 = marker_data.userstring2;
  string userstring2_question;
  string userstring2_info;
  switch (styles_logic_get_userstring2_function (type, subtype)) {
    case UserString2None :
      break;
    case UserString2DumpEndnotesHere :
      if (userint2 == EndNotePositionAtMarker) {
        view.enable_zone ("userstring2_dumpendnotes");
        userstring2_question = translate("Please enter a marker at which the endnotes should be dumped");
        userstring2_info = translate("The marker is to be given without the backslash, e.g. \"zendnotes\".");
      }
      break;
  }
  if (request->query.count ("userstring2")) {
    Dialog_Entry dialog_entry = Dialog_Entry ("view", userstring2_question, userstring2, "userstring2", userstring2_info);
    dialog_entry.add_query ("sheet", sheet);
    dialog_entry.add_query ("style", style);
    page += dialog_entry.run ();
    return page;
  }
  if (request->post.count("userstring2")) {
    userstring2 = request->post["entry"];
    if (write) database_styles.updateUserstring2 (sheet, style, userstring2);
  }
  if (userstring2 == "") userstring2 = "--";
  view.set_variable ("userstring2", filter_string_sanitize_html (userstring2));
  
  // Recreate stylesheets after editing a style.
  if ((request->query.size () != 2) || (request->post.size () != 0)) {
    styles_sheets_create_all ();
  }

  
  // Userstring3 not yet used.
  
  
  page += view.render ("styles", "view");
  
  page += Assets_Page::footer ();
  
  return page;
}
Beispiel #30
0
string journal_index (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  int userLevel = request->session_logic()->currentLevel ();

  string filename = request->query ["filename"];
  if (!filename.empty ()) {
    return journal_index_ajax (request, filename);
  }

  Database_Logs database_logs = Database_Logs ();

  
  Assets_Header header = Assets_Header (translate ("Journal"), webserver_request);
  header.addBreadCrumb (menu_logic_tools_menu (), menu_logic_tools_text ());
  string page = header.run ();


  Assets_View view;


  if (request->query.count ("clear")) {
    database_logs.clear ();
    // If the logbook has been cleared on a mobile device, and the screen shuts off,
    // and then the user activates the screen on the mobile device,
    // the logbook will then again be cleared, because that was the last opened URL.
    // Redirecting the browser to a clean URL fixes this behaviour.
    redirect_browser (request, journal_index_url ());
    return "";
  }

  
  string lastfilename;
  vector <string> entries = database_logs.get (lastfilename);


  string lines;
  for (auto entry : entries) {
    int entryLevel = convert_to_int (entry);
    // Cloud: Pay attention to only rendering journal entries of sufficient user level.
    // Client: Render any journal entry.
    if (!client_logic_client_enabled ()) {
      if (entryLevel > userLevel) continue;
    }
    entry = render_journal_entry (entry);
    lines.append ("<p>");
    lines.append (entry);
    lines.append ("</p>\n");
  }
  view.set_variable ("lines", lines);

  
  // Pass the filename of the most recent entry to javascript
  // for use by the AJAX calls for getting subsequent journal entries.
  // It should be passed as a String object in JavaScript.
  // Because when it were passed as an Int, JavaScript would round the value off.
  // And rounding it off often led to double journal entries.
  string script = "var filename = \"" + lastfilename + "\";";
  view.set_variable ("script", script);


  page += view.render ("journal", "index");

  page += Assets_Page::footer ();

  return page;
}