void WindowCheckKeyterms::load_renderings()
{
  extern Settings *settings;
  ustring project = settings->genconfig.project_get();
  ProjectConfiguration *projectconfig = settings->projectconfig(project);
  ustring versification = projectconfig->versification_get();
  ustring keyterm;
  keyterms_get_term(keyword_id, keyterm);
  vector <ustring> renderings;
  vector <bool> wholewords;
  vector <bool> casesensitives;
  ustring category;
  {
    ustring dummy1;
    vector < Reference > dummy2;
    keyterms_get_data(keyword_id, category, dummy1, dummy2);
  }
  keyterms_retrieve_renderings(project, keyterm, category, renderings, wholewords, casesensitives);
  clear_renderings();
  GtkTreeIter iter;
  for (unsigned int i = 0; i < renderings.size(); i++) {
    gtk_tree_store_append(treestore_renderings, &iter, NULL);
    bool wholeword = wholewords[i];
    bool casesensitive = casesensitives[i];
    gtk_tree_store_set(treestore_renderings, &iter, 0, wholeword, 1, casesensitive, 2, renderings[i].c_str(), 3, 1, -1);
  }
  gtk_tree_store_append(treestore_renderings, &iter, NULL);
  gtk_tree_store_set(treestore_renderings, &iter, 0, false, 1, true, 2, enter_new_rendering_here().c_str(), 3, 1, -1);
}
void notes_get_references_from_editor(GtkTextBuffer * textbuffer, vector < Reference > &references, vector < ustring > &messages)
/*
 Gets all references from the notes editor.
 Normalizes them.
 Produces messages on trouble.
 Handles notes that span more than one chapter.
 */
{
    // Get all lines from the textbuffer.
    vector < ustring > lines;
    textbuffer_get_lines(textbuffer, lines);
    // When discovering a reference from a user's entry, use previous values,
    // so that it becomes quicker for a user to enter new references.
    // If Leviticus 10:11 is already there, and the user wishes to add verse
    // 12 also, he just enters 12 on a line, and that' it.
    Reference previousreference;
    for (unsigned int i = 0; i < lines.size(); i++) {
        if (!lines[i].empty()) {
            // Normalize reference.
            Reference reference;
            if (reference_discover(previousreference, lines[i], reference)) {
                ustring ch1, vs1, ch2, vs2;
                if (chapter_span_discover(lines[i], ch1, vs1, ch2, vs2)) {
                    // We cross the chapter boundaries.
                    // Store as two or more references,
                    // the first one going up to the end of the chapter,
                    // and the second one starting at the next chapter verse 1,
                    // and any chapter in-between.
                    extern Settings *settings;
                    ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get());
                    Reference ref(reference.book_get(), convert_to_int(ch1), vs1);
                    ustring lastverse = versification_get_last_verse(projectconfig->versification_get(), reference.book_get(), convert_to_int(ch1));
                    ref.verse_append("-" + lastverse);
                    references.push_back(ref);
                    for (unsigned int ch = convert_to_int(ch1) + 1; ch < convert_to_int(ch2); ch++) {
                        Reference ref(reference.book_get(), ch, "1");
                        ustring lastverse = versification_get_last_verse(projectconfig->versification_get(), reference.book_get(), ch);
                        ref.verse_append("-" + lastverse);
                        references.push_back(ref);
                    }
                    ref.chapter_set(convert_to_int(ch2));
                    ref.verse_set("1-" + vs2);
                    references.push_back(ref);
                    // Store values to discover next reference.
                    previousreference.book_set(reference.book_get());
                    previousreference.chapter_set(convert_to_int(ch2));
                    previousreference.verse_set(vs2);
                } else {
                    // We've a normal reference.
                    // Store reference.
                    references.push_back(reference);
                    // Store values to discover next reference.
                    previousreference.assign(reference);
                }
            } else {
                messages.push_back(_("Reference ") + lines[i] + _(" is not valid and has been removed."));
            }
        }
    }
}
Exemple #3
0
XeTeXDialog::XeTeXDialog(int dummy)
{
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get());

  gtkbuilder = gtk_builder_new ();
  gtk_builder_add_from_file (gtkbuilder, gw_build_filename (Directories->get_package_data(), "gtkbuilder.xetexdialog.xml").c_str(), NULL);

  dialog = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "dialog"));

  label_portion = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "label_portion"));

  button_portion = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "button_portion"));
  g_signal_connect((gpointer) button_portion, "clicked", G_CALLBACK(on_button_portion_clicked), gpointer(this));

  expander = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "expander"));
  gtk_expander_set_expanded(GTK_EXPANDER(expander), settings->session.print_dialog_options_expanded);

  label_expander = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "label_expander"));

  notebook = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "notebook"));
  g_signal_connect_after((gpointer) notebook, "switch_page", G_CALLBACK(on_notebook_switch_page), gpointer(this));

  label_tab_notes = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "label_tab_notes"));
  checkbutton_full_references = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "checkbutton_full_references"));
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_full_references), settings->session.print_references_in_notes_in_full);
  // Set widget insensitive since is has not yet been implemented.
  gtk_widget_set_sensitive (checkbutton_full_references, false);

  label_tab_page = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "label_tab_page"));
  checkbutton_cropmarks = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "checkbutton_cropmarks"));
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_cropmarks), settings->session.print_crop_marks);

  label_tab_mapping = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "label_tab_mapping"));
  button_font_mapping_clear = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "button_font_mapping_clear"));
  filechooserbutton_font_mapping_file = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "filechooserbutton_font_mapping_file"));
  g_signal_connect((gpointer) button_font_mapping_clear, "clicked", G_CALLBACK(on_button_font_mapping_clear_clicked), gpointer(filechooserbutton_font_mapping_file));
  if (!projectconfig->xetex_font_mapping_file_get().empty()) {
    gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooserbutton_font_mapping_file), projectconfig->xetex_font_mapping_file_get().c_str());
  }

  label_tab_engine = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "label_tab_engine"));
  GSList *shaping_engine_group = NULL;
  radiobutton_shaping_engine_generic = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "radiobutton_shaping_engine_generic"));
  gtk_radio_button_set_group(GTK_RADIO_BUTTON(radiobutton_shaping_engine_generic), shaping_engine_group);
  shaping_engine_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radiobutton_shaping_engine_generic));
  radiobutton_shaping_engine_arab = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "radiobutton_shaping_engine_arab"));
  gtk_radio_button_set_group(GTK_RADIO_BUTTON(radiobutton_shaping_engine_arab), shaping_engine_group);
  shaping_engine_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radiobutton_shaping_engine_arab));
  shaping_engine_set (projectconfig->xetex_shaping_engine_get());

  InDialogHelp * indialoghelp = new InDialogHelp(dialog, gtkbuilder, NULL, "file/print/project");
  cancelbutton = indialoghelp->cancelbutton;
  okbutton = indialoghelp->okbutton;
  gtk_widget_grab_focus(okbutton);
  gtk_widget_grab_default(okbutton);
  g_signal_connect((gpointer) okbutton, "clicked", G_CALLBACK(on_okbutton_clicked), gpointer(this));

  set_gui();
}
Exemple #4
0
void git_revert_to_internal_repository(const ustring & project)
// This reverts the repository to the internal one, if that is not yet the case.
{
  // Set in the configuration that we're using a local repository only.
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(project);
  projectconfig->git_use_remote_repository_set(false);
}
CheckValidateReferences::CheckValidateReferences(const ustring & project, const vector < unsigned int >&books, bool gui)
/*
It checks on the correctness and existence of the references found in the
text and in the notes.
project: project to check.
books: books to check; if empty it checks them all.
gui: whether to show graphical progressbar.
*/
{
  // The variables and settings.
  cancelled = false;
  myproject = project;
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(project);
  versification = projectconfig->versification_get();
  language = projectconfig->language_get();

  // Get a list of the books to check. If no books were given, take them all.
  vector < unsigned int >mybooks(books.begin(), books.end());
  if (mybooks.empty())
    mybooks = project_get_books(project);

  // GUI.
  progresswindow = NULL;
  if (gui) {
    progresswindow = new ProgressWindow(_("Validating references"), true);
    progresswindow->set_iterate(0, 1, mybooks.size());
  }
  // Go through each book.
  for (unsigned int bk = 0; bk < mybooks.size(); bk++) {
    if (gui) {
      progresswindow->iterate();
      if (progresswindow->cancel) {
        cancelled = true;
        return;
      }
    }
    book = mybooks[bk];

    // Go through each chapter.
    vector < unsigned int >chapters = project_get_chapters(project, book);
    for (unsigned int ch = 0; ch < chapters.size(); ch++) {
      chapter = chapters[ch];

      // Go through each verse.
      vector < ustring > verses = project_get_verses(project, book, chapter);
      for (unsigned int vs = 0; vs < verses.size(); vs++) {
        verse = verses[vs];

        // Check the text.
        ustring line = project_retrieve_verse(project, book, chapter, verse);
        check(line);
      }
    }
  }
}
void RemoteRepositoryAssistant::on_assistant_apply ()
{
  // Configurations.
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(bible);

  // Whether to use the remote repository.
  bool use_remote_repository = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton_use_repository));
  if (bible_notes_selector_bible ())
    projectconfig->git_use_remote_repository_set(use_remote_repository);
  else
    settings->genconfig.consultation_notes_git_use_remote_repository_set(use_remote_repository);

  // The remote repository URL.
  if (bible_notes_selector_bible ())
    projectconfig->git_remote_repository_url_set(repository_url_get());
  else
    settings->genconfig.consultation_notes_git_remote_repository_url_set(repository_url_get());
  
  // If the repository was cloned, move it into place.
  if (repository_was_cloned()) {
    ustring destination_data_directory;
    if (bible_notes_selector_bible ())
      destination_data_directory = project_data_directory_project(bible);
    else
      destination_data_directory = notes_shared_storage_folder ();
    unix_rmdir(destination_data_directory);
    unix_mv(persistent_clone_directory, destination_data_directory);
    // Switch rename detection off. 
    // This is necessary for the consultation notes, since git has been seen to cause spurious renames.
    GwSpawn spawn ("git");
    spawn.workingdirectory (destination_data_directory);
    spawn.arg ("config");
    spawn.arg ("--global");
    spawn.arg ("diff.renamelimit");
    spawn.arg ("0");
    spawn.run ();
  }

  if (bible_notes_selector_bible ()) {
    // Take a snapshot of the whole project.
    snapshots_shoot_project (bible);
  } else{
    // Create the index for the consultation notes.
    notes_create_index ();
  }

  // Show summary.
  gtk_assistant_set_current_page (GTK_ASSISTANT (assistant), summary_page_number);
}
Exemple #7
0
void git_upgrade ()
// Upgrades the git system.
{
  // Go through the projects that have their git repository enabled.
  extern Settings * settings;
  vector <ustring> projects = projects_get_all ();
  for (unsigned int i = 0; i < projects.size(); i++) {
    ProjectConfiguration * projectconfig = settings->projectconfig (projects[i]);
    ustring git_directory = gw_build_filename (project_data_directory_project (projects[i]), ".git");
    if (projectconfig->git_use_remote_repository_get()) {
      // At times there's a stale index.lock file that prevents any collaboration.
      // This is to be removed.
      ustring index_lock = gw_build_filename (git_directory, "index.lock");
      if (g_file_test (index_lock.c_str(), G_FILE_TEST_IS_REGULAR)) {
        gw_message (_("Cleaning out index lock ") + index_lock);
        unix_unlink (index_lock.c_str());
      }
      // Get the data directory for the project
      ustring datadirectory = tiny_project_data_directory_project(projects[i]);
      // On most machines git can determine the user's name from the system services. 
      // On the XO machine, it can't. It is set here manually. 
      // On more recent versions of git, like version 1.8.3 and younger,
      // although git may determine the user's name from the system, 
      // it still requires it to be set manually.
      ustring command;
      command = "git config user.email \"";
      command.append(g_get_user_name());
      command.append("@");
      command.append(g_get_host_name());
      command.append("\"");
      maintenance_register_shell_command (datadirectory, command);
      command = "git config user.name \"";
      command.append(g_get_real_name());
      command.append("\"");
      maintenance_register_shell_command (datadirectory, command);
      // (Re)initialize the repository. This can be done repeatedly without harm.
      // Note that this is done on shutdown.
      maintenance_register_shell_command (datadirectory, "git init");
    } else {
      if (g_file_test (git_directory.c_str(), G_FILE_TEST_IS_DIR)) {
        gw_message (_("Cleaning out folder ") + git_directory);
        ProgressWindow progresswindow (_("Tidying up project ") + projects[i], false);
        progresswindow.set_fraction (0.5);
        unix_rmdir (git_directory);
      }
    }
  }
}
Exemple #8
0
void XeTeXDialog::on_okbutton()
{
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get());
  settings->session.print_dialog_options_expanded = gtk_expander_get_expanded(GTK_EXPANDER(expander));
  settings->session.print_references_in_notes_in_full = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton_full_references));
  settings->session.print_crop_marks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton_cropmarks));
  gchar * xetex_font_mapping_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooserbutton_font_mapping_file));
  if (xetex_font_mapping_filename) {
    projectconfig->xetex_font_mapping_file_set(xetex_font_mapping_filename);
    g_free (xetex_font_mapping_filename);
  } else {
    projectconfig->xetex_font_mapping_file_set("");
  }
  projectconfig->xetex_shaping_engine_set(shaping_engine_get ());
}
CheckChaptersVerses::CheckChaptersVerses(const ustring & project, const vector < unsigned int >&books, bool gui)
/*
It checks the number of chapters per book and the number of verses per chapter.
project: project to check.
books: books to check; if empty it checks them all.
gui: show graphical progressbar.
*/
{
  cancelled = false;
  myproject = project;
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(project);
  myversification = projectconfig->versification_get();
  // If no books given, take them all.
  vector < unsigned int >mybooks(books.begin(), books.end());
  if (mybooks.empty())
    mybooks = project_get_books(project);
  progresswindow = NULL;
  if (gui) {
    progresswindow = new ProgressWindow(_("Checking chapters and verses"), true);
    progresswindow->set_iterate(0, 1, mybooks.size());
  }
  for (unsigned int bk = 0; bk < mybooks.size(); bk++) {
    if (gui) {
      progresswindow->iterate();
      progresswindow->set_text(books_id_to_english(mybooks[bk]));
      if (progresswindow->cancel) {
        cancelled = true;
        return;
      }
    }
    first_chapter_found = false;
    vector < unsigned int >chapters = project_get_chapters(project, mybooks[bk]);
    highest_chapter_get(mybooks[bk]);
    for (unsigned int ch = 0; ch < chapters.size(); ch++) {
      new_chapter_check(mybooks[bk], chapters[ch]);
      vector < ustring > verses;
      verses = project_get_verses(project, mybooks[bk], chapters[ch]);
      highest_verse_get(mybooks[bk], chapters[ch]);
      verses_check(mybooks[bk], chapters[ch], verses);
    }
    last_chapter_check(mybooks[bk], chapters);
  }
}
Exemple #10
0
void notes_display(ustring& note_buffer, vector <unsigned int> ids, unsigned int cursor_id, unsigned int &cursor_offset, bool & stop, unsigned int edited_note_id)
/*
 This collect html data for displaying the notes.
 It collects data for all the notes that have an id given in ids.
 It inserts a html anchor at the start of the note whose id is "cursor_id".
 If an "edited_note_id" is given that is not in the list of "ids", then it will display that one too, together with a message.
 */
{
    extern Settings *settings;
    ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get());
    ustring language = projectconfig->language_get();

    // Whether to show the text of the reference(s).
    bool show_reference_text = settings->genconfig.notes_display_reference_text_get();

    // Whether to show the summary only.
    bool show_summary = settings->genconfig.notes_display_summary_get();

    // See whether to display an extra note, one just edited.
    if (edited_note_id) {
        set <unsigned int> id_set (ids.begin(), ids.end());
        if (id_set.find (edited_note_id) == id_set.end()) {
            notes_display_internal(language, show_reference_text, show_summary, note_buffer, edited_note_id,
                                   _("The following note is displayed because it was created or edited. Normally it would not have been displayed."),
                                   cursor_id, cursor_offset);
        }
    }

    // Go through all the notes.
    for (unsigned int c = 0; c < ids.size(); c++) {

        // Handle possible stop command.
        if (stop)
            continue;

        // Display this note.
        notes_display_internal(language, show_reference_text, show_summary, note_buffer, ids[c], NULL, cursor_id, cursor_offset);

    }

}
Exemple #11
0
void VcProj::removeProjectConfiguration( const ProjectConfiguration &config )
{
	// delete the <ProjectConfiguration> itself
	std::string projectConfigurationNodesXPath = "/Project/ItemGroup[@Label=\"ProjectConfigurations\"]/ProjectConfiguration";
	pugi::xpath_node_set configurationNodes = mProjDom->select_nodes( projectConfigurationNodesXPath.c_str() );
	for( pugi::xpath_node_set::const_iterator it = configurationNodes.begin(); it != configurationNodes.end(); ++it ) {
		if( QString( it->node().attribute( "Include" ).value() ) == config.asString() ) {
			it->node().parent().remove_child( it->node() );
			break;
		}
	}

	// delete all nodes of the form
	// Condition="'$(Configuration)|$(Platform)'=='Debug_ANGLE|Win32'"
	std::string conditionString = "'$(Configuration)|$(Platform)'=='" + config.asString().toStdString() + "'";
	std::string conditionXPath = "//*[@Condition=\"" + conditionString + "\"]";
	pugi::xpath_node_set conditionNodes = mProjDom->select_nodes( conditionXPath.c_str() );
	for( pugi::xpath_node_set::const_iterator it = conditionNodes.begin(); it != conditionNodes.end(); ++it ) {
		it->node().parent().remove_child( it->node() );
	}
}
void SelectBooksDialog::on_okbutton()
{
    // Get the list of books now selected.
    selection.clear();
    vector < ustring > books;
    gtk_tree_selection_selected_foreach(selectbooks, selection_foreach_function, gpointer(&books));
    for (unsigned int i = 0; i < books.size(); i++) {
        unsigned int book = books_name_to_id(mylanguage, books[i]);
        if (book)
            selection.push_back(book);
    }
    // Also produce a set out of that list.
    selectionset.clear();
    for (unsigned int i = 0; i < selection.size(); i++) {
        selectionset.insert(selection[i]);
    }
    // If portions are showing, store the values there too.
    if (myshowportions) {
        // Get books, includes and portions.
        vector < ustring > reordered_books;
        vector < bool > reordered_includes;
        vector < ustring > reordered_portions;
        {
            vector < ustring > books = listview_get_strings(treeviewbooks);
            for (unsigned int i = 0; i < books.size(); i++) {
                unsigned int book = books_name_to_id(mylanguage, books[i]);
                reordered_books.push_back(books_id_to_english(book));
                bool include = (selectionset.find(book) != selectionset.end());
                reordered_includes.push_back(include);
            }
        }
        reordered_portions = listview_get_strings(treeviewportions);
        // Save books, includes and portions.
        extern Settings *settings;
        ProjectConfiguration *projectconfig = settings->projectconfig(myproject);
        projectconfig->reordered_books_set(reordered_books);
        projectconfig->reordered_includes_set(reordered_includes);
        projectconfig->reordered_portions_set(reordered_portions);
    }
}
void OTQuotations::get(Reference & reference, vector < Reference > &references, vector < ustring > &comments)
/*
Retrieves an Old Testament quotation of a New Testament reference.
This function does a bit more too. If an OT reference is passed, it also looks 
up the place in the NT where this is quoted.
reference: The input reference.
references: The output reference: contains the related references.
*/
{
  // Read data if we've nothing yet.
  if (quotations_nt_order.empty())
    read();

  // Store the original reference.
  references.push_back(reference);
  comments.push_back(_("Current one"));

  // Remap the references.
  extern Settings *settings;
  ustring project = settings->genconfig.project_get();
  ProjectConfiguration *projectconfig = settings->projectconfig(project, false);
  Mapping mapping(projectconfig->versification_get(), reference.book_get());
  for (unsigned int i = 0; i < quotations_nt_order.size(); i++) {
    mapping.book_change(quotations_nt_order[i].reference.book_get());
    mapping.original_to_me(quotations_nt_order[i].reference);
    for (unsigned int i2 = 0; i2 < quotations_nt_order[i].referents.size(); i2++) {
      mapping.book_change(quotations_nt_order[i].referents[i2].book_get());
      mapping.original_to_me(quotations_nt_order[i].referents[i2]);
    }
  }

  // Go through the quotations looking for matching ones.
  bool lxx = false;
  for (unsigned int i = 0; i < quotations_nt_order.size(); i++) {
    // If this is a NT reference, look for the corresponding OT quotations.
    if (reference.equals(quotations_nt_order[i].reference)) {
      for (unsigned int i2 = 0; i2 < quotations_nt_order[i].referents.size(); i2++) {
        references.push_back(quotations_nt_order[i].referents[i2]);
        comments.push_back(comment(_("Quotation"), lxx));
      }
    }
    // If this is an OT reference, look for possible other ones in the OT, and the NT place that quotes it.
    for (unsigned int i2 = 0; i2 < quotations_nt_order[i].referents.size(); i2++) {
      if (reference.equals(quotations_nt_order[i].referents[i2])) {
        references.push_back(quotations_nt_order[i].reference);
        comments.push_back(_("Quoted here"));
        for (unsigned int i3 = 0; i3 < quotations_nt_order[i].referents.size(); i3++) {
          if (i3 != i2) {
            references.push_back(quotations_nt_order[i].referents[i3]);
            comments.push_back(comment(_("Parallel passage"), lxx));
          }
        }
      }
    }
  }

  // If there is only one reference found, that will be the original one.
  // That means that no parallel or corresponding references were found.
  // Erase that single one in such cases.
  if (references.size() == 1) {
    references.clear();
    comments.clear();
  }
}
Exemple #14
0
pugi::xml_node VcProj::findItemDefinitionGroup( const ProjectConfiguration &projConfig )
{
	return findItemDefinitionGroup( projConfig.getConfig(), projConfig.getPlatform() );
}
int main(int argc, char** argv)
{
	try {
		// init command line parser
		util::ProgramOptions::init(argc, argv);

		int stack_id = optionStackId.as<int>();
		std::string comp_dir = optionComponentDir.as<std::string>();
		std::string pg_host = optionPGHost.as<std::string>();
		std::string pg_user = optionPGUser.as<std::string>();
		std::string pg_pass = optionPGPassword.as<std::string>();
		std::string pg_dbase = optionPGDatabase.as<std::string>();


		std::cout << "Testing PostgreSQL stores with stack ID " << stack_id << std::endl;

		// init logger
		logger::LogManager::init();
		logger::LogManager::setGlobalLogLevel(logger::Debug);

		// create new project configuration
		ProjectConfiguration pc;
		pc.setBackendType(ProjectConfiguration::PostgreSql);
		StackDescription stack;
		stack.id = stack_id;
		pc.setCatmaidStack(Raw, stack);
		pc.setComponentDirectory(comp_dir);
		pc.setPostgreSqlHost(pg_host);
		pc.setPostgreSqlUser(pg_user);
		pc.setPostgreSqlPassword(pg_pass);
		pc.setPostgreSqlDatabase(pg_dbase);

		PostgreSqlSliceStore sliceStore(pc, Membrane);

		// Add first set of slices
		boost::shared_ptr<Slice> slice1 = createSlice(10, 0);
		boost::shared_ptr<Slice> slice2 = createSlice(10, 1);
		boost::shared_ptr<Slice> slice3 = createSlice(10, 2);

		Slices slices = Slices();
		slices.add(slice1);
		slices.add(slice2);
		slices.add(slice3);

		Block block(0, 0, 0);
		sliceStore.associateSlicesToBlock(slices, block);

		Blocks blocks;
		blocks.add(block);
		Blocks missingBlocks;

		boost::shared_ptr<Slices> retrievedSlices =
				sliceStore.getSlicesByBlocks(blocks, missingBlocks);

		// Create conflict set where each slice
		ConflictSet conflictSet1;
		conflictSet1.addSlice(slice1->hashValue());
		conflictSet1.addSlice(slice2->hashValue());
		conflictSet1.addSlice(slice3->hashValue());

		ConflictSets conflictSets;
		conflictSets.add(conflictSet1);

		sliceStore.associateConflictSetsToBlock(conflictSets, block);
		boost::shared_ptr<ConflictSets> retrievedConflictSets =
				sliceStore.getConflictSetsByBlocks(blocks, missingBlocks);
		for (const ConflictSet& cs : *retrievedConflictSets) {
			std::cout << "ConflictSet hash: " << hash_value(cs);

			for (const SliceHash& sh : cs.getSlices()) {
				std::cout << " Slice hash: " << sh;
			}

			std::cout << std::endl;
		}

		PostgreSqlSegmentStore segmentStore(pc, Membrane);
		util::box<unsigned int, 2> segmentBounds(0, 0, 0, 0);
		std::vector<double> segmentFeatures;
		segmentFeatures.push_back(0.0);
		segmentFeatures.push_back(1.0);
		segmentFeatures.push_back(2.0);
		SegmentDescription segment(0, segmentBounds);
		segment.addLeftSlice(slice1->hashValue());
		segment.addRightSlice(slice2->hashValue());
		segment.setFeatures(segmentFeatures);

		boost::shared_ptr<SegmentDescriptions> segments = boost::make_shared<SegmentDescriptions>();
		segments->add(segment);

		segmentStore.associateSegmentsToBlock(*segments, block);

		boost::shared_ptr<SegmentDescriptions> retrievedSegments =
				segmentStore.getSegmentsByBlocks(blocks, missingBlocks, false);

	} catch (boost::exception& e) {

		handleException(e, std::cerr);
	}
}
void RemoteRepositoryAssistant::on_assistant_prepare (GtkWidget *page)
{
  extern Settings * settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(bible);
  
  if (page == checkbutton_use_repository) {
    // Set all values in the GUI, according to the project configuration if it is a Bible, 
    // or the general configuration for project notes.

    // Whether to use the remote repository.
    bool use_remote_repository = false;
    if (bible_notes_selector_bible ()) {
      use_remote_repository = projectconfig->git_use_remote_repository_get();
    } else {
      use_remote_repository = settings->genconfig.consultation_notes_git_use_remote_repository_get();
    }
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton_use_repository), use_remote_repository);

    // Set the repository location.
    ustring repository_url;
    if (bible_notes_selector_bible ()) {
      repository_url = projectconfig->git_remote_repository_url_get();
    } else {
      repository_url = settings->genconfig.consultation_notes_git_remote_repository_url_get();
    }
    ignore_entry_repository_changed = true;
    gtk_entry_set_text (GTK_ENTRY (entry_repository), repository_url.c_str());
    ignore_entry_repository_changed = false;
  }
  
  if (page == label_try_git) {
    // Prepare for the page to try git.
    if (!git_tried_and_okay) {
      git_tried_and_okay = try_git ();
      if (git_tried_and_okay) {
        gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), label_try_git, true);
      }
    }
  }

  if (page == vbox_repository) {
    // Prepare for the page where the repository URL is set.
    gtk_widget_grab_focus (entry_repository);
    on_entry_repository();
  }

  if (page == vbox_clone) {
    // Prepare for the page where the cloning is done.
    if (repository_url_get() != previously_cloned_url) {
      repository_unclone();
    }
    gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), vbox_clone, repository_was_cloned());
    if (!repository_was_cloned()) {
      gtk_label_set_text (GTK_LABEL (label_clone), "");
    }
  }
  
  if (page == label_write_test) {
    // Prepare for the page for testing write access.
    if (!write_access_granted) {
      test_write_access ();
    }
  }
}
LocalSegmentStore::LocalSegmentStore(const ProjectConfiguration& config)
	: _weights(config.getLocalFeatureWeights()) {}
Exemple #18
0
void XeTeX::write_document_tex_file ()
{
  // Settings.
  extern Settings * settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get());
  
  // Style sheet.
  extern Styles * styles;
  Stylesheet * sheet = styles->stylesheet (stylesheet_get_actual ());
  
  document_tex.push_back (_("% Configuration file created by Bibledit-Gtk"));
  document_tex.push_back (_("% You can modify it to suit your needs"));
  document_tex.push_back (_("% After modification, run the following command in this directory:"));
  document_tex.push_back (_("%   xetex document.tex"));
  document_tex.push_back (_("% After that look carefully at the output"));
  document_tex.push_back (_("% If it says that a re-run is required, repeat this command"));

  document_tex.push_back ("");
  document_tex.push_back (_("% Include the ptx2pdf macros"));
  document_tex.push_back ("\\input paratext2.tex");

  document_tex.push_back ("");
  document_tex.push_back (_("% Paper size"));
  document_tex.push_back ("\\PaperWidth=" + convert_to_string (settings->genconfig.paper_width_get()) + "cm");
  document_tex.push_back ("\\PaperHeight=" + convert_to_string (settings->genconfig.paper_height_get()) + "cm");

  if (settings->session.print_crop_marks){
    document_tex.push_back ("");
    document_tex.push_back (_("% Crop marks"));
    document_tex.push_back ("\\CropMarkstrue");
  }

  document_tex.push_back ("");
  document_tex.push_back (_("% The basic unit for the margins; changing this will alter them all"));
  document_tex.push_back ("\\MarginUnit=1cm");

  document_tex.push_back ("");
  document_tex.push_back (_("% Relative sizes of margins, based on the unit above"));
  document_tex.push_back ("\\def\\TopMarginFactor{" + convert_to_string (settings->genconfig.paper_top_margin_get()) + "}");
  document_tex.push_back ("\\def\\BottomMarginFactor{" + convert_to_string (settings->genconfig.paper_bottom_margin_get()) + "}");
  document_tex.push_back ("\\def\\SideMarginFactor{" + convert_to_string (settings->genconfig.paper_outside_margin_get()) + "}");

  if (settings->genconfig.paper_inside_margin_get() != settings->genconfig.paper_outside_margin_get()) {
    document_tex.push_back ("");
    document_tex.push_back (_("% Extra margin for the gutter on the binding side"));
    document_tex.push_back ("\\BindingGuttertrue");
    document_tex.push_back ("\\BindingGutter=" + convert_to_string (settings->genconfig.paper_inside_margin_get() - settings->genconfig.paper_outside_margin_get()) + "cm");
    document_tex.push_back ("");
    document_tex.push_back (_("% Double sided printing"));
    document_tex.push_back ("\\DoubleSidedtrue");
  }

  if (!projectconfig->editor_font_default_get()) {
    PangoFontDescription *font_desc = pango_font_description_from_string(projectconfig->editor_font_name_get().c_str());
    if (font_desc){
      
      // Assemble the string for the font mapping.
      ustring font_mapping = projectconfig->xetex_font_mapping_file_get();
      if (!font_mapping.empty()) {
        if (g_str_has_suffix (font_mapping.c_str(), ".tec")) {
          font_mapping = gw_path_get_basename (font_mapping);
          // Remove the .tec suffix.
          font_mapping.erase (font_mapping.length() - 4, 4);
          // Insert the mapping command.
          font_mapping.insert (0, "mapping=");
        } else {
          gw_warning (_("Font mapping file ") + font_mapping +  _(" should have the .tec suffix - ignoring this file"));
          font_mapping.clear();
        }
      }

      // Assemble the string for the shaping engine.
      ustring shaping_engine;
      switch (XeTeXScriptingEngineType (projectconfig->xetex_shaping_engine_get())) {
        case xtxsetGeneric:                                 break;
        case xtxsetArab:    shaping_engine = "script=arab"; break;
      }

      // Assemble the addition to the font.
      ustring font_addition;
      if (!font_mapping.empty()) {
        if (font_addition.empty())
          font_addition.append (":");
        else 
          font_addition.append (";");
        font_addition.append (font_mapping);
      }
      if (!shaping_engine.empty()) {
        if (font_addition.empty())
          font_addition.append (":");
        else 
          font_addition.append (";");
        font_addition.append (shaping_engine);
      }

      ustring font_family = pango_font_description_get_family (font_desc);
      document_tex.push_back ("");
      document_tex.push_back (_("% Fonts to use for \"plain\", \"bold\", \"italic\", and \"bold italic\" from the stylesheet"));
      document_tex.push_back (_("% (they need not really be italic, etc.)"));
      document_tex.push_back (_("% Add e.g. \":mapping=farsidigits\" to get digits in Farsi, provided the farsidigits.tec TECkit mapping is available"));
      document_tex.push_back (_("% Add e.g. \":script=arab\" to use the arab shaping engine instead of the generic one"));
      document_tex.push_back ("\\def\\regular{\"" + font_family + font_addition + "\"}");
      document_tex.push_back ("\\def\\bold{\"" + font_family + "/B" + font_addition + "\"}");
      document_tex.push_back ("\\def\\italic{\"" + font_family + "/I" + font_addition +  "\"}");
      document_tex.push_back ("\\def\\bolditalic{\"" + font_family + "/BI" + font_addition +  + "\"}");
      pango_font_description_free(font_desc);
    }
  }

  if (projectconfig->right_to_left_get()) {
    document_tex.push_back ("");
    document_tex.push_back (_("% Right-to-left layout mode"));
    document_tex.push_back ("\\RTLtrue");
  }

  document_tex.push_back ("");
  document_tex.push_back (_("% The unit for font sizes in the stylesheet; changing this will scale all text proportionately"));
  document_tex.push_back ("\\FontSizeUnit=1pt");

  document_tex.push_back ("");
  document_tex.push_back (_("% Scaling factor used to adjust line spacing, relative to font size"));
  double line_spacing_factor = 1.0;
  double vertical_space_factor = 1.0;
  if (!projectconfig->editor_font_default_get()){
    line_spacing_factor = projectconfig->text_line_height_get() / 100;
    vertical_space_factor = projectconfig->text_line_height_get() / 100;
  }
  document_tex.push_back ("\\def\\LineSpacingFactor{" + convert_to_string (line_spacing_factor) + "}");
  document_tex.push_back ("\\def\\VerticalSpaceFactor{" + convert_to_string (vertical_space_factor) + "}");

  document_tex.push_back ("");
  document_tex.push_back (_("% Information to include in the running header (at top of pages, except first)"));
  document_tex.push_back (_("% We set the items to print at left/center/right of odd and even pages separately"));
  document_tex.push_back (_("% Possible contents:"));
  document_tex.push_back (_("%   \\rangeref = Scripture reference of the range of text on the page;"));
  document_tex.push_back (_("%   \\firstref = reference of the first verse on the page)"));
  document_tex.push_back (_("%   \\lastref = reference of the last verse on the page)"));
  document_tex.push_back (_("%   \\pagenumber = the page number"));
  document_tex.push_back (_("%   \\empty = print nothing in this position"));
  document_tex.push_back ("\\def\\RHoddleft{\\empty}");
  document_tex.push_back ("\\def\\RHoddcenter{\\empty}");
  document_tex.push_back ("\\def\\RHoddright{\\rangeref}");
  document_tex.push_back ("");
  document_tex.push_back ("\\def\\RHevenleft{\\rangeref}");
  document_tex.push_back ("\\def\\RHevencenter{\\empty}");
  document_tex.push_back ("\\def\\RHevenright{\\empty}");
  document_tex.push_back ("");
  document_tex.push_back ("\\def\\RHtitleleft{\\empty}");
  document_tex.push_back ("\\def\\RHtitlecenter{\\empty}");
  document_tex.push_back ("\\def\\RHtitleright{\\empty}");
  document_tex.push_back ("");
  document_tex.push_back ("\\def\\RFoddcenter{\\pagenumber}");
  document_tex.push_back ("\\def\\RFevencenter{\\pagenumber}");
  document_tex.push_back ("\\def\\RFtitlecenter{\\pagenumber}");

  document_tex.push_back ("");
  document_tex.push_back (_("% Whether to include verse number in running head, or only chapter"));
  document_tex.push_back ("\\VerseRefstrue");

  document_tex.push_back ("");
  document_tex.push_back (_("% Whether to skip printing verse number 1 at start of chapter"));
  document_tex.push_back ("\\OmitVerseNumberOnetrue");

  document_tex.push_back ("");
  document_tex.push_back (_("% Whether to use paragraph indent at drop-cap chapter numbers"));
  document_tex.push_back (_("% \\IndentAtChaptertrue"));

  // Go through the stylesheet looking for note markers.
  for (unsigned int i = 0; i < sheet->styles.size(); i++) {
    bool retrieve_note_data = false;
    StyleV2 * style = sheet->styles[i];
    if (style->type == stFootEndNote) {
      if ((style->subtype == fentFootnote) || (style->subtype == fentEndnote)) {
        retrieve_note_data = true;
      }
    }
    if ((style->type == stFootEndNote) || (style->type == stCrossreference)) {
      if (style->subtype == ctCrossreference) {
        retrieve_note_data = true;
      }
    }
    if (retrieve_note_data) {

      ustring marker = style->marker;
      document_tex.push_back ("");
      document_tex.push_back (_("% Reformat \\") + marker + " notes as a single paragraph");
      document_tex.push_back ("\\ParagraphedNotes{" + marker + "}");

      document_tex.push_back ("");
      NoteNumberingType note_numbering = NoteNumberingType (style->userint1);
      switch (note_numbering) {
        case nntNumerical:
          document_tex.push_back (_("% Numerical callers for \\") + marker + _(" notes"));
          document_tex.push_back ("\\NumericCallers{" + marker + "}");
          break;
        case nntAlphabetical:
          document_tex.push_back (_("% Alphabetical callers for \\") + marker + _(" notes"));
          document_tex.push_back ("\\AutoCallers{" + marker+ "}{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}");
          break;
        case nntUserDefined:
          ustring autocallers;
          for (unsigned int i = 0; i < style->userstring1.size(); i++) {
            if (i)
              autocallers.append (",");
            autocallers.append (style->userstring1.substr (i, 1));
          }
          if (!autocallers.empty()) {
            document_tex.push_back (_("% Special caller sequence for \\") + marker + " notes");
            document_tex.push_back ("\\AutoCallers{" + marker+ "}{" + autocallers + "}");
          }
          break;
      }

      document_tex.push_back ("");
      NoteNumberingRestartType note_restart = NoteNumberingRestartType (style->userint2);
      switch (note_restart) {
        case nnrtNever:
          break;
        case nnrtBook:
          break;
        case nnrtChapter:
          break;
      }
      document_tex.push_back (_("% Reset callers every page for \\") + marker + _(" notes"));
      document_tex.push_back ("\\PageResetCallers{" + marker + "}");

      document_tex.push_back ("");
      document_tex.push_back (_("% Omit callers in the note for \\") + marker + _(" notes"));
      document_tex.push_back (_("% \\OmitCallerInNote{") + marker + "}");

    }
  }

  document_tex.push_back ("");
  document_tex.push_back (_("% The number of columns"));
  document_tex.push_back ("\\TitleColumns=1");
  document_tex.push_back ("\\IntroColumns=1");
  document_tex.push_back ("\\BodyColumns=2");

  document_tex.push_back ("");
  document_tex.push_back (_("% The gutter between double cols, relative to font size"));
  document_tex.push_back ("\\def\\ColumnGutterFactor{15}");

  // Define the Paratext stylesheet to be used as a basis for formatting
  write_stylesheet ();

  // Write the data and add their filenames.
  for (unsigned int i = 0; i < book_ids.size(); i++) {
    ustring filename = convert_to_string (book_ids[i]) + " " + books_id_to_english(book_ids[i]) + ".usfm";
    replace_text (filename, " ", "_");
    write_lines (gw_build_filename (working_directory, filename), book_data[i]);
    document_tex.push_back ("\\ptxfile{" + filename + "}");
  }

  // End of document input.
  document_tex.push_back ("\\end");

  // Write document.text to file.
  write_lines (gw_build_filename (working_directory, "document.tex"), document_tex);
}
RevertDialog::RevertDialog(Reference * reference)
{
  // Save variables.
  extern Settings *settings;
  project = settings->genconfig.project_get();
  ProjectConfiguration *projectconfig = settings->projectconfig(project);
  language = projectconfig->language_get();
  reference_chapter = reference->chapter_get();
  revisionloaded = false;
  branch = 0;

  // Build dialog.
  Shortcuts shortcuts(0);

  revertdialog = gtk_dialog_new();
  gtk_window_set_title(GTK_WINDOW(revertdialog), _("Revert"));
  gtk_window_set_position(GTK_WINDOW(revertdialog), GTK_WIN_POS_CENTER_ON_PARENT);
  gtk_window_set_type_hint(GTK_WINDOW(revertdialog), GDK_WINDOW_TYPE_HINT_DIALOG);

  dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG (revertdialog));
  gtk_widget_show(dialog_vbox1);

  hbox1 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox1);
  gtk_box_pack_start(GTK_BOX(dialog_vbox1), hbox1, TRUE, TRUE, 0);

  vbox1 = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vbox1);
  gtk_box_pack_start(GTK_BOX(hbox1), vbox1, TRUE, TRUE, 0);

  table1 = gtk_table_new(2, 2, FALSE);
  gtk_widget_show(table1);
  gtk_box_pack_start(GTK_BOX(vbox1), table1, FALSE, TRUE, 0);

  comboboxbook = gtk_combo_box_new_text();
  gtk_widget_show(comboboxbook);
  gtk_table_attach(GTK_TABLE(table1), comboboxbook, 0, 1, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);

  comboboxchapter = gtk_combo_box_new_text();
  gtk_widget_show(comboboxchapter);
  gtk_table_attach(GTK_TABLE(table1), comboboxchapter, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (GTK_FILL), 0, 0);

  labelbook = gtk_label_new(_("Book"));
  gtk_widget_show(labelbook);
  gtk_table_attach(GTK_TABLE(table1), labelbook, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment(GTK_MISC(labelbook), 0, 0.5);

  shortcuts.label(labelbook);

  gtk_label_set_mnemonic_widget(GTK_LABEL(labelbook), comboboxbook);

  labelchapter = gtk_label_new(_("Chapter"));
  gtk_widget_show(labelchapter);
  gtk_table_attach(GTK_TABLE(table1), labelchapter, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment(GTK_MISC(labelchapter), 0, 0.5);

  shortcuts.label(labelchapter);

  gtk_label_set_mnemonic_widget(GTK_LABEL(labelchapter), comboboxchapter);

  hseparator1 = gtk_hseparator_new();
  gtk_widget_show(hseparator1);
  gtk_box_pack_start(GTK_BOX(vbox1), hseparator1, FALSE, TRUE, 0);

  labelrevisions = gtk_label_new(_("Revisions"));
  gtk_widget_show(labelrevisions);
  gtk_box_pack_start(GTK_BOX(vbox1), labelrevisions, FALSE, FALSE, 0);
  gtk_misc_set_alignment(GTK_MISC(labelrevisions), 0, 0.5);

  shortcuts.label(labelrevisions);

  scrolledwindowrevisions = gtk_scrolled_window_new(NULL, NULL);
  gtk_widget_show(scrolledwindowrevisions);
  gtk_box_pack_start(GTK_BOX(vbox1), scrolledwindowrevisions, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindowrevisions), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindowrevisions), GTK_SHADOW_IN);

  treeviewrevisions = gtk_tree_view_new();
  gtk_widget_show(treeviewrevisions);
  gtk_container_add(GTK_CONTAINER(scrolledwindowrevisions), treeviewrevisions);
  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeviewrevisions), FALSE);

  gtk_label_set_mnemonic_widget(GTK_LABEL(labelrevisions), treeviewrevisions);

  // Create treeview related stuff.
  store = gtk_list_store_new(1, G_TYPE_STRING);
  gtk_tree_view_set_model(GTK_TREE_VIEW(treeviewrevisions), GTK_TREE_MODEL(store));
  g_object_unref(store);
  GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewrevisions), column);
  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviewrevisions));
  gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);

  vseparator1 = gtk_vseparator_new();
  gtk_widget_show(vseparator1);
  gtk_box_pack_start(GTK_BOX(hbox1), vseparator1, FALSE, TRUE, 0);

  vbox2 = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vbox2);
  gtk_box_pack_start(GTK_BOX(hbox1), vbox2, TRUE, TRUE, 0);

  GSList *radiobutton_current_group = NULL;

  radiobutton_current = gtk_radio_button_new_with_mnemonic (NULL, _("View current version"));
  gtk_widget_show (radiobutton_current);
  gtk_box_pack_start (GTK_BOX (vbox2), radiobutton_current, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_current), radiobutton_current_group);
  radiobutton_current_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_current));

  shortcuts.button(radiobutton_current);

  radiobutton_previous = gtk_radio_button_new_with_mnemonic (NULL, _("View previous revision"));
  gtk_widget_show (radiobutton_previous);
  gtk_box_pack_start (GTK_BOX (vbox2), radiobutton_previous, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_previous), radiobutton_current_group);
  radiobutton_current_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_previous));

  shortcuts.button(radiobutton_previous);

  radiobutton_changes = gtk_radio_button_new_with_mnemonic (NULL, _("View changes if reverting to previous revision"));
  gtk_widget_show (radiobutton_changes);
  gtk_box_pack_start (GTK_BOX (vbox2), radiobutton_changes, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_changes), radiobutton_current_group);
  radiobutton_current_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_changes));

  shortcuts.button(radiobutton_changes);
 
  changes_gui = new DisplayChangesGui (vbox2);

  gtk_widget_set_size_request(changes_gui->textview, 450, 500);

  dialog_action_area1 = gtk_dialog_get_action_area (GTK_DIALOG(revertdialog));
  gtk_widget_show(dialog_action_area1);
  gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area1), GTK_BUTTONBOX_END);

  new InDialogHelp(revertdialog, NULL, &shortcuts, "edit/revert");

  cancelbutton1 = gtk_button_new_from_stock("gtk-cancel");
  gtk_widget_show(cancelbutton1);
  gtk_dialog_add_action_widget(GTK_DIALOG(revertdialog), cancelbutton1, GTK_RESPONSE_CANCEL);
  gtk_widget_set_can_default (GTK_WIDGET (cancelbutton1), true);

  okbutton1 = gtk_button_new_from_stock("gtk-ok");
  gtk_widget_show(okbutton1);
  gtk_dialog_add_action_widget(GTK_DIALOG(revertdialog), okbutton1, GTK_RESPONSE_OK);
  gtk_widget_set_can_default (GTK_WIDGET (okbutton1), true);

  shortcuts.stockbutton(cancelbutton1);
  shortcuts.stockbutton(okbutton1);
  shortcuts.process();

  g_signal_connect((gpointer) comboboxbook, "changed", G_CALLBACK(on_comboboxbook_changed), gpointer(this));
  g_signal_connect((gpointer) comboboxchapter, "changed", G_CALLBACK(on_comboboxchapter_changed), gpointer(this));
  g_signal_connect((gpointer) treeviewrevisions, "row_activated", G_CALLBACK(on_treeviewrevisions_row_activated), gpointer(this));
  g_signal_connect((gpointer) okbutton1, "clicked", G_CALLBACK(on_okbutton1_clicked), gpointer(this));
  g_signal_connect ((gpointer) radiobutton_current, "toggled",  G_CALLBACK (on_radiobutton_toggled), gpointer(this));
  g_signal_connect ((gpointer) radiobutton_previous, "toggled",  G_CALLBACK (on_radiobutton_toggled), gpointer(this));
  g_signal_connect ((gpointer) radiobutton_changes, "toggled",  G_CALLBACK (on_radiobutton_toggled), gpointer(this));

  gtk_widget_grab_focus(okbutton1);
  gtk_widget_grab_default(okbutton1);

  // Load books. This also loads the chapters through the callback.
  vector < unsigned int >books = project_get_books(project);
  vector < ustring > localbooks;
  for (unsigned int i = 0; i < books.size(); i++) {
    localbooks.push_back(books_id_to_name(language, books[i]));
  }
  combobox_set_strings(comboboxbook, localbooks);
  combobox_set_string(comboboxbook, books_id_to_name(language, reference->book_get()));
  
  // By default view changes.
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_changes), true);
}
void WindowCheckKeyterms::html_write_keyterms (HtmlWriter2& htmlwriter, unsigned int keyword_id)
{
  // Get data about the project.
  extern Settings *settings;
  ustring project = settings->genconfig.project_get();
  ProjectConfiguration *projectconfig = settings->projectconfig(project);
  ustring versification = projectconfig->versification_get();

  // Add action links.
  htmlwriter.paragraph_open ();
  htmlwriter.hyperlink_add ("index", "[Index]");
  htmlwriter.text_add (" ");
  htmlwriter.hyperlink_add ("send", _("[Send to references window]"));
  htmlwriter.paragraph_close ();

  // Add the keyterm itself.
  ustring keyterm;
  keyterms_get_term(keyword_id, keyterm);
  htmlwriter.heading_open (3);
  htmlwriter.text_add (keyterm);
  htmlwriter.heading_close();
  
  // Retrieve the renderings.
  vector <ustring> renderings;
  vector <bool> wholewords;
  vector <bool> casesensitives;
  get_renderings(renderings, wholewords, casesensitives);

  // Get the data for the keyword identifier.
  ustring dummy;
  ustring information;
  keyterms_get_data(keyword_id, dummy, information, references);

  // Divide the information into lines.
  ParseLine parseline (information);
  
  // Write the information.
  for (unsigned int i = 0; i < parseline.lines.size(); i++) {
 
    information = parseline.lines[i];
    htmlwriter.paragraph_open ();
    size_t pos = information.find (keyterms_reference_start_markup ());
    while (pos != string::npos) {
      htmlwriter.text_add (information.substr (0, pos));
      information.erase (0, pos + keyterms_reference_start_markup ().length());
      pos = information.find (keyterms_reference_end_markup ());
      if (pos != string::npos) {
        // Extract the reference.
        htmlwriter.paragraph_close ();
        ustring original_reference_text = information.substr (0, pos);
        Reference reference = get_reference (original_reference_text);
        // Remap the reference.
        {
          Mapping mapping(versification, reference.book_get());
          vector <int> chapters;
          vector <int> verses;
          mapping.original_to_me(reference.chapter_get(), reference.verse_get(), chapters, verses);
          if (!chapters.empty()) {
            reference.chapter_set(chapters[0]);
            reference.verse_set(convert_to_string (verses[0]));
          }
        }
        ustring remapped_reference_text = reference.human_readable ("");
        ustring displayed_reference_text (remapped_reference_text);
        if (remapped_reference_text != original_reference_text) {
          displayed_reference_text.append (" (");
          displayed_reference_text.append (original_reference_text);
          displayed_reference_text.append (")");
        }
        // Add the reference with hyperlink.
        htmlwriter.hyperlink_add ("goto " + remapped_reference_text, remapped_reference_text);
        information.erase (0, pos + keyterms_reference_end_markup ().length());
        // Add the reference's text.
        ustring verse = project_retrieve_verse(project, reference);
        if (verse.empty()) {
          verse.append(_("<empty>"));
        } else {
          CategorizeLine cl(verse);
          cl.remove_verse_number(reference.verse_get());
          verse = cl.verse;
        }
        htmlwriter.text_add (" ");

        // Add the verse plus markup for approved text.
        vector <size_t> startpositions;
        vector <size_t> lengths;
        size_t processposition = 0;
        if (find_renderings (verse, renderings, wholewords, casesensitives, &startpositions, &lengths)) {
          quick_sort (startpositions, lengths, 0, startpositions.size());
          // Overlapping items need to be combined to avoid crashes.
          xml_combine_overlaps (startpositions, lengths);
          for (unsigned int i = 0; i < startpositions.size(); i++) {
            htmlwriter.text_add (verse.substr (0, startpositions[i] - processposition));
            htmlwriter.bold_open();
            htmlwriter.text_add (verse.substr (startpositions[i] - processposition, lengths[i]));
            htmlwriter.bold_close();
            verse.erase (0, startpositions[i] - processposition + lengths[i]);
            processposition = startpositions[i] + lengths[i];
          }
          // Add whatever is left over of the verse. This could be the full verse in case it wasn't processed.
          htmlwriter.text_add (verse);
        }
        else
        {
        	htmlwriter.highlight_open();
        	htmlwriter.text_add (verse);
        	htmlwriter.highlight_close();
        }

        // Proceed to next.
        htmlwriter.paragraph_open ();
        pos = information.find (keyterms_reference_start_markup ());
      }
    }
    htmlwriter.text_add (information);
    htmlwriter.paragraph_close ();
  }
}
void view_parallel_references_pdf(ProjectMemory & main_project, vector < ustring > *extra_projects, vector < Reference > references, bool keep_verses_together_within_page, vector < ustring > *remarks, bool highlight)
/*
 Formats the references in "references", and highlights all words in
 "session->highlights*" and shows them in a pdf viewer.
 There is a pointer to a list of "remarks". Any remarks will be printed first.
 */
{
  // Log.
  gw_message(_("Printing parallel references"));

  // Progress system.
  ProgressWindow progresswindow(_("Printing Parallel References"), false);
  progresswindow.set_iterate(0, 1, references.size());

  // Configuration
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(main_project.name);
  ustring stylesheet = stylesheet_get_actual ();

  // Store the additional projects to print.
  vector < ustring > additional_projects;
  if (extra_projects)
    additional_projects = *extra_projects;
  settings->session.additional_printing_projects = additional_projects;

  // Prepare for mapping.
  Mapping mapping(projectconfig->versification_get(), 0);

  // The converter.
  Text2Pdf text2pdf(gw_build_filename(Directories->get_temp(), "document.pdf"), settings->genconfig.print_engine_use_intermediate_text_get());

  // Page.
  text2pdf.page_size_set(settings->genconfig.paper_width_get(), settings->genconfig.paper_height_get());
  text2pdf.page_margins_set(settings->genconfig.paper_inside_margin_get(), settings->genconfig.paper_outside_margin_get(), settings->genconfig.paper_top_margin_get(), settings->genconfig.paper_bottom_margin_get());
  text2pdf.page_one_column_only();

  // Headers.
  if (settings->genconfig.printdate_get()) {
    text2pdf.print_date_in_header();
  }
  // Font, etc., of main project.
  ustring main_font = projectconfig->editor_font_name_get();
  unsigned int main_line_spacing = projectconfig->text_line_height_get();
  if (projectconfig->editor_font_default_get()) {
    main_font.clear();
    main_line_spacing = 100;
  }
  text2pdf.set_font(main_font);
  text2pdf.set_line_spacing(main_line_spacing);
  bool main_right_to_left = projectconfig->right_to_left_get();
  text2pdf.set_right_to_left(main_right_to_left);

  // Start off with inserting any remarks.
  if (remarks) {
    for (unsigned int r = 0; r < remarks->size(); r++) {
      text2pdf.open_paragraph();
      text2pdf.paragraph_set_column_count(1);
      text2pdf.add_text(remarks->at(r));
      text2pdf.close_paragraph();
    }
  }
  // Some variables to avoid excessive session access during highlighting.
  vector < bool > highlight_casesensitives;
  vector < ustring > highlight_words;
  if (highlight) {
    for (unsigned int hl = 0; hl < settings->session.highlights.size(); hl++) {
      highlight_casesensitives.push_back(settings->session.highlights[hl].casesensitive);
      highlight_words.push_back(settings->session.highlights[hl].word);
    }
  }
  // All the projects to be put in this parallel Bible, together with
  // their related information, like mapping, fonts.
  vector < ustring > project_names;
  vector < ProjectMemory > project_memories;
  vector < Mapping > mapping_s;
  vector < ustring > fonts;
  vector < unsigned int >line_spacings;
  vector < bool > right_to_lefts;
  if (extra_projects) {
    vector < ustring > project_s_raw = *extra_projects;
    for (unsigned int i = 0; i < project_s_raw.size(); i++) {
      ProjectMemory projectmemory(project_s_raw[i], true);
      project_memories.push_back(projectmemory);
      ProjectConfiguration *projectconfig = settings->projectconfig(project_s_raw[i]);
      project_names.push_back(project_s_raw[i]);
      Mapping mapping(projectconfig->versification_get(), 0);
      mapping_s.push_back(mapping);
      ustring font = projectconfig->editor_font_name_get();
      unsigned int line_spacing = projectconfig->text_line_height_get();
      if (projectconfig->editor_font_default_get()) {
        font.clear();
        line_spacing = 100;
      }
      fonts.push_back(font);
      line_spacings.push_back(line_spacing);
      right_to_lefts.push_back(projectconfig->right_to_left_get());
    }
  }
  // Produce chunks for all references.
  for (unsigned int rf = 0; rf < references.size(); rf++) {

    // Update progress bar.
    progresswindow.iterate();

    // Whether to keep things on one page.    
    if (keep_verses_together_within_page) {
      text2pdf.open_keep_together();
    }
    // Set main font, etc.
    text2pdf.set_font(main_font);
    text2pdf.set_line_spacing(main_line_spacing);
    text2pdf.set_right_to_left(main_right_to_left);

    // Add the reference to the text.
    text2pdf.add_text(references[rf].human_readable(""));

    // Map this verse to the original, that is, to Hebrew or Greek.
    vector <int> hebrew_greek_chapters;
    vector <int> hebrew_greek_verses;
    mapping.book_change(references[rf].book);
    mapping.me_to_original(references[rf].chapter, references[rf].verse, hebrew_greek_chapters, hebrew_greek_verses);
    // Get verse text for each version.
    for (unsigned int vsn = 0; vsn <= project_names.size(); vsn++) {

      // Add the font, etc., for each project.
      ustring font(main_font);
      unsigned int line_spacing = main_line_spacing;
      bool right_to_left = main_right_to_left;
      if (vsn > 0) {
        font = fonts[vsn - 1];
        line_spacing = line_spacings[vsn - 1];
        right_to_left = right_to_lefts[vsn - 1];
      }
      text2pdf.set_font(font);
      text2pdf.set_line_spacing(line_spacing);
      text2pdf.set_right_to_left(right_to_left);

      // Get the verse text.
      ustring line;
      if (vsn == 0) {
        // First version.
        ProjectBook *projectbook = main_project.get_book_pointer(references[rf].book);
        if (projectbook) {
          ProjectChapter *projectchapter = projectbook->get_chapter_pointer(references[rf].chapter);
          if (projectchapter) {
            ProjectVerse *projectverse = projectchapter->get_verse_pointer(references[rf].verse);
            if (projectverse) {
              line = projectverse->data;
            }
          }
        }
      } else {
        // Other versions. 
        // Get mapped chapters / verses.
        line.clear();
        vector <int> mychapters;
        vector <int> myverses;
        mapping_s[vsn - 1].book_change(references[rf].book);
        mapping_s[vsn - 1].original_to_me(hebrew_greek_chapters, hebrew_greek_verses, mychapters, myverses);
        // Get text of any of the mapped verses.
        for (unsigned int mp = 0; mp < mychapters.size(); mp++) {
          // Get the verse and add it to the usfm code.
          ProjectBook *projectbook = project_memories[vsn - 1].get_book_pointer(references[rf].book);
          if (projectbook) {
            ProjectChapter *projectchapter = projectbook->get_chapter_pointer(mychapters[mp]);
            if (projectchapter) {
              ProjectVerse *projectverse = projectchapter->get_verse_pointer(convert_to_string(myverses[mp]));
              if (projectverse) {
                if (!line.empty()) 
                  line.append (" ");
                line.append (projectverse->data);
              }
            }
          }
        }
      }

      // Add the project name if there are more than one.
      if (!project_names.empty()) {
        ustring project;
        if (vsn == 0)
          project = main_project.name;
        else
          project = project_names[vsn - 1];
        text2pdf.open_paragraph();
        text2pdf.inline_set_font_size_percentage(65);
        text2pdf.add_text(project);
        text2pdf.inline_clear_font_size_percentage();
        text2pdf.add_text(" ");
      } else {
        text2pdf.open_paragraph();
      }

      // Do text replacement.
      text_replacement(line);

      // Positions in the line, and lengths to highlight.
      vector < size_t > highlight_positions;
      vector < size_t > highlight_lengths;

      // Go through all the words to highlight.
      for (unsigned int i2 = 0; i2 < highlight_casesensitives.size(); i2++) {
        // Word to highlight
        ustring highlightword;
        if (highlight_casesensitives[i2])
          highlightword = highlight_words[i2];
        else
          highlightword = highlight_words[i2].casefold();
        // Variabele s holds a shadow string.
        ustring s;
        if (highlight_casesensitives[i2])
          s = line;
        else
          s = line.casefold();
        // Find positions for highlighting.
        size_t offposition = s.find(highlightword);
        while (offposition != string::npos) {
          // Store position and length.
          highlight_positions.push_back(offposition);
          highlight_lengths.push_back(highlightword.length());
          // Look for possible next word to highlight.
          offposition = offposition + highlightword.length() + 1;
          // There is something like a bug in s.find. If the offposition
          // is greater than the length of s, then s.find will return
          // a value below offposition, instead of string::npos as is
          // expected. Workaround.
          if (offposition > s.length())
            break;
          offposition = s.find(highlightword, offposition);
        }
      }
      // Sort the positions from small to bigger.
      xml_sort_positions(highlight_positions, highlight_lengths);
      // Combine overlapping positions.
      xml_combine_overlaps(highlight_positions, highlight_lengths);

      // Insert the code for highlighting.
      for (int i = highlight_positions.size () - 1; i >= 0; i--) {
        for (int i2 = highlight_lengths.size() - 1; i2 >= 0; i2--) {
          line.insert (highlight_positions[i] + i2, INSERTION_FLAG);
        }
      }

      // Add usfm converter to the layout engine, and set various things.
      Usfm2Text usfm2text(&text2pdf, false);
      usfm2text.add_styles(usfm2xslfo_read_stylesheet(stylesheet));

      usfm2text.no_bold();
      usfm2text.no_space_before_or_after();
      usfm2text.no_new_page();
      usfm2text.add_usfm_code(line);
      usfm2text.process();
    }

    // Add a bit of space.
    text2pdf.close_paragraph();
    text2pdf.add_text(" ");
    text2pdf.close_paragraph();

    // Whether to close code keeping things on one page.    
    if (keep_verses_together_within_page) {
      text2pdf.close_keep_together();
    }
  }

  // Hide progeressbar.
  progresswindow.hide();

  // Process the data.
  text2pdf.run();

  // Display the pdf file.
  text2pdf.view();

  // Log: ready.
  gw_message(_("Ready printing the parallel references"));
}
Exemple #22
0
void mechon_mamre_action_page (HtmlWriter2& htmlwriter)
{
  htmlwriter.heading_open (3);
  htmlwriter.text_add (_("Hebrew import from Mechon Mamre"));
  htmlwriter.heading_close ();

  vector <ustring> messages;
  bool keep_going = true;

  // Locate the downloaded file.
  ustring ct005zipfilename = gw_build_filename (g_get_home_dir (), "ct005.zip");
  messages.push_back (_("Looking for file ") + ct005zipfilename);
  if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) {
    ct005zipfilename.clear();
  }
  if (ct005zipfilename.empty()) {
    ct005zipfilename = gw_build_filename (g_get_home_dir (), "Desktop", "ct005.zip");
    messages.push_back (_("Looking for file ") + ct005zipfilename);
    if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) {
      ct005zipfilename.clear();
    }
  }
  if (ct005zipfilename.empty()) {
    ct005zipfilename = gw_build_filename (g_get_home_dir (), "Downloads", "ct005.zip");
    messages.push_back (_("Looking for file ") + ct005zipfilename);
    if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) {
      ct005zipfilename.clear();
    }
  }
  if (ct005zipfilename.empty()) {
    messages.push_back (_("Can't find Hebrew input file"));
    keep_going = false;
  }
  if (keep_going) {
    messages.push_back (_("Using file ") + ct005zipfilename);
  }

  // Unpack the zipped file.
  ustring directory;
  if (keep_going) {
    directory = gw_build_filename (Directories->get_temp (), "uncompress");
    unix_rmdir (directory);
    gw_mkdir_with_parents (directory);
    if (!uncompress (ct005zipfilename, directory)) {
      messages.push_back (_("Could not unpack the file"));
      keep_going = false;
    }
    messages.push_back (_("Unpacking into folder ") + directory);
  }

  // Show the readme file.
  if (keep_going) {
    ustring readmefile = gw_build_filename (directory, "readme.txt");
    ReadText rt (readmefile, true, true);
    ustring line;
    for (unsigned int i = 0; i < rt.lines.size(); i++) {
      if (rt.lines[i].empty()) {
        if (!line.empty()) {
          messages.push_back (line);
          line.clear();
        }
      } else {
        line.append (rt.lines[i] + " ");
      }
    }
    messages.push_back (line);
  }

  // Look for the directory where all the html files reside.
  if (keep_going) {
    directory = gw_build_filename (directory, "c", "ct");
    if (!g_file_test (directory.c_str(), G_FILE_TEST_IS_DIR)) {
      messages.push_back (_("Can't find data in directory ") + directory);
    }
    messages.push_back (_("Looking for data in directory ") + directory);
  }
  
  // Get a list of the html files that have the data.
  vector <ustring> files;
  if (keep_going) {
    ReadFiles rf (directory, "c", ".htm");
    for (unsigned int i = 0; i < rf.files.size(); i++) {
      ustring filename = gw_build_filename (directory, rf.files[i]);
      // Check on a few characteristics.
      if (mechon_mamre_copyright(filename)) {
        unsigned int digitcount = digit_count_in_string(rf.files[i]);
        if ((digitcount == 3) || (digitcount == 4)) {
          files.push_back(filename);
        }
      }
    }
  }

  // Create a new Bible into which to import the data.
  ustring bible = _("Hebrew Mechon Mamre");
  if (keep_going) {
    if (project_exists (bible)) {
      messages.push_back (_("A Bible already exists by this name: ") + bible);
      keep_going = false;      
    } else {
      project_create_restore (bible, "");
      messages.push_back (_("Creating a new Bible called \"") + bible + "\"");
      // Make a couple of settings.
      extern Settings * settings;
      ProjectConfiguration * projectconfig = settings->projectconfig (bible);
      projectconfig->versification_set ("Original");
      projectconfig->editable_set (false);
      projectconfig->right_to_left_set (true);
      projectconfig->spelling_check_set (false);
    }
  }

  // Store all the chapters 0 in each book.
  if (keep_going) {
    vector <unsigned int> books = books_type_to_ids(btOldTestament);
    ProgressWindow progresswindow (_("Creating books"), false);
    progresswindow.set_iterate (0, 1, books.size());
    for (unsigned int bk = 0; bk < books.size(); bk++) {
      progresswindow.iterate ();
      vector <ustring> usfm;
      usfm.push_back ("\\id " + books_id_to_paratext (books[bk]));
      CategorizeChapterVerse ccv (usfm);      
      project_store_chapter (bible, books[bk], ccv);
    }  
  }

  // Store all the chapters.
  if (keep_going) {
    ProgressWindow progresswindow (_("Importing chapters"), false);
    progresswindow.set_iterate (0, 1, files.size());
    for (unsigned int i = 0; i < files.size(); i++) {
      progresswindow.iterate ();
      unsigned int book = 0;
      unsigned int chapter = 0;
      mechon_mamre_extract_book_chapter (files[i], book, chapter);
      vector <ustring> contents = mechon_mamre_extract_contents (files[i], chapter);
      CategorizeChapterVerse ccv (contents);
      project_store_chapter (bible, book, ccv);
      messages.push_back (_("Importing ") + books_id_to_localname (book) + " " + convert_to_string (chapter) + _(" from file ") + files[i]);
    }
  }

  // Write accumulated messages.
  htmlwriter.heading_open (3);
  if (keep_going) {
    htmlwriter.text_add (_("Success! Bible was created: ") + bible);
  } else {
    htmlwriter.text_add (_("Error!"));
  }
  htmlwriter.heading_close ();
  if (keep_going) {
    htmlwriter.paragraph_open ();
    htmlwriter.text_add (_("To view the Hebrew text, open the Bible in the editor. Optionally set the font for better display of the Hebrew text. A donation made to Mechon Mamre will support their work."));
    htmlwriter.paragraph_close ();
  }
  for (unsigned int i = 0; i < messages.size(); i++) {
    htmlwriter.paragraph_open ();
    htmlwriter.text_add (messages[i]);
    htmlwriter.paragraph_close ();
  }  
  
  // Write OK.
  htmlwriter.paragraph_open ();
  htmlwriter.hyperlink_add ("ok", _("Ok"));
  htmlwriter.paragraph_close ();
}
SelectBooksDialog::SelectBooksDialog(bool showportions, GtkWindow *parent)
/*
This dialog selects books.
This function takes the book from the project that is now open, and
the language of that project.
It then loads the books.
bookset: Indicator for the caller's relevant books.
*/
{
    // Initialize variables.
    extern Settings *settings;
    myproject = settings->genconfig.project_get();
    ProjectConfiguration *projectconfig = settings->projectconfig(myproject);
    mylanguage = projectconfig->language_get();
    myselectables = project_get_books(myproject);
    myshowportions = showportions;

    // Build dialog.
    Shortcuts shortcuts(0);

    selectbooksdialog = gtk_dialog_new();
    ustring title(_("Select books"));
    if (showportions) {
        title.append(_(" and portions"));
    }
    gtk_window_set_title(GTK_WINDOW(selectbooksdialog), title.c_str());
    gtk_window_set_transient_for(GTK_WINDOW(selectbooksdialog), parent);
    gtk_window_set_position(GTK_WINDOW(selectbooksdialog), GTK_WIN_POS_CENTER_ALWAYS); // was GTK_WIN_POS_CENTER_ON_PARENT
    gtk_window_set_modal(GTK_WINDOW(selectbooksdialog), TRUE);

    dialog_vbox1 = gtk_dialog_get_content_area (GTK_DIALOG(selectbooksdialog));
    gtk_widget_show(dialog_vbox1);

    vbox1 = gtk_vbox_new(FALSE, 0);
    gtk_widget_show(vbox1);
    gtk_box_pack_start(GTK_BOX(dialog_vbox1), vbox1, TRUE, TRUE, 0);

    hbox11 = gtk_hbox_new(FALSE, 0);
    gtk_widget_show(hbox11);
    gtk_box_pack_start(GTK_BOX(vbox1), hbox11, TRUE, TRUE, 0);

    vbox2 = gtk_vbox_new(FALSE, 0);
    gtk_widget_show(vbox2);
    gtk_box_pack_start(GTK_BOX(hbox11), vbox2, TRUE, TRUE, 0);

    labelbooks = gtk_label_new(_("Books"));
    gtk_widget_show(labelbooks);
    gtk_box_pack_start(GTK_BOX(vbox2), labelbooks, FALSE, FALSE, 0);

    shortcuts.label(labelbooks);

    scrolledwindowbooks = gtk_scrolled_window_new(NULL, NULL);
    gtk_widget_show(scrolledwindowbooks);
    gtk_box_pack_start(GTK_BOX(vbox2), scrolledwindowbooks, TRUE, TRUE, 0);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindowbooks), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindowbooks), GTK_SHADOW_IN);

    treeviewbooks = gtk_tree_view_new();
    gtk_widget_show(treeviewbooks);
    gtk_container_add(GTK_CONTAINER(scrolledwindowbooks), treeviewbooks);
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeviewbooks), FALSE);

    vbox3 = gtk_vbox_new(FALSE, 0);
    gtk_widget_show(vbox3);
    gtk_box_pack_start(GTK_BOX(hbox11), vbox3, TRUE, TRUE, 0);

    if (myshowportions) {

        labelportions = gtk_label_new(_("Portions"));
        gtk_widget_show(labelportions);
        gtk_box_pack_start(GTK_BOX(vbox3), labelportions, FALSE, FALSE, 0);

        shortcuts.label(labelportions);

        scrolledwindowportions = gtk_scrolled_window_new(NULL, NULL);
        gtk_widget_show(scrolledwindowportions);
        gtk_box_pack_start(GTK_BOX(vbox3), scrolledwindowportions, TRUE, TRUE, 0);
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindowportions), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindowportions), GTK_SHADOW_IN);

        treeviewportions = gtk_tree_view_new();
        gtk_widget_show(treeviewportions);
        gtk_container_add(GTK_CONTAINER(scrolledwindowportions), treeviewportions);
        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeviewportions), FALSE);

    }

    table1 = gtk_table_new(2, 3, FALSE);
    gtk_widget_show(table1);
    gtk_box_pack_start(GTK_BOX(vbox1), table1, FALSE, FALSE, 0);

    nobutton = gtk_button_new();
    gtk_widget_show(nobutton);
    gtk_table_attach(GTK_TABLE(table1), nobutton, 0, 1, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);

    alignment1 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_widget_show(alignment1);
    gtk_container_add(GTK_CONTAINER(nobutton), alignment1);

    hbox4 = gtk_hbox_new(FALSE, 2);
    gtk_widget_show(hbox4);
    gtk_container_add(GTK_CONTAINER(alignment1), hbox4);

    image1 = gtk_image_new_from_stock("gtk-clear", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show(image1);
    gtk_box_pack_start(GTK_BOX(hbox4), image1, FALSE, FALSE, 0);

    label6 = gtk_label_new_with_mnemonic(_("No books"));
    gtk_widget_show(label6);
    gtk_box_pack_start(GTK_BOX(hbox4), label6, FALSE, FALSE, 0);

    shortcuts.label(label6);

    otbutton = gtk_button_new();
    gtk_widget_show(otbutton);
    gtk_table_attach(GTK_TABLE(table1), otbutton, 1, 2, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);

    alignment2 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_widget_show(alignment2);
    gtk_container_add(GTK_CONTAINER(otbutton), alignment2);

    hbox5 = gtk_hbox_new(FALSE, 2);
    gtk_widget_show(hbox5);
    gtk_container_add(GTK_CONTAINER(alignment2), hbox5);

    image2 = gtk_image_new_from_stock("gtk-goto-first", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show(image2);
    gtk_box_pack_start(GTK_BOX(hbox5), image2, FALSE, FALSE, 0);

    label7 = gtk_label_new_with_mnemonic(_("Old Testament"));
    gtk_widget_show(label7);
    gtk_box_pack_start(GTK_BOX(hbox5), label7, FALSE, FALSE, 0);

    shortcuts.label(label7);

    ntbutton = gtk_button_new();
    gtk_widget_show(ntbutton);
    gtk_table_attach(GTK_TABLE(table1), ntbutton, 2, 3, 0, 1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);

    alignment3 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_widget_show(alignment3);
    gtk_container_add(GTK_CONTAINER(ntbutton), alignment3);

    hbox6 = gtk_hbox_new(FALSE, 2);
    gtk_widget_show(hbox6);
    gtk_container_add(GTK_CONTAINER(alignment3), hbox6);

    image3 = gtk_image_new_from_stock("gtk-goto-last", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show(image3);
    gtk_box_pack_start(GTK_BOX(hbox6), image3, FALSE, FALSE, 0);

    label8 = gtk_label_new_with_mnemonic(_("New Testament"));
    gtk_widget_show(label8);
    gtk_box_pack_start(GTK_BOX(hbox6), label8, FALSE, FALSE, 0);

    shortcuts.label(label8);

    otherbutton = gtk_button_new();
    gtk_widget_show(otherbutton);
    gtk_table_attach(GTK_TABLE(table1), otherbutton, 0, 1, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);

    alignment6 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_widget_show(alignment6);
    gtk_container_add(GTK_CONTAINER(otherbutton), alignment6);

    hbox9 = gtk_hbox_new(FALSE, 2);
    gtk_widget_show(hbox9);
    gtk_container_add(GTK_CONTAINER(alignment6), hbox9);

    image6 = gtk_image_new_from_stock("gtk-dialog-warning", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show(image6);
    gtk_box_pack_start(GTK_BOX(hbox9), image6, FALSE, FALSE, 0);

    label11 = gtk_label_new_with_mnemonic(_("Other books"));
    gtk_widget_show(label11);
    gtk_box_pack_start(GTK_BOX(hbox9), label11, FALSE, FALSE, 0);

    shortcuts.label(label11);

    allbutton = gtk_button_new();
    gtk_widget_show(allbutton);
    gtk_table_attach(GTK_TABLE(table1), allbutton, 1, 2, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);

    alignment4 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_widget_show(alignment4);
    gtk_container_add(GTK_CONTAINER(allbutton), alignment4);

    hbox7 = gtk_hbox_new(FALSE, 2);
    gtk_widget_show(hbox7);
    gtk_container_add(GTK_CONTAINER(alignment4), hbox7);

    image4 = gtk_image_new_from_stock("gtk-add", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show(image4);
    gtk_box_pack_start(GTK_BOX(hbox7), image4, FALSE, FALSE, 0);

    label9 = gtk_label_new_with_mnemonic(_("All books"));
    gtk_widget_show(label9);
    gtk_box_pack_start(GTK_BOX(hbox7), label9, FALSE, FALSE, 0);

    shortcuts.label(label9);

    currentbutton = gtk_button_new();
    gtk_widget_show(currentbutton);
    gtk_table_attach(GTK_TABLE(table1), currentbutton, 2, 3, 1, 2, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);

    alignment5 = gtk_alignment_new(0.5, 0.5, 0, 0);
    gtk_widget_show(alignment5);
    gtk_container_add(GTK_CONTAINER(currentbutton), alignment5);

    hbox8 = gtk_hbox_new(FALSE, 2);
    gtk_widget_show(hbox8);
    gtk_container_add(GTK_CONTAINER(alignment5), hbox8);

    image5 = gtk_image_new_from_stock("gtk-properties", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show(image5);
    gtk_box_pack_start(GTK_BOX(hbox8), image5, FALSE, FALSE, 0);

    label10 = gtk_label_new_with_mnemonic(_("Current book"));
    gtk_widget_show(label10);
    gtk_box_pack_start(GTK_BOX(hbox8), label10, FALSE, FALSE, 0);

    shortcuts.label(label10);

    dialog_action_area1 = gtk_dialog_get_action_area (GTK_DIALOG(selectbooksdialog));
    gtk_widget_show(dialog_action_area1);
    gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog_action_area1), GTK_BUTTONBOX_END);

    const gchar *helpfile;
    if (showportions) {
        helpfile = "file/print/portion";
    } else {
        helpfile = "file/print/selection";
    }
    new InDialogHelp(selectbooksdialog, NULL, &shortcuts, helpfile);

    cancelbutton = gtk_button_new_from_stock("gtk-cancel");
    gtk_widget_show(cancelbutton);
    gtk_dialog_add_action_widget(GTK_DIALOG(selectbooksdialog), cancelbutton, GTK_RESPONSE_CANCEL);
    gtk_widget_set_can_default (GTK_WIDGET (cancelbutton), true);

    shortcuts.stockbutton(cancelbutton);

    okbutton = gtk_button_new_from_stock("gtk-ok");
    gtk_widget_show(okbutton);
    gtk_dialog_add_action_widget(GTK_DIALOG(selectbooksdialog), okbutton, GTK_RESPONSE_OK);
    gtk_widget_set_can_default (GTK_WIDGET (okbutton), true);

    shortcuts.stockbutton(okbutton);

    shortcuts.process();

    g_signal_connect((gpointer) treeviewbooks, "key_press_event", G_CALLBACK(on_treeviewbooks_key_press_event), gpointer(this));
    if (myshowportions) {
        g_signal_connect((gpointer) treeviewportions, "row_activated", G_CALLBACK(on_treeviewportions_row_activated), gpointer(this));
    }
    g_signal_connect((gpointer) nobutton, "clicked", G_CALLBACK(on_nobutton_clicked), gpointer(this));
    g_signal_connect((gpointer) otbutton, "clicked", G_CALLBACK(on_otbutton_clicked), gpointer(this));
    g_signal_connect((gpointer) ntbutton, "clicked", G_CALLBACK(on_ntbutton_clicked), gpointer(this));
    g_signal_connect((gpointer) otherbutton, "clicked", G_CALLBACK(on_otherbutton_clicked), gpointer(this));
    g_signal_connect((gpointer) allbutton, "clicked", G_CALLBACK(on_allbutton_clicked), gpointer(this));
    g_signal_connect((gpointer) currentbutton, "clicked", G_CALLBACK(on_currentbutton_clicked), gpointer(this));
    g_signal_connect((gpointer) okbutton, "clicked", G_CALLBACK(on_okbutton_clicked), gpointer(this));

    gtk_widget_grab_focus(treeviewbooks);
    gtk_widget_grab_default(okbutton);

    gtk_label_set_mnemonic_widget(GTK_LABEL(labelbooks), treeviewbooks);
    if (myshowportions)
        gtk_label_set_mnemonic_widget(GTK_LABEL(labelportions), treeviewportions);

    // Storage, renderer, column and selection for books.
    {
        storebooks = gtk_list_store_new(1, G_TYPE_STRING);
        gtk_tree_view_set_model(GTK_TREE_VIEW(treeviewbooks), GTK_TREE_MODEL(storebooks));
        g_object_unref(storebooks);
        GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
        columnbooks = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewbooks), columnbooks);
        selectbooks = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviewbooks));
        gtk_tree_selection_set_mode(selectbooks, GTK_SELECTION_MULTIPLE);
    }

    // Storage, renderer, column and selection for portions.
    if (myshowportions) {
        storeportions = gtk_list_store_new(1, G_TYPE_STRING);
        gtk_tree_view_set_model(GTK_TREE_VIEW(treeviewportions), GTK_TREE_MODEL(storeportions));
        g_object_unref(storeportions);
        GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
        columnportions = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
        gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewportions), columnportions);
        selectportions = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviewportions));
        gtk_tree_selection_set_mode(selectportions, GTK_SELECTION_SINGLE);
    }
    // Load content.
    myselectables = project_get_books(myproject);
    loadbooks();
    if (myshowportions)
        loadportions();

    // Update gui.
    update_gui_event_id = 0;
    if (myshowportions) {
        update_gui_event_id = g_timeout_add_full(G_PRIORITY_DEFAULT, 100, GSourceFunc(on_update_gui_timeout), gpointer(this), NULL);
    }

    new DialogAutoScaler (selectbooksdialog, G_MAXINT);
}
void WindowShowRelatedVerses::load_webview (const gchar * url)
{
  // New url.
  active_url = url;

  // Start writing a html page.
  HtmlWriter2 htmlwriter ("");
  bool display_another_page = true;

  if (active_url.find ("keyterm ") == 0) {
    item_type = ritKeytermId;
    item_id = active_url.substr (8, 100);
    gtk_button_clicked (GTK_BUTTON (button_item));
    display_another_page = false;
  }

  else if (active_url.find ("strong ") == 0) {
    item_type = ritStrongNumber;
    item_id = active_url.substr (7, 100);
    gtk_button_clicked (GTK_BUTTON (button_item));
    display_another_page = false;
  }

  else if (active_url.find ("parallels") == 0) {
    item_type = ritParallels;
    gtk_button_clicked (GTK_BUTTON (button_item));
    display_another_page = false;
  }

  else {

    // Display the keyterms in the verse, and their renderings.
    htmlwriter.heading_open (3);
    htmlwriter.text_add (_("Keyterms in verse ") + myreference.verse);
    htmlwriter.heading_close ();
    vector <int> keyterms = keyterms_get_terms_in_verse(myreference);
    for (unsigned int i = 0; i < keyterms.size(); i++) {

      htmlwriter.paragraph_open();

      // Display the keyterm.
      ustring term;
      keyterms_get_term(keyterms[i], term);
      htmlwriter.text_add ("* ");
      ustring url = "keyterm " + convert_to_string (keyterms[i]);
      htmlwriter.hyperlink_add (url, term);
      htmlwriter.text_add (": ");

      // Display the renderings.
      vector <ustring> renderings;
      vector <bool> wholewords;
      vector <bool> casesensitives;
      ustring category;
      {
        ustring dummy1;
        vector < Reference > dummy2;
        keyterms_get_data(keyterms[i], category, dummy1, dummy2);
      }
      keyterms_retrieve_renderings(myproject, term, category, renderings, wholewords, casesensitives);
      for (unsigned int i2 = 0; i2 < renderings.size(); i2++) {
        if (i2)
          htmlwriter.text_add (", ");
        htmlwriter.text_add (renderings[i2]);
      }

      htmlwriter.paragraph_close();
    }
    
    // If there are no keyterms, mention this.
    if (keyterms.empty()) {
      htmlwriter.paragraph_open ();
      htmlwriter.text_add ("none");
      htmlwriter.paragraph_close ();
    }

    // Terms derived from the Strong's numbers in this verse.
    htmlwriter.heading_open (3);
    htmlwriter.text_add (_("Similar words in other verses"));
    htmlwriter.heading_close ();

    // Get the data.
    vector <ustring> strongs;
    vector <ustring> words;
    kjv_get_strongs_data (myreference, strongs, words);

    // Display the data.
    for (unsigned int i = 0; i < strongs.size(); i++) {
      htmlwriter.paragraph_open ();
      Parse parse (strongs[i]);
      for (unsigned int i2 = 0; i2 < parse.words.size (); i2++) {
        htmlwriter.text_add (words[i]);
        htmlwriter.text_add (" ");
        ustring url = "strong " + parse.words[i2];
        htmlwriter.hyperlink_add (url, parse.words[i2]);
      }
      htmlwriter.paragraph_close ();
    }
    
    // Parallel passages.
    vector <Reference> parallel_references;
    vector <ustring> parallel_comments;
    parallel_passages_retrieve (myreference, parallel_references, parallel_comments);
    if (!parallel_references.empty()) {
      extern Settings *settings;
      ProjectConfiguration *projectconfig = settings->projectconfig(myproject);
      ustring language = projectconfig->language_get();
      htmlwriter.heading_open (3);
      htmlwriter.text_add (_("Parallel passages"));
      htmlwriter.heading_close ();
      for (unsigned int i = 0; i < parallel_references.size(); i++) {
        htmlwriter.paragraph_open ();
        htmlwriter.text_add (parallel_references[i].human_readable (language) + " " + parallel_comments[i]);
        htmlwriter.paragraph_close ();
      }
      htmlwriter.paragraph_open ();
      htmlwriter.hyperlink_add ("parallels", _("Send to references window"));
      htmlwriter.paragraph_close ();
    }    

  }
  
  htmlwriter.finish();
  if (display_another_page) {
    // Load the page.
    webkit_web_view_load_string (WEBKIT_WEB_VIEW (webview), htmlwriter.html.c_str(), NULL, NULL, NULL);
    // Scroll to the position that possibly was stored while this url was last active.
    GtkAdjustment * adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolledwindow));
    gtk_adjustment_set_value (adjustment, scrolling_position[active_url]);
  }
}
GotoReferenceDialog::GotoReferenceDialog(unsigned int currentbook, unsigned int currentchapter, const ustring & currentverse)
{
  // Init variables
  extern Settings *settings;
  ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get());
  language = projectconfig->language_get();
  newreference = false;
  oldbook = currentbook;
  oldchapter = currentchapter;
  oldverse = currentverse;
  go_back = false;
  go_forward = false;

  Shortcuts shortcuts(0);

  gtkbuilder = gtk_builder_new ();
  gtk_builder_add_from_file (gtkbuilder, gw_build_filename (Directories->get_package_data(), "gtkbuilder.gotoreferencedialog.xml").c_str(), NULL);

  dialog = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "dialog"));
  g_signal_connect((gpointer) dialog, "key_press_event", G_CALLBACK(on_key_press_event), gpointer(this));

  notebook = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "notebook"));

  // Enter current reference into the free entry, and select it, so user can use that.
  entry_free = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "entry_free"));
  gtk_widget_grab_focus(entry_free);
  ustring ref = books_id_to_name(language, currentbook) + " " + convert_to_string(currentchapter) + ":" + currentverse;
  gtk_entry_set_text(GTK_ENTRY(entry_free), ref.c_str());
  gtk_editable_select_region(GTK_EDITABLE(entry_free), 0, -1);

  // Completion for the reference entry.
  completion_setup(entry_free, cpGoto);

  // Signals entry.
  g_signal_connect((gpointer) entry_free, "activate", G_CALLBACK(on_entry_free_activate), gpointer(this));
  
  // Aided entry widgets.
  treeview_book = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "treeview_book"));
  treeview_chapter = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "treeview_chapter"));
  treeview_verse = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "treeview_verse"));
  
  // Connect to the signals of the treeviews.
  g_signal_connect_after((gpointer) treeview_book, "move_cursor", G_CALLBACK(on_treeview_book_move_cursor), gpointer(this));
  g_signal_connect_after((gpointer) treeview_book, "row_activated", G_CALLBACK(on_treeview_book_row_activated), gpointer(this));
  g_signal_connect_after((gpointer) treeview_chapter, "move_cursor", G_CALLBACK(on_treeview_chapter_move_cursor), gpointer(this));
  g_signal_connect_after((gpointer) treeview_chapter, "row_activated", G_CALLBACK(on_treeview_chapter_row_activated), gpointer(this));
  g_signal_connect_after((gpointer) treeview_verse, "move_cursor", G_CALLBACK(on_treeview_verse_move_cursor), gpointer(this));
  g_signal_connect_after((gpointer) treeview_verse, "row_activated", G_CALLBACK(on_treeview_verse_row_activated), gpointer(this));

  // Create stores and fill the book store.
  store_book = gtk_list_store_new(1, G_TYPE_STRING);
  store_chapter = gtk_list_store_new(1, G_TYPE_STRING);
  store_verse = gtk_list_store_new(1, G_TYPE_STRING);
  vector < unsigned int >ibooks = project_get_books(settings->genconfig.project_get());
  vector < ustring > ubooks;
  for (unsigned int i = 0; i < ibooks.size(); i++)
    ubooks.push_back(books_id_to_name(language, ibooks[i]));
  listview_set_strings(treeview_book, store_book, ubooks);

  // Set the stores as models for the treeviews.
  gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_book), GTK_TREE_MODEL(store_book));
  gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_chapter), GTK_TREE_MODEL(store_chapter));
  gtk_tree_view_set_model(GTK_TREE_VIEW(treeview_verse), GTK_TREE_MODEL(store_verse));

  // Unreference the stores once, so they get destroyed with the treeview.
  g_object_unref(store_book);
  g_object_unref(store_chapter);
  g_object_unref(store_verse);

  // Text cell renderer.
  GtkCellRenderer *renderer;
  renderer = gtk_cell_renderer_text_new();

  // Columns.
  GtkTreeViewColumn *column_book;
  column_book = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_book), column_book);
  GtkTreeViewColumn *column_chapter;
  column_chapter = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_chapter), column_chapter);
  GtkTreeViewColumn *column_verse;
  column_verse = gtk_tree_view_column_new_with_attributes("", renderer, "text", 0, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_verse), column_verse);

  // Set up the selection for each of the tree views.
  GtkTreeSelection *select_book;
  select_book = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_book));
  gtk_tree_selection_set_mode(select_book, GTK_SELECTION_SINGLE);
  GtkTreeSelection *select_chapter;
  select_chapter = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_chapter));
  gtk_tree_selection_set_mode(select_chapter, GTK_SELECTION_SINGLE);
  GtkTreeSelection *select_verse;
  select_verse = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_verse));
  gtk_tree_selection_set_mode(select_verse, GTK_SELECTION_SINGLE);

  // History back.
  radiobutton_back = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "radiobutton_back"));
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_back), true);

  // History forward.
  radiobutton_forward = GTK_WIDGET (gtk_builder_get_object (gtkbuilder, "radiobutton_forward"));
 
  // Link history button.
  GSList *history_button_group = NULL;
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_back), history_button_group);
  history_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_back));
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_forward), history_button_group);
  history_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_forward));

  // Dialog action area.
  InDialogHelp * indialoghelp = new InDialogHelp(dialog, gtkbuilder, &shortcuts, NULL);
  cancelbutton = indialoghelp->cancelbutton;
  okbutton = indialoghelp->okbutton;
  gtk_widget_grab_default(okbutton);
  g_signal_connect((gpointer) okbutton, "clicked", G_CALLBACK(on_okbutton_clicked), gpointer(this));
}
void lib_finder::OnProjectHook(cbProject* project,TiXmlElement* elem,bool loading)
{
    ProjectConfiguration* Proj = GetProject(project);
    if ( loading ) Proj->XmlLoad(elem,project);
    else           Proj->XmlWrite(elem,project);
}