Logo Search packages:      
Sourcecode: bibledit version File versions  Download package

mainwindow.cpp

/*
** Copyright (C) 2003-2006 Teus Benschop.
**  
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**  
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**  
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**  
*/


#include "mainwindow.h"
#include "libraries.h"
#include "dialoglistview.h"
#include "dialogshowscript.h"
#include "constants.h"
#include "utilities.h"
#include "htmlbrowser.h"
#include "usfmtools.h"
#include "dialogreplace.h"
#include "dialoggotoreference.h"
#include <signal.h>
#include "bible.h"
#include "projectutils.h"
#include "dialogproject.h"
#include "usfm.h"
#include "dialogimporttext.h"
#include "dialogreplacing.h"
#include <gdk/gdkkeysyms.h>
#include <glib.h>
#include "dialogsearchspecial.h"
#include "referenceutils.h"
#include <config.h>
#include "references.h"
#include "pdfviewer.h"
#include "printreferences.h"
#include "notes_utils.h"
#include "dialogfindnote.h"
#include "dialogimportnotes.h"
#include "date_time_utils.h"
#include "dialognotes.h"
#include "dialogentry.h"
#include "projectutils.h"
#include "directories.h"
#include "dialogcompare.h"
#include "export_utils.h"
#include "dialogprintprefs.h"
#include "dialogprintproject.h"
#include "dialogeditextramatter.h"
#include "printproject.h"
#include "formatter.h"
#include "dialogformatter.h"
#include "compareutils.h"
#include "dialogexportnotes.h"
#include "dialogshownotes.h"
#include "dialogentry3.h"
#include "gwrappers.h"
#include "gtkwrappers.h"
#include "search_utils.h"
#include "combobox.h"
#include "scripturechecks.h"
#include "dialogrefexchange.h"
#include "dialogeditlist.h"
#include <sqlite3.h>
#include "sqlite_reader.h"
#include "highlight.h"
#include "fonts.h"
#include "dialogfont.h"
#include "styletree.h"
#include "dialogopenstylesheet.h"
#include "stylesheetutils.h"
#include "dialogstylesheet.h"
#include "keyboard.h"
#include "dialoginsertnote.h"
#include "dialogparallelbible.h"
#include "print_parallel_bible.h"
#include "editor.h"
#include "dialogscreenlayout.h"
#include "layout.h"
#include "dialogbook.h"
#include "synchronize.h"
#include "dialogsynchronization.h"
#include "books.h"
#include "screen.h"
#include "projectconfig.h"
#include "dialogsynchronize.h"
#include "dialoglinecutter.h"


/*
|
|
|
|
|
Construction and destruction
|
|
|
|
|
 */


MainWindow::MainWindow (SplashScreen * splashscreen):
editor (0),
track (0),
//backup (0), 
session (0),
undo (0), 
windowsoutpost (true), 
bibletime (true)
{
  splashscreen->percentage (30);

  accel_group = gtk_accel_group_new ();

  mainwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  set_titlebar ("");
  gtk_window_set_default_size (GTK_WINDOW (mainwindow), 800, 600);
  gtk_window_set_default_icon_from_file (gw_build_filename (PACKAGE_DATA_DIR, "icon.xpm").c_str(), NULL);

  g_set_application_name ("Bibledit");

  // Screen Dimensions.
  ScreenDimensions screendimensions (GTK_WINDOW (mainwindow));
  
  // Initialize configuration.
  genconfig = new GeneralConfiguration (0);
  
  // Time Bibledit started.
  genconfig->startup_time_set (time(0));

  // Start Outpost.
  windowsoutpost.Start ();

  // Size and position of the main window.
  screen_layout_window_size_load (mainwindow);

  vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox1);
  gtk_container_add (GTK_CONTAINER (mainwindow), vbox1);

  menubar1 = gtk_menu_bar_new ();
  gtk_widget_show (menubar1);
  gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);

  menuitem_file = gtk_menu_item_new_with_mnemonic ("_File");
  gtk_widget_show (menuitem_file);
  gtk_container_add (GTK_CONTAINER (menubar1), menuitem_file);

  menuitem_file_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_file), menuitem_file_menu);

  file_project = gtk_image_menu_item_new_with_mnemonic ("_Project");
  gtk_widget_show (file_project);
  gtk_container_add (GTK_CONTAINER (menuitem_file_menu), file_project);

  image463 = gtk_image_new_from_stock ("gtk-index", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image463);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (file_project), image463);

  file_project_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_project), file_project_menu);

  new1 = gtk_image_menu_item_new_with_mnemonic ("_New");
  gtk_widget_show (new1);
  gtk_container_add (GTK_CONTAINER (file_project_menu), new1);

  image903 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image903);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new1), image903);

  open1 = gtk_image_menu_item_new_from_stock ("gtk-open", accel_group);
  gtk_widget_show (open1);
  gtk_container_add (GTK_CONTAINER (file_project_menu), open1);

  close1 = gtk_image_menu_item_new_from_stock ("gtk-close", accel_group);
  gtk_widget_show (close1);
  gtk_container_add (GTK_CONTAINER (file_project_menu), close1);

  delete1 = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
  gtk_widget_show (delete1);
  gtk_container_add (GTK_CONTAINER (file_project_menu), delete1);

  print_project = gtk_image_menu_item_new_with_mnemonic ("_Print");
  gtk_widget_show (print_project);
  gtk_container_add (GTK_CONTAINER (file_project_menu), print_project);

  image805 = gtk_image_new_from_stock ("gtk-print", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image805);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (print_project), image805);

  properties1 = gtk_image_menu_item_new_with_mnemonic ("P_roperties");
  gtk_widget_show (properties1);
  gtk_container_add (GTK_CONTAINER (file_project_menu), properties1);

  image4995 = gtk_image_new_from_stock ("gtk-properties", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image4995);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (properties1), image4995);

  import1 = gtk_image_menu_item_new_with_mnemonic ("_Import");
  gtk_widget_show (import1);
  gtk_container_add (GTK_CONTAINER (file_project_menu), import1);

  image464 = gtk_image_new_from_stock ("gtk-convert", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image464);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (import1), image464);

  export_project = gtk_image_menu_item_new_with_mnemonic ("_Export");
  gtk_widget_show (export_project);
  gtk_container_add (GTK_CONTAINER (file_project_menu), export_project);

  image3298 = gtk_image_new_from_stock ("gtk-convert", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image3298);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (export_project), image3298);

  export_project_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (export_project), export_project_menu);

  export_usfm_files = gtk_image_menu_item_new_with_mnemonic ("_Unified Standard Format Markers files");
  gtk_widget_show (export_usfm_files);
  gtk_container_add (GTK_CONTAINER (export_project_menu), export_usfm_files);

  image12814 = gtk_image_new_from_stock ("gtk-convert", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image12814);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (export_usfm_files), image12814);

  to_bibleworks_version_database_compiler = gtk_image_menu_item_new_with_mnemonic ("_BibleWorks Version Database Compiler");
  gtk_widget_show (to_bibleworks_version_database_compiler);
  gtk_container_add (GTK_CONTAINER (export_project_menu), to_bibleworks_version_database_compiler);

  image3299 = gtk_image_new_from_stock ("gtk-convert", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image3299);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (to_bibleworks_version_database_compiler), image3299);

  export_to_sword_module = gtk_image_menu_item_new_with_mnemonic ("_SWORD module");
  gtk_widget_show (export_to_sword_module);
  gtk_container_add (GTK_CONTAINER (export_project_menu), export_to_sword_module);

  image11392 = gtk_image_new_from_stock ("gtk-convert", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image11392);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (export_to_sword_module), image11392);

  copy_project_to = gtk_image_menu_item_new_with_mnemonic ("Cop_y to");
  gtk_widget_show (copy_project_to);
  gtk_container_add (GTK_CONTAINER (file_project_menu), copy_project_to);

  image2688 = gtk_image_new_from_stock ("gtk-copy", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image2688);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (copy_project_to), image2688);

  compare_with1 = gtk_image_menu_item_new_with_mnemonic ("Co_mpare with");
  gtk_widget_show (compare_with1);
  gtk_container_add (GTK_CONTAINER (file_project_menu), compare_with1);

  image2764 = gtk_image_new_from_stock ("gtk-zoom-fit", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image2764);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (compare_with1), image2764);

  parallel_bible = gtk_image_menu_item_new_with_mnemonic ("P_arallel Bible");
  gtk_widget_show (parallel_bible);
  gtk_container_add (GTK_CONTAINER (file_project_menu), parallel_bible);

  image11566 = gtk_image_new_from_stock ("gtk-copy", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image11566);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (parallel_bible), image11566);

  synchronize_projects = gtk_image_menu_item_new_with_mnemonic ("_Synchronize");
  gtk_widget_show (synchronize_projects);
  gtk_container_add (GTK_CONTAINER (file_project_menu), synchronize_projects);

  image12270 = gtk_image_new_from_stock ("gtk-refresh", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image12270);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (synchronize_projects), image12270);

  file_references = gtk_image_menu_item_new_with_mnemonic ("_References");
  gtk_widget_show (file_references);
  gtk_container_add (GTK_CONTAINER (menuitem_file_menu), file_references);

  image465 = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image465);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (file_references), image465);

  file_references_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_references), file_references_menu);

  open_references1 = gtk_image_menu_item_new_with_mnemonic ("_Open");
  gtk_widget_show (open_references1);
  gtk_container_add (GTK_CONTAINER (file_references_menu), open_references1);

  image466 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image466);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (open_references1), image466);

  references_save_as = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
  gtk_widget_show (references_save_as);
  gtk_container_add (GTK_CONTAINER (file_references_menu), references_save_as);

  print_references = gtk_image_menu_item_new_with_mnemonic ("_Print");
  gtk_widget_show (print_references);
  gtk_container_add (GTK_CONTAINER (file_references_menu), print_references);
  gtk_widget_add_accelerator (print_references, "activate", accel_group,
                              GDK_P, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image759 = gtk_image_new_from_stock ("gtk-print", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image759);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (print_references), image759);

  close_references = gtk_image_menu_item_new_with_mnemonic ("_Close");
  gtk_widget_show (close_references);
  gtk_container_add (GTK_CONTAINER (file_references_menu), close_references);

  image468 = gtk_image_new_from_stock ("gtk-close", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image468);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (close_references), image468);

  delete_references = gtk_image_menu_item_new_with_mnemonic ("_Delete");
  gtk_widget_show (delete_references);
  gtk_container_add (GTK_CONTAINER (file_references_menu), delete_references);

  image469 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image469);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (delete_references), image469);

  reference_hide = gtk_image_menu_item_new_with_mnemonic ("_Hide from now on");
  gtk_widget_show (reference_hide);
  gtk_container_add (GTK_CONTAINER (file_references_menu), reference_hide);

  image6483 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image6483);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (reference_hide), image6483);

  style = gtk_image_menu_item_new_with_mnemonic ("_Styles");
  gtk_widget_show (style);
  gtk_container_add (GTK_CONTAINER (menuitem_file_menu), style);

  image10735 = gtk_image_new_from_stock ("gtk-print-preview", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10735);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (style), image10735);

  style_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (style), style_menu);

  stylesheets_expand_all = gtk_image_menu_item_new_with_mnemonic ("_Expand all");
  gtk_widget_show (stylesheets_expand_all);
  gtk_container_add (GTK_CONTAINER (style_menu), stylesheets_expand_all);

  image10736 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10736);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheets_expand_all), image10736);

  stylesheets_collapse_all = gtk_image_menu_item_new_with_mnemonic ("_Collapse all");
  gtk_widget_show (stylesheets_collapse_all);
  gtk_container_add (GTK_CONTAINER (style_menu), stylesheets_collapse_all);

  image10737 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10737);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheets_collapse_all), image10737);

  style_insert = gtk_image_menu_item_new_with_mnemonic ("_Insert");
  gtk_widget_show (style_insert);
  gtk_container_add (GTK_CONTAINER (style_menu), style_insert);

  image10738 = gtk_image_new_from_stock ("gtk-paste", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10738);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (style_insert), image10738);

  stylesheet_edit_mode = gtk_check_menu_item_new_with_mnemonic ("Edit _mode");
  gtk_widget_show (stylesheet_edit_mode);
  gtk_container_add (GTK_CONTAINER (style_menu), stylesheet_edit_mode);

  style_new = gtk_image_menu_item_new_with_mnemonic ("_New");
  gtk_widget_show (style_new);
  gtk_container_add (GTK_CONTAINER (style_menu), style_new);

  image10739 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10739);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (style_new), image10739);

  style_properties = gtk_image_menu_item_new_from_stock ("gtk-properties", accel_group);
  gtk_widget_show (style_properties);
  gtk_container_add (GTK_CONTAINER (style_menu), style_properties);

  style_delete = gtk_image_menu_item_new_from_stock ("gtk-delete", accel_group);
  gtk_widget_show (style_delete);
  gtk_container_add (GTK_CONTAINER (style_menu), style_delete);

  menu_stylesheet = gtk_image_menu_item_new_with_mnemonic ("_Stylesheet");
  gtk_widget_show (menu_stylesheet);
  gtk_container_add (GTK_CONTAINER (style_menu), menu_stylesheet);

  image10740 = gtk_image_new_from_stock ("gtk-print-preview", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10740);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_stylesheet), image10740);

  menu_stylesheet_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_stylesheet), menu_stylesheet_menu);

  stylesheet_switch = gtk_image_menu_item_new_with_mnemonic ("_Switch");
  gtk_widget_show (stylesheet_switch);
  gtk_container_add (GTK_CONTAINER (menu_stylesheet_menu), stylesheet_switch);

  image10741 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10741);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheet_switch), image10741);

  stylesheets_new = gtk_image_menu_item_new_with_mnemonic ("_New");
  gtk_widget_show (stylesheets_new);
  gtk_container_add (GTK_CONTAINER (menu_stylesheet_menu), stylesheets_new);

  image10742 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10742);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheets_new), image10742);

  stylesheets_delete = gtk_image_menu_item_new_with_mnemonic ("_Delete");
  gtk_widget_show (stylesheets_delete);
  gtk_container_add (GTK_CONTAINER (menu_stylesheet_menu), stylesheets_delete);

  image10743 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10743);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheets_delete), image10743);

  stylesheets_rename = gtk_image_menu_item_new_with_mnemonic ("_Rename");
  gtk_widget_show (stylesheets_rename);
  gtk_container_add (GTK_CONTAINER (menu_stylesheet_menu), stylesheets_rename);

  image10744 = gtk_image_new_from_stock ("gtk-redo", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10744);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheets_rename), image10744);

  stylesheets_import = gtk_image_menu_item_new_with_mnemonic ("_Import");
  gtk_widget_show (stylesheets_import);
  gtk_container_add (GTK_CONTAINER (menu_stylesheet_menu), stylesheets_import);

  image10745 = gtk_image_new_from_stock ("gtk-network", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10745);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheets_import), image10745);

  stylesheets_export = gtk_image_menu_item_new_with_mnemonic ("_Export");
  gtk_widget_show (stylesheets_export);
  gtk_container_add (GTK_CONTAINER (menu_stylesheet_menu), stylesheets_export);

  image10746 = gtk_image_new_from_stock ("gtk-network", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10746);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (stylesheets_export), image10746);

  notes2 = gtk_image_menu_item_new_with_mnemonic ("Project _notes");
  gtk_widget_show (notes2);
  gtk_container_add (GTK_CONTAINER (menuitem_file_menu), notes2);

  image936 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image936);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (notes2), image936);

  notes2_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (notes2), notes2_menu);

  new_note = gtk_image_menu_item_new_from_stock ("gtk-new", accel_group);
  gtk_widget_show (new_note);
  gtk_container_add (GTK_CONTAINER (notes2_menu), new_note);

  delete_note = gtk_image_menu_item_new_with_mnemonic ("_Delete");
  gtk_widget_show (delete_note);
  gtk_container_add (GTK_CONTAINER (notes2_menu), delete_note);

  image963 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image963);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (delete_note), image963);

  import_notes = gtk_image_menu_item_new_with_mnemonic ("_Import");
  gtk_widget_show (import_notes);
  gtk_container_add (GTK_CONTAINER (notes2_menu), import_notes);

  image1455 = gtk_image_new_from_stock ("gtk-convert", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image1455);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (import_notes), image1455);

  export_notes = gtk_image_menu_item_new_with_mnemonic ("_Export");
  gtk_widget_show (export_notes);
  gtk_container_add (GTK_CONTAINER (notes2_menu), export_notes);

  image4068 = gtk_image_new_from_stock ("gtk-convert", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image4068);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (export_notes), image4068);

  quit1 = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
  gtk_widget_show (quit1);
  gtk_container_add (GTK_CONTAINER (menuitem_file_menu), quit1);

  menuitem_edit = gtk_menu_item_new_with_mnemonic ("_Edit");
  gtk_widget_show (menuitem_edit);
  gtk_container_add (GTK_CONTAINER (menubar1), menuitem_edit);

  menuitem_edit_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_edit), menuitem_edit_menu);

  cut1 = gtk_image_menu_item_new_from_stock ("gtk-cut", accel_group);
  gtk_widget_show (cut1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), cut1);

  copy1 = gtk_image_menu_item_new_from_stock ("gtk-copy", accel_group);
  gtk_widget_show (copy1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), copy1);

  paste1 = gtk_image_menu_item_new_from_stock ("gtk-paste", accel_group);
  gtk_widget_show (paste1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), paste1);

  separator2 = gtk_separator_menu_item_new ();
  gtk_widget_show (separator2);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), separator2);
  gtk_widget_set_sensitive (separator2, FALSE);

  undo1 = gtk_image_menu_item_new_with_mnemonic ("_Undo");
  gtk_widget_show (undo1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), undo1);
  gtk_widget_add_accelerator (undo1, "activate", accel_group, GDK_Z, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image295 = gtk_image_new_from_stock ("gtk-undo", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image295);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (undo1), image295);

  redo1 = gtk_image_menu_item_new_with_mnemonic ("_Redo");
  gtk_widget_show (redo1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), redo1);
  gtk_widget_add_accelerator (redo1, "activate", accel_group, GDK_Z,
                              GdkModifierType (GDK_CONTROL_MASK | GDK_SHIFT_MASK),
                              GTK_ACCEL_VISIBLE);

  image296 = gtk_image_new_from_stock ("gtk-redo", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image296);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (redo1), image296);

  separator4 = gtk_separator_menu_item_new ();
  gtk_widget_show (separator4);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), separator4);
  gtk_widget_set_sensitive (separator4, FALSE);

  find1 = gtk_image_menu_item_new_from_stock ("gtk-find", accel_group);
  gtk_widget_show (find1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), find1);

  find_and_replace1 = gtk_image_menu_item_new_from_stock ("gtk-find-and-replace", accel_group);
  gtk_widget_show (find_and_replace1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), find_and_replace1);

  find_in_notes1 = gtk_image_menu_item_new_with_mnemonic ("Find in Project _notes");
  gtk_widget_show (find_in_notes1);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), find_in_notes1);

  image1430 = gtk_image_new_from_stock ("gtk-find", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image1430);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (find_in_notes1), image1430);

  separator7 = gtk_separator_menu_item_new ();
  gtk_widget_show (separator7);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), separator7);
  gtk_widget_set_sensitive (separator7, FALSE);

  get_references_from_note = gtk_image_menu_item_new_with_mnemonic ("_Get references from project note");
  gtk_widget_show (get_references_from_note);
  gtk_container_add (GTK_CONTAINER (menuitem_edit_menu), get_references_from_note);

  image3158 = gtk_image_new_from_stock ("gtk-index", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image3158);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (get_references_from_note), image3158);

  menuitem_view = gtk_menu_item_new_with_mnemonic ("_View");
  gtk_widget_show (menuitem_view);
  gtk_container_add (GTK_CONTAINER (menubar1), menuitem_view);

  menuitem_view_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_view), menuitem_view_menu);

  screen_font = gtk_image_menu_item_new_with_mnemonic ("_Screen font");
  gtk_widget_show (screen_font);
  gtk_container_add (GTK_CONTAINER (menuitem_view_menu), screen_font);

  image8005 = gtk_image_new_from_stock ("gtk-select-font", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image8005);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (screen_font), image8005);

  printer_font = gtk_image_menu_item_new_with_mnemonic ("_Printer font");
  gtk_widget_show (printer_font);
  gtk_container_add (GTK_CONTAINER (menuitem_view_menu), printer_font);

  image8006 = gtk_image_new_from_stock ("gtk-select-font", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image8006);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (printer_font), image8006);

  viewnotes = gtk_image_menu_item_new_with_mnemonic ("Project _notes");
  gtk_widget_show (viewnotes);
  gtk_container_add (GTK_CONTAINER (menuitem_view_menu), viewnotes);

  image2627 = gtk_image_new_from_stock ("gtk-index", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image2627);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewnotes), image2627);

  screen_layout = gtk_image_menu_item_new_with_mnemonic ("Screen _layout");
  gtk_widget_show (screen_layout);
  gtk_container_add (GTK_CONTAINER (menuitem_view_menu), screen_layout);

  image11944 = gtk_image_new_from_stock ("gtk-justify-fill", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image11944);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (screen_layout), image11944);

  insert1 = gtk_menu_item_new_with_mnemonic ("_Insert");
  gtk_widget_show (insert1);
  gtk_container_add (GTK_CONTAINER (menubar1), insert1);

  insert1_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (insert1), insert1_menu);

  standard_text_1 = gtk_image_menu_item_new_with_mnemonic ("Standard text _1");
  gtk_widget_show (standard_text_1);
  gtk_container_add (GTK_CONTAINER (insert1_menu), standard_text_1);
  gtk_widget_add_accelerator (standard_text_1, "activate", accel_group,
                              GDK_1, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image1963 = gtk_image_new_from_stock ("gtk-paste", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image1963);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (standard_text_1), image1963);

  standard_text_2 = gtk_image_menu_item_new_with_mnemonic ("Standard text _2");
  gtk_widget_show (standard_text_2);
  gtk_container_add (GTK_CONTAINER (insert1_menu), standard_text_2);
  gtk_widget_add_accelerator (standard_text_2, "activate", accel_group,
                              GDK_2, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image1964 = gtk_image_new_from_stock ("gtk-paste", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image1964);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (standard_text_2), image1964);

  standard_text_3 = gtk_image_menu_item_new_with_mnemonic ("Standard text _3");
  gtk_widget_show (standard_text_3);
  gtk_container_add (GTK_CONTAINER (insert1_menu), standard_text_3);
  gtk_widget_add_accelerator (standard_text_3, "activate", accel_group,
                              GDK_3, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image1965 = gtk_image_new_from_stock ("gtk-paste", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image1965);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (standard_text_3), image1965);

  standard_text_4 = gtk_image_menu_item_new_with_mnemonic ("Standard text _4");
  gtk_widget_show (standard_text_4);
  gtk_container_add (GTK_CONTAINER (insert1_menu), standard_text_4);
  gtk_widget_add_accelerator (standard_text_4, "activate", accel_group,
                              GDK_4, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image1966 = gtk_image_new_from_stock ("gtk-paste", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image1966);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (standard_text_4), image1966);

  separator9 = gtk_separator_menu_item_new ();
  gtk_widget_show (separator9);
  gtk_container_add (GTK_CONTAINER (insert1_menu), separator9);
  gtk_widget_set_sensitive (separator9, FALSE);

  current_reference1 = gtk_image_menu_item_new_with_mnemonic ("_Current reference");
  gtk_widget_show (current_reference1);
  gtk_container_add (GTK_CONTAINER (insert1_menu), current_reference1);

  image3797 = gtk_image_new_from_stock ("gtk-paste", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image3797);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (current_reference1), image3797);

  separator13 = gtk_separator_menu_item_new ();
  gtk_widget_show (separator13);
  gtk_container_add (GTK_CONTAINER (insert1_menu), separator13);
  gtk_widget_set_sensitive (separator13, FALSE);

  insert_footnote = gtk_image_menu_item_new_with_mnemonic ("_Footnote");
  gtk_widget_show (insert_footnote);
  gtk_container_add (GTK_CONTAINER (insert1_menu), insert_footnote);

  image10927 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10927);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_footnote), image10927);

  insert_endnote = gtk_image_menu_item_new_with_mnemonic ("_Endnote");
  gtk_widget_show (insert_endnote);
  gtk_container_add (GTK_CONTAINER (insert1_menu), insert_endnote);

  image10928 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10928);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_endnote), image10928);

  insert_crossreference = gtk_image_menu_item_new_with_mnemonic ("Cross_reference");
  gtk_widget_show (insert_crossreference);
  gtk_container_add (GTK_CONTAINER (insert1_menu), insert_crossreference);

  image10929 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image10929);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_crossreference), image10929);

  menuitem_goto = gtk_menu_item_new_with_mnemonic ("_Goto");
  gtk_widget_show (menuitem_goto);
  gtk_container_add (GTK_CONTAINER (menubar1), menuitem_goto);

  menuitem_goto_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_goto), menuitem_goto_menu);

  next_verse1 = gtk_image_menu_item_new_with_mnemonic ("Next verse");
  gtk_widget_show (next_verse1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), next_verse1);
  gtk_widget_add_accelerator (next_verse1, "activate", accel_group, GDK_F9, GdkModifierType (0),
                              GTK_ACCEL_VISIBLE);
  // The GdkModifierType was given as 0 by glade's code, but that did not compile.
  // Here we take that 0 and cast it to a GdkModifierType. That works well.

  image95 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image95);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (next_verse1), image95);

  previous_verse1 = gtk_image_menu_item_new_with_mnemonic ("Previous verse");
  gtk_widget_show (previous_verse1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), previous_verse1);
  gtk_widget_add_accelerator (previous_verse1, "activate", accel_group, GDK_F9, GDK_SHIFT_MASK,
                              GTK_ACCEL_VISIBLE);

  image96 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image96);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (previous_verse1), image96);

  next_chapter1 = gtk_image_menu_item_new_with_mnemonic ("Next chapter");
  gtk_widget_show (next_chapter1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), next_chapter1);
  gtk_widget_add_accelerator (next_chapter1, "activate", accel_group, GDK_F8, GdkModifierType (0),
                              GTK_ACCEL_VISIBLE);

  image97 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image97);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (next_chapter1), image97);

  previous_chapter1 = gtk_image_menu_item_new_with_mnemonic ("Previous chapter");
  gtk_widget_show (previous_chapter1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), previous_chapter1);
  gtk_widget_add_accelerator (previous_chapter1, "activate", accel_group, GDK_F8, GDK_SHIFT_MASK,
                              GTK_ACCEL_VISIBLE);

  image98 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image98);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (previous_chapter1), image98);

  next_book1 = gtk_image_menu_item_new_with_mnemonic ("Next book");
  gtk_widget_show (next_book1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), next_book1);
  gtk_widget_add_accelerator (next_book1, "activate", accel_group, GDK_F7, GdkModifierType (0),
                              GTK_ACCEL_VISIBLE);

  image99 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image99);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (next_book1), image99);

  previous_book1 = gtk_image_menu_item_new_with_mnemonic ("Previous book");
  gtk_widget_show (previous_book1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), previous_book1);
  gtk_widget_add_accelerator (previous_book1, "activate", accel_group, GDK_F7, GDK_SHIFT_MASK,
                              GTK_ACCEL_VISIBLE);

  image100 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image100);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (previous_book1), image100);

  next_reference1 = gtk_image_menu_item_new_with_mnemonic ("Next reference");
  gtk_widget_show (next_reference1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), next_reference1);
  gtk_widget_add_accelerator (next_reference1, "activate", accel_group, GDK_F6, GdkModifierType (0),
                              GTK_ACCEL_VISIBLE);

  image608 = gtk_image_new_from_stock ("gtk-go-down", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image608);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (next_reference1), image608);

  previous_reference1 = gtk_image_menu_item_new_with_mnemonic ("Previous reference");
  gtk_widget_show (previous_reference1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), previous_reference1);
  gtk_widget_add_accelerator (previous_reference1, "activate", accel_group, GDK_F6, GDK_SHIFT_MASK,
                              GTK_ACCEL_VISIBLE);

  image609 = gtk_image_new_from_stock ("gtk-go-up", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image609);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (previous_reference1), image609);

  next_reference_in_history1 = gtk_image_menu_item_new_with_mnemonic ("Next reference in history");
  gtk_widget_show (next_reference_in_history1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), next_reference_in_history1);
  gtk_widget_add_accelerator (next_reference_in_history1, "activate", accel_group,
                              GDK_Right, GDK_MOD1_MASK,
                              GTK_ACCEL_VISIBLE);

  image5687 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image5687);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (next_reference_in_history1), image5687);

  previous_reference_in_history1 = gtk_image_menu_item_new_with_mnemonic ("Previous reference in history");
  gtk_widget_show (previous_reference_in_history1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), previous_reference_in_history1);
  gtk_widget_add_accelerator (previous_reference_in_history1, "activate", accel_group,
                              GDK_Left, GDK_MOD1_MASK,
                              GTK_ACCEL_VISIBLE);

  image5688 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image5688);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (previous_reference_in_history1), image5688);

  reference1 = gtk_image_menu_item_new_with_mnemonic ("Reference");
  gtk_widget_show (reference1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), reference1);
  gtk_widget_add_accelerator (reference1, "activate", accel_group, GDK_g, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image101 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image101);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (reference1), image101);

  text_area1 = gtk_image_menu_item_new_with_mnemonic ("Text area");
  gtk_widget_show (text_area1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), text_area1);
  gtk_widget_add_accelerator (text_area1, "activate", accel_group,
                              GDK_F5, GdkModifierType (0),
                              GTK_ACCEL_VISIBLE);

  image4721 = gtk_image_new_from_stock ("gtk-home", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image4721);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (text_area1), image4721);

  goto_bible_notes_area1 = gtk_image_menu_item_new_with_mnemonic ("Bible notes area");
  gtk_widget_show (goto_bible_notes_area1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), goto_bible_notes_area1);
  gtk_widget_add_accelerator (goto_bible_notes_area1, "activate", accel_group,
                              GDK_F5, GdkModifierType (GDK_CONTROL_MASK | GDK_SHIFT_MASK),
                              GTK_ACCEL_VISIBLE);

  image11878 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image11878);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (goto_bible_notes_area1), image11878);

  references_area1 = gtk_image_menu_item_new_with_mnemonic ("Tools area");
  gtk_widget_show (references_area1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), references_area1);
  gtk_widget_add_accelerator (references_area1, "activate", accel_group,
                              GDK_F5, GDK_SHIFT_MASK,
                              GTK_ACCEL_VISIBLE);

  image4722 = gtk_image_new_from_stock ("gtk-jump-to", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image4722);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (references_area1), image4722);

  insert_style = gtk_image_menu_item_new_with_mnemonic ("Styles area");
  gtk_widget_show (insert_style);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), insert_style);
  gtk_widget_add_accelerator (insert_style, "activate", accel_group,
                              GDK_S, (GdkModifierType) GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image11111 = gtk_image_new_from_stock ("gtk-print-preview", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image11111);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (insert_style), image11111);

  notes_area1 = gtk_image_menu_item_new_with_mnemonic ("Project notes area");
  gtk_widget_show (notes_area1);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), notes_area1);
  gtk_widget_add_accelerator (notes_area1, "activate", accel_group,
                              GDK_F5, GDK_CONTROL_MASK,
                              GTK_ACCEL_VISIBLE);

  image4723 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image4723);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (notes_area1), image4723);

  separator11 = gtk_separator_menu_item_new ();
  gtk_widget_show (separator11);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), separator11);
  gtk_widget_set_sensitive (separator11, FALSE);

  synchronize_other_programs2 = gtk_image_menu_item_new_with_mnemonic ("_Synchronize other programs");
  gtk_widget_show (synchronize_other_programs2);
  gtk_container_add (GTK_CONTAINER (menuitem_goto_menu), synchronize_other_programs2);

  image4931 = gtk_image_new_from_stock ("gtk-execute", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image4931);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (synchronize_other_programs2), image4931);

  check1 = gtk_menu_item_new_with_mnemonic ("Chec_k");
  gtk_widget_show (check1);
  gtk_container_add (GTK_CONTAINER (menubar1), check1);

  check1_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (check1), check1_menu);

  chapters_and_verses1 = gtk_image_menu_item_new_with_mnemonic ("_Chapters and verses");
  gtk_widget_show (chapters_and_verses1);
  gtk_container_add (GTK_CONTAINER (check1_menu), chapters_and_verses1);

  image5580 = gtk_image_new_from_stock ("gtk-zoom-100", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image5580);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (chapters_and_verses1), image5580);

  markers1 = gtk_image_menu_item_new_with_mnemonic ("_Markers");
  gtk_widget_show (markers1);
  gtk_container_add (GTK_CONTAINER (check1_menu), markers1);

  image5578 = gtk_image_new_from_stock ("gtk-zoom-100", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image5578);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (markers1), image5578);

  markers1_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (markers1), markers1_menu);

  validate_usfms1 = gtk_image_menu_item_new_with_mnemonic ("_Validate");
  gtk_widget_show (validate_usfms1);
  gtk_container_add (GTK_CONTAINER (markers1_menu), validate_usfms1);

  image5579 = gtk_image_new_from_stock ("gtk-ok", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image5579);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (validate_usfms1), image5579);

  count_usfms1 = gtk_image_menu_item_new_with_mnemonic ("_Count");
  gtk_widget_show (count_usfms1);
  gtk_container_add (GTK_CONTAINER (markers1_menu), count_usfms1);

  image6239 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image6239);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (count_usfms1), image6239);

  compare_usfm1 = gtk_image_menu_item_new_with_mnemonic ("C_ompare");
  gtk_widget_show (compare_usfm1);
  gtk_container_add (GTK_CONTAINER (markers1_menu), compare_usfm1);

  image6748 = gtk_image_new_from_stock ("gtk-zoom-fit", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image6748);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (compare_usfm1), image6748);

  characters1 = gtk_image_menu_item_new_with_mnemonic ("C_haracters");
  gtk_widget_show (characters1);
  gtk_container_add (GTK_CONTAINER (check1_menu), characters1);

  image6867 = gtk_image_new_from_stock ("gtk-zoom-100", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image6867);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (characters1), image6867);

  characters1_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (characters1), characters1_menu);

  count_characters = gtk_image_menu_item_new_with_mnemonic ("_Inventory");
  gtk_widget_show (count_characters);
  gtk_container_add (GTK_CONTAINER (characters1_menu), count_characters);

  image6868 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image6868);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (count_characters), image6868);

  unwanted_patterns = gtk_image_menu_item_new_with_mnemonic ("_Unwanted patterns");
  gtk_widget_show (unwanted_patterns);
  gtk_container_add (GTK_CONTAINER (characters1_menu), unwanted_patterns);

  image7494 = gtk_image_new_from_stock ("gtk-clear", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image7494);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (unwanted_patterns), image7494);

  check_words = gtk_image_menu_item_new_with_mnemonic ("_Words");
  gtk_widget_show (check_words);
  gtk_container_add (GTK_CONTAINER (check1_menu), check_words);

  image7111 = gtk_image_new_from_stock ("gtk-zoom-100", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image7111);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (check_words), image7111);

  check_words_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (check_words), check_words_menu);

  check_capitalization = gtk_image_menu_item_new_with_mnemonic ("_Capitalization");
  gtk_widget_show (check_capitalization);
  gtk_container_add (GTK_CONTAINER (check_words_menu), check_capitalization);

  image7112 = gtk_image_new_from_stock ("gtk-ok", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image7112);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (check_capitalization), image7112);

  check_repetition = gtk_image_menu_item_new_with_mnemonic ("_Repetition");
  gtk_widget_show (check_repetition);
  gtk_container_add (GTK_CONTAINER (check_words_menu), check_repetition);

  image7238 = gtk_image_new_from_stock ("gtk-refresh", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image7238);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (check_repetition), image7238);

  unwanted_words = gtk_image_menu_item_new_with_mnemonic ("_Unwanted");
  gtk_widget_show (unwanted_words);
  gtk_container_add (GTK_CONTAINER (check_words_menu), unwanted_words);

  image7631 = gtk_image_new_from_stock ("gtk-clear", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image7631);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (unwanted_words), image7631);

  word_count_inventory = gtk_image_menu_item_new_with_mnemonic ("_Inventory");
  gtk_widget_show (word_count_inventory);
  gtk_container_add (GTK_CONTAINER (check_words_menu), word_count_inventory);

  image13715 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image13715);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (word_count_inventory), image13715);

  check_punctuation = gtk_image_menu_item_new_with_mnemonic ("_Punctuation");
  gtk_widget_show (check_punctuation);
  gtk_container_add (GTK_CONTAINER (check1_menu), check_punctuation);

  image7366 = gtk_image_new_from_stock ("gtk-zoom-100", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image7366);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (check_punctuation), image7366);

  check_punctuation_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (check_punctuation), check_punctuation_menu);

  check_matching_pairs = gtk_image_menu_item_new_with_mnemonic ("_Matching pairs");
  gtk_widget_show (check_matching_pairs);
  gtk_container_add (GTK_CONTAINER (check_punctuation_menu), check_matching_pairs);

  image7367 = gtk_image_new_from_stock ("gtk-refresh", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image7367);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (check_matching_pairs), image7367);

  menutools = gtk_menu_item_new_with_mnemonic ("_Tools");
  gtk_widget_show (menutools);
  gtk_container_add (GTK_CONTAINER (menubar1), menutools);

  menutools_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menutools), menutools_menu);

  line_cutter_for_hebrew_text1 = gtk_image_menu_item_new_with_mnemonic ("_Line cutter for Hebrew text");
  gtk_widget_show (line_cutter_for_hebrew_text1);
  gtk_container_add (GTK_CONTAINER (menutools_menu), line_cutter_for_hebrew_text1);

  image13532 = gtk_image_new_from_stock ("gtk-cut", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image13532);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (line_cutter_for_hebrew_text1), image13532);

  menuitem_preferences = gtk_menu_item_new_with_mnemonic ("_Preferences");
  gtk_widget_show (menuitem_preferences);
  gtk_container_add (GTK_CONTAINER (menubar1), menuitem_preferences);

  menuitem_preferences_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_preferences), menuitem_preferences_menu);

  notes_preferences = gtk_image_menu_item_new_with_mnemonic ("Project _notes");
  gtk_widget_show (notes_preferences);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), notes_preferences);

  image2116 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image2116);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (notes_preferences), image2116);

  printingprefs = gtk_image_menu_item_new_with_mnemonic ("_Printing");
  gtk_widget_show (printingprefs);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), printingprefs);

  image3493 = gtk_image_new_from_stock ("gtk-print", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image3493);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (printingprefs), image3493);

  formatting_objects_processor = gtk_image_menu_item_new_with_mnemonic ("_Formatter");
  gtk_widget_show (formatting_objects_processor);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), formatting_objects_processor);

  image3718 = gtk_image_new_from_stock ("gtk-print-preview", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image3718);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (formatting_objects_processor), image3718);

  reference_exchange1 = gtk_image_menu_item_new_with_mnemonic ("_Reference exchange");
  gtk_widget_show (reference_exchange1);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), reference_exchange1);

  image5972 = gtk_image_new_from_stock ("gtk-network", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image5972);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (reference_exchange1), image5972);

  ignored_references1 = gtk_image_menu_item_new_with_mnemonic ("_Ignored references");
  gtk_widget_show (ignored_references1);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), ignored_references1);

  image6467 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image6467);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (ignored_references1), image6467);

  prefs_books = gtk_image_menu_item_new_with_mnemonic ("_Books");
  gtk_widget_show (prefs_books);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), prefs_books);

  image12167 = gtk_image_new_from_stock ("gtk-index", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image12167);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (prefs_books), image12167);

  preferences_synchronization = gtk_image_menu_item_new_with_mnemonic ("_Synchronization");
  gtk_widget_show (preferences_synchronization);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), preferences_synchronization);

  image12530 = gtk_image_new_from_stock ("gtk-refresh", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image12530);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (preferences_synchronization), image12530);

  preferences_debug = gtk_check_menu_item_new_with_mnemonic ("_Debug");
  gtk_widget_show (preferences_debug);
  gtk_container_add (GTK_CONTAINER (menuitem_preferences_menu), preferences_debug);

  menuitem_help = gtk_menu_item_new_with_mnemonic ("_Help");
  gtk_widget_show (menuitem_help);
  gtk_container_add (GTK_CONTAINER (menubar1), menuitem_help);

  menuitem_help_menu = gtk_menu_new ();
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_help), menuitem_help_menu);

  help1 = gtk_image_menu_item_new_from_stock ("gtk-help", accel_group);
  gtk_widget_show (help1);
  gtk_container_add (GTK_CONTAINER (menuitem_help_menu), help1);

  system_log1 = gtk_image_menu_item_new_with_mnemonic ("_System log");
  gtk_widget_show (system_log1);
  gtk_container_add (GTK_CONTAINER (menuitem_help_menu), system_log1);

  image4388 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_MENU);
  gtk_widget_show (image4388);
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (system_log1), image4388);

  about1 = gtk_image_menu_item_new_from_stock ("gtk-about", accel_group);
  gtk_widget_show (about1);
  gtk_container_add (GTK_CONTAINER (menuitem_help_menu), about1);

  toolbar1 = gtk_toolbar_new ();
  gtk_widget_show (toolbar1);
  gtk_box_pack_start (GTK_BOX (vbox1), toolbar1, FALSE, FALSE, 0);
  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar1), GTK_TOOLBAR_BOTH_HORIZ);

  GtkToolItem * toolitem1 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem1));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem1), -1);

  button_back = gtk_button_new ();
  gtk_widget_show (button_back);
  gtk_container_add (GTK_CONTAINER (toolitem1), button_back);

  image1 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_BUTTON);
  gtk_widget_show (image1);
  gtk_container_add (GTK_CONTAINER (button_back), image1);

  GtkToolItem * toolitem2 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem2));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem2), -1);

  button_forward = gtk_button_new ();
  gtk_widget_show (button_forward);
  gtk_container_add (GTK_CONTAINER (toolitem2), button_forward);

  image2 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_BUTTON);
  gtk_widget_show (image2);
  gtk_container_add (GTK_CONTAINER (button_forward), image2);

  GtkToolItem * toolitem4 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem4));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem4), -1);

  spinbutton_book_adj = gtk_adjustment_new (0, -1e+06, 1e+06, 1, 10, 10);
  spinbutton_book = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_book_adj), 1, 0);
  gtk_widget_show (spinbutton_book);
  gtk_container_add (GTK_CONTAINER (toolitem4), spinbutton_book);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton_book), TRUE);
  gtk_editable_set_editable (GTK_EDITABLE (spinbutton_book), false);  
  gtk_entry_set_visibility (GTK_ENTRY (spinbutton_book), false);
  gtk_entry_set_invisible_char (GTK_ENTRY (spinbutton_book), 0);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton_book), 0);
  GTK_WIDGET_UNSET_FLAGS (spinbutton_book, GTK_CAN_FOCUS);
  
  GtkToolItem * toolitem3 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem3));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem3), -1);

  comboboxentry_book = gtk_combo_box_new_text ();
  gtk_widget_show (comboboxentry_book);
  gtk_container_add (GTK_CONTAINER (toolitem3), comboboxentry_book);

  GtkToolItem * toolitem5 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem5));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem5), -1);

  spinbutton_chapter_adj = gtk_adjustment_new (0, -1e+06, 1e+06, 1, 10, 10);
  spinbutton_chapter = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_chapter_adj), 1, 0);
  gtk_widget_show (spinbutton_chapter);
  gtk_container_add (GTK_CONTAINER (toolitem5), spinbutton_chapter);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton_chapter), TRUE);
  gtk_editable_set_editable (GTK_EDITABLE (spinbutton_chapter), false);  
  gtk_entry_set_visibility (GTK_ENTRY (spinbutton_chapter), false);
  gtk_entry_set_invisible_char (GTK_ENTRY (spinbutton_chapter), 0);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton_chapter), 0);
  GTK_WIDGET_UNSET_FLAGS (spinbutton_chapter, GTK_CAN_FOCUS);

  GtkToolItem * toolitem6 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem6));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem6), -1);

  comboboxentry_chapter = gtk_combo_box_new_text ();
  gtk_widget_show (comboboxentry_chapter);
  gtk_container_add (GTK_CONTAINER (toolitem6), comboboxentry_chapter);

  GtkToolItem * toolitem7 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem7));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem7), -1);

  spinbutton_verse_adj = gtk_adjustment_new (0, -1e+06, 1e+06, 1, 10, 10);
  spinbutton_verse = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_verse_adj), 1, 0);
  gtk_widget_show (spinbutton_verse);
  gtk_container_add (GTK_CONTAINER (toolitem7), spinbutton_verse);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton_verse), TRUE);
  gtk_editable_set_editable (GTK_EDITABLE (spinbutton_verse), false);  
  gtk_entry_set_visibility (GTK_ENTRY (spinbutton_verse), false);
  gtk_entry_set_invisible_char (GTK_ENTRY (spinbutton_verse), 0);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton_verse), 0);
  GTK_WIDGET_UNSET_FLAGS (spinbutton_verse, GTK_CAN_FOCUS);

  GtkToolItem * toolitem8 = gtk_tool_item_new ();
  gtk_widget_show (GTK_WIDGET (toolitem8));
  gtk_toolbar_insert (GTK_TOOLBAR (toolbar1), GTK_TOOL_ITEM (toolitem8), -1);

  comboboxentry_verse = gtk_combo_box_new_text ();
  gtk_widget_show (comboboxentry_verse);
  gtk_container_add (GTK_CONTAINER (toolitem8), comboboxentry_verse);

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

  hpaned1 = gtk_hpaned_new ();
  gtk_widget_show (hpaned1);
  gtk_box_pack_start (GTK_BOX (hbox1), hpaned1, TRUE, TRUE, 0);
  // Position of horizontal pane will be set later.

  vbox_left = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox_left);
  gtk_paned_pack1 (GTK_PANED (hpaned1), vbox_left, FALSE, TRUE);

  vpaned1 = gtk_vpaned_new ();
  gtk_widget_show (vpaned1);
  gtk_box_pack_start (GTK_BOX (vbox_left), vpaned1, TRUE, TRUE, 0);
  // Position of main vertical pane will be set later.

  vpaned_editor = gtk_vpaned_new ();
  gtk_widget_show (vpaned_editor);
  gtk_paned_pack1 (GTK_PANED (vpaned1), vpaned_editor, FALSE, TRUE);
  // Position of the footnotes' pane will be set later.

  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow1);
  gtk_paned_pack1 (GTK_PANED (vpaned_editor), scrolledwindow1, FALSE, TRUE);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);

  GtkWidget * widget;
  
  widget = gtk_text_view_new ();
  gtk_widget_show (widget);
  gtk_container_add (GTK_CONTAINER (scrolledwindow1), widget);
  gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (widget), FALSE);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (widget), GTK_WRAP_WORD);

  // Set textview in the editor object.
  editor.textview_text_set (widget);
  
  scrolledwindow10 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow10);
  gtk_paned_pack2 (GTK_PANED (vpaned_editor), scrolledwindow10, TRUE, TRUE);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow10), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow10), GTK_SHADOW_IN);

  widget = gtk_text_view_new ();
  gtk_widget_show (widget);
  gtk_container_add (GTK_CONTAINER (scrolledwindow10), widget);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (widget), GTK_WRAP_WORD);
  // Accept no tabs, as these are not in the USFM standard anyway, and so tab moves to next widget.
  gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (widget), FALSE);

  // Set textview in the editor object.
  editor.textview_notes_set (widget);

  notebook1 = gtk_notebook_new ();
  gtk_widget_show (notebook1);
  gtk_paned_pack2 (GTK_PANED (vpaned1), notebook1, TRUE, TRUE);
  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook1), FALSE);

  scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow3);
  gtk_container_add (GTK_CONTAINER (notebook1), scrolledwindow3);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  textview_notes = gtk_text_view_new ();
  gtk_widget_show (textview_notes);
  gtk_container_add (GTK_CONTAINER (scrolledwindow3), textview_notes);
  // The editor does not accept tabs, so that <Tab> goes to the next widget.
  // USFM has no tabs defined anyway. This applies to all textviews.
  gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (textview_notes), FALSE);
  gtk_text_view_set_editable (GTK_TEXT_VIEW (textview_notes), FALSE);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview_notes), GTK_WRAP_WORD);

  label1 = gtk_label_new ("");
  gtk_widget_show (label1);
  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label1);

  hbox3 = gtk_hbox_new (FALSE, 4);
  gtk_widget_show (hbox3);
  gtk_container_add (GTK_CONTAINER (notebook1), hbox3);
  gtk_container_set_border_width (GTK_CONTAINER (hbox3), 1);

  scrolledwindow4 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow4);
  gtk_box_pack_start (GTK_BOX (hbox3), scrolledwindow4, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow4), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  textview_note = gtk_text_view_new ();
  gtk_widget_show (textview_note);
  gtk_container_add (GTK_CONTAINER (scrolledwindow4), textview_note);
  gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (textview_note), FALSE);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview_note), GTK_WRAP_WORD);

  vbox4 = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox4);
  gtk_box_pack_start (GTK_BOX (hbox3), vbox4, FALSE, FALSE, 0);

  button_note_cancel = gtk_button_new_from_stock ("gtk-cancel");
  gtk_widget_show (button_note_cancel);
  gtk_box_pack_end (GTK_BOX (vbox4), button_note_cancel, FALSE, FALSE, 0);

  button_note_ok = gtk_button_new_from_stock ("gtk-ok");
  gtk_widget_show (button_note_ok);
  gtk_box_pack_end (GTK_BOX (vbox4), button_note_ok, FALSE, FALSE, 0);

  label2 = gtk_label_new ("");
  gtk_widget_show (label2);
  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label2);

  vbox_right = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox_right);
  gtk_paned_pack2 (GTK_PANED (hpaned1), vbox_right, TRUE, TRUE);

  notebook_tools = gtk_notebook_new ();
  gtk_widget_show (notebook_tools);
  gtk_box_pack_start (GTK_BOX (vbox_right), notebook_tools, TRUE, TRUE, 0);

  // Deal with screen layout.
  if (genconfig->tools_area_left()) {
    screen_layout_tools_area_set (false, vbox_left, vbox_right, vpaned1, notebook_tools);  
  }
  
  vpaned_references = gtk_vpaned_new ();
  gtk_widget_show (vpaned_references);
  gtk_container_add (GTK_CONTAINER (notebook_tools), vpaned_references);
  // Position of pane will be set later.

  scrolledwindow_references = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow_references);
  gtk_paned_pack1 (GTK_PANED (vpaned_references), scrolledwindow_references, FALSE, TRUE);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow_references), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  // Manually added and changed.
  liststore_references = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
  // Text cell renderer.
  GtkCellRenderer *renderer;
  renderer = gtk_cell_renderer_text_new ();
  
  treeview_references = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore_references));
  gtk_widget_show (treeview_references);
  gtk_container_add (GTK_CONTAINER (scrolledwindow_references), treeview_references);
  
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_references), TRUE);
  // Unreference the store once, so it gets destroyed with the treeview.
  g_object_unref (liststore_references);
  // Add reference column.
  treecolumn_references = gtk_tree_view_column_new_with_attributes ("", renderer, "text", 0, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_references), treecolumn_references);
  // Add comments column
  GtkTreeViewColumn * treecolumn2;
  treecolumn2 = gtk_tree_view_column_new_with_attributes ("Comment", renderer, "text", 1, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_references), treecolumn2);
  treeselect_references = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_references));
  gtk_tree_selection_set_mode (treeselect_references, GTK_SELECTION_MULTIPLE);

  scrolledwindow_quick_refs = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow_quick_refs);
  gtk_paned_pack2 (GTK_PANED (vpaned_references), scrolledwindow_quick_refs, TRUE, TRUE);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow_quick_refs), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  textview_quick_refs = gtk_text_view_new ();
  gtk_widget_show (textview_quick_refs);
  gtk_container_add (GTK_CONTAINER (scrolledwindow_quick_refs), textview_quick_refs);
  gtk_text_view_set_editable (GTK_TEXT_VIEW (textview_quick_refs), FALSE);
  gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (textview_quick_refs), FALSE);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview_quick_refs), GTK_WRAP_WORD);
  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (textview_quick_refs), FALSE);

  label13 = gtk_label_new ("References");
  gtk_widget_show (label13);
  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook_tools), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook_tools), 0), label13);

  scrolledwindow7 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow7);
  gtk_container_add (GTK_CONTAINER (notebook_tools), scrolledwindow7);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow7), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  // TreeStore and TreeView.
  treestore_styles = gtk_tree_store_new (1, G_TYPE_STRING);
  treeview_styles = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore_styles));
  gtk_widget_show (treeview_styles);
  gtk_container_add (GTK_CONTAINER (scrolledwindow7), treeview_styles);
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_styles), false);
  // Add the column.
  treecolumn_styles = gtk_tree_view_column_new_with_attributes ("", renderer, "text", 0, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_styles), treecolumn_styles);
  // Selection object.
  treeselect_styles = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_styles));
  gtk_tree_selection_set_mode (treeselect_styles, GTK_SELECTION_MULTIPLE);  

  label14 = gtk_label_new ("Styles");
  gtk_widget_show (label14);
  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook_tools), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook_tools), 1), label14);

  // Set page number to display.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), genconfig->tools_area_page_number());

  notebook3 = gtk_notebook_new ();
  gtk_widget_show (notebook3);
  gtk_container_add (GTK_CONTAINER (notebook_tools), notebook3);
  GTK_WIDGET_UNSET_FLAGS (notebook3, GTK_CAN_FOCUS);
  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook3), false);
  gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook3), FALSE);

  vbox3 = gtk_vbox_new (FALSE, 1);
  gtk_widget_show (vbox3);
  gtk_container_add (GTK_CONTAINER (notebook3), vbox3);
  gtk_container_set_border_width (GTK_CONTAINER (vbox3), 2);

  label_note_category = gtk_label_new_with_mnemonic ("C_ategory");
  gtk_widget_show (label_note_category);
  gtk_box_pack_start (GTK_BOX (vbox3), label_note_category, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label_note_category), 0, 0.5);

  combobox_note_category = gtk_combo_box_new_text ();
  gtk_widget_show (combobox_note_category);
  gtk_box_pack_start (GTK_BOX (vbox3), combobox_note_category, FALSE, TRUE, 0);

  label_note_references = gtk_label_new_with_mnemonic ("_References");
  gtk_widget_show (label_note_references);
  gtk_box_pack_start (GTK_BOX (vbox3), label_note_references, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label_note_references), 0, 0.5);

  scrolledwindow8 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow8);
  gtk_box_pack_start (GTK_BOX (vbox3), scrolledwindow8, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow8), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  textview_note_references = gtk_text_view_new ();
  gtk_widget_show (textview_note_references);
  gtk_container_add (GTK_CONTAINER (scrolledwindow8), textview_note_references);
  gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (textview_note_references), FALSE);

  label_note_project = gtk_label_new_with_mnemonic ("Pro_ject");
  gtk_widget_show (label_note_project);
  gtk_box_pack_start (GTK_BOX (vbox3), label_note_project, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label_note_project), 0, 0.5);

  combobox_note_project = gtk_combo_box_new_text ();
  gtk_widget_show (combobox_note_project);
  gtk_box_pack_start (GTK_BOX (vbox3), combobox_note_project, FALSE, TRUE, 0);

  label_note_created_on = gtk_label_new ("");
  gtk_widget_show (label_note_created_on);
  gtk_box_pack_start (GTK_BOX (vbox3), label_note_created_on, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label_note_created_on), 0, 0.5);

  label_note_created_by = gtk_label_new ("");
  gtk_widget_show (label_note_created_by);
  gtk_box_pack_start (GTK_BOX (vbox3), label_note_created_by, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label_note_created_by), 0, 0.5);

  label_note_edited_on = gtk_label_new ("");
  gtk_widget_show (label_note_edited_on);
  gtk_box_pack_start (GTK_BOX (vbox3), label_note_edited_on, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label_note_edited_on), 0, 0.5);

  label_note_logbook = gtk_label_new ("Logbook");
  gtk_widget_show (label_note_logbook);
  gtk_box_pack_start (GTK_BOX (vbox3), label_note_logbook, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label_note_logbook), 0, 0.5);

  scrolledwindow9 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow9);
  gtk_box_pack_start (GTK_BOX (vbox3), scrolledwindow9, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow9), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  textview_note_logbook = gtk_text_view_new ();
  gtk_widget_show (textview_note_logbook);
  gtk_container_add (GTK_CONTAINER (scrolledwindow9), textview_note_logbook);
  gtk_text_view_set_editable (GTK_TEXT_VIEW (textview_note_logbook), FALSE);
  gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (textview_note_logbook), FALSE);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview_note_logbook), GTK_WRAP_WORD);
  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (textview_note_logbook), FALSE);

  label18 = gtk_label_new ("");
  gtk_widget_show (label18);
  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook3), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook3), 0), label18);

  label17 = gtk_label_new ("When a project note\nis being edited,\nthis will show content\nof that note.");
  gtk_widget_show (label17);
  gtk_container_add (GTK_CONTAINER (notebook3), label17);
  gtk_label_set_line_wrap (GTK_LABEL (label17), TRUE);

  label20 = gtk_label_new ("");
  gtk_widget_show (label20);
  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook3), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook3), 1), label20);

  label_notetools = gtk_label_new ("Project note");
  gtk_widget_show (label_notetools);
  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook_tools), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook_tools), 2), label_notetools);

  // Switch notebook so project note controls hide.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook3), 1);

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

  hbox7 = gtk_hbox_new (FALSE, 8);
  gtk_widget_show (hbox7);
  gtk_box_pack_start (GTK_BOX (hbox5), hbox7, TRUE, TRUE, 0);

  statuslabel_stylesheet = gtk_label_new ("");
  gtk_widget_show (statuslabel_stylesheet);
  gtk_box_pack_start (GTK_BOX (hbox7), statuslabel_stylesheet, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (statuslabel_stylesheet), 0, 0.5);

  statusbutton_attention = gtk_button_new ();
  // gtk_widget_show (statusbutton_attention);
  gtk_box_pack_start (GTK_BOX (hbox7), statusbutton_attention, FALSE, FALSE, 0);

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

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

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

  label21 = gtk_label_new_with_mnemonic ("Attention");
  gtk_widget_show (label21);
  gtk_box_pack_start (GTK_BOX (hbox8), label21, FALSE, FALSE, 0);

  statusbar1 = gtk_statusbar_new ();
  gtk_widget_show (statusbar1);
  gtk_box_pack_start (GTK_BOX (hbox5), statusbar1, FALSE, TRUE, 0);
  gtk_widget_set_size_request (statusbar1, 25, -1);

  // Appearance of text in editor.
  editor_set_font ();

  // Positions of panes.
  screen_layout_panes_position_load (hpaned1, vpaned1, vpaned_editor, vpaned_references);

  g_signal_connect ((gpointer) mainwindow, "destroy", G_CALLBACK (gtk_main_quit), gpointer(this));
  g_signal_connect ((gpointer) mainwindow, "delete_event", G_CALLBACK (on_mainwindow_delete_event), gpointer(this));
  g_signal_connect ((gpointer) mainwindow, "focus_in_event", G_CALLBACK (on_mainwindow_focus_in_event), gpointer(this));
  g_signal_connect ((gpointer) new1, "activate", G_CALLBACK (on_new1_activate), gpointer(this));
  g_signal_connect ((gpointer) open1, "activate", G_CALLBACK (on_open1_activate), gpointer(this));
  g_signal_connect ((gpointer) close1, "activate", G_CALLBACK (on_close1_activate), gpointer(this));
  g_signal_connect ((gpointer) delete1, "activate", G_CALLBACK (on_delete1_activate), gpointer(this));
  g_signal_connect ((gpointer) print_project, "activate", G_CALLBACK (on_print_project_activate), gpointer(this));
  g_signal_connect ((gpointer) properties1, "activate", G_CALLBACK (on_properties1_activate), gpointer(this));
  g_signal_connect ((gpointer) import1, "activate", G_CALLBACK (on_import1_activate), gpointer(this));
  g_signal_connect ((gpointer) export_usfm_files, "activate", G_CALLBACK (on_export_usfm_files_activate), gpointer(this));
  g_signal_connect ((gpointer) to_bibleworks_version_database_compiler, "activate", G_CALLBACK (on_to_bibleworks_version_compiler_activate), gpointer(this));
  g_signal_connect ((gpointer) export_to_sword_module, "activate", G_CALLBACK (on_export_to_sword_module_activate), gpointer(this));
  g_signal_connect ((gpointer) copy_project_to, "activate", G_CALLBACK (on_copy_project_to_activate), gpointer(this));
  g_signal_connect ((gpointer) compare_with1, "activate", G_CALLBACK (on_compare_with1_activate), gpointer(this));
  g_signal_connect ((gpointer) parallel_bible, "activate", G_CALLBACK (on_parallel_bible_activate), gpointer(this));
  g_signal_connect ((gpointer) synchronize_projects, "activate", G_CALLBACK (on_synchronize_projects_activate), gpointer(this));  
  g_signal_connect ((gpointer) file_references, "activate", G_CALLBACK (on_file_references_activate), gpointer(this));
  g_signal_connect ((gpointer) open_references1, "activate", G_CALLBACK (on_open_references1_activate), gpointer(this));
  g_signal_connect ((gpointer) references_save_as, "activate", G_CALLBACK (on_references_save_as_activate), gpointer(this));
  g_signal_connect ((gpointer) print_references, "activate", G_CALLBACK (on_print_references_activate), gpointer(this));
  g_signal_connect ((gpointer) close_references, "activate", G_CALLBACK (on_close_references_activate), gpointer (this));
  g_signal_connect ((gpointer) delete_references, "activate", G_CALLBACK (on_delete_references_activate), gpointer (this));
  g_signal_connect ((gpointer) reference_hide, "activate", G_CALLBACK (on_reference_hide_activate), gpointer (this));
  g_signal_connect ((gpointer) new_note, "activate", G_CALLBACK (on_new_note_activate), gpointer(this));
  g_signal_connect ((gpointer) delete_note, "activate", G_CALLBACK (on_delete_note_activate), gpointer(this));
  g_signal_connect ((gpointer) import_notes, "activate", G_CALLBACK (on_import_notes_activate), gpointer(this));
  g_signal_connect ((gpointer) export_notes, "activate", G_CALLBACK (on_export_notes_activate), gpointer(this));
  g_signal_connect ((gpointer) style, "activate", G_CALLBACK (on_file_styles), gpointer(this));
  g_signal_connect ((gpointer) stylesheet_switch, "activate", G_CALLBACK (on_stylesheet_switch_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheet_edit_mode, "activate", G_CALLBACK (on_stylesheet_edit_mode_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheets_new, "activate", G_CALLBACK (on_stylesheets_new_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheets_delete, "activate", G_CALLBACK (on_stylesheets_delete_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheets_rename, "activate", G_CALLBACK (on_stylesheets_rename_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheets_import, "activate", G_CALLBACK (on_stylesheets_import_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheets_export, "activate", G_CALLBACK (on_stylesheets_export_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheets_expand_all, "activate", G_CALLBACK (on_stylesheets_expand_all_activate), gpointer(this));
  g_signal_connect ((gpointer) stylesheets_collapse_all, "activate", G_CALLBACK (on_stylesheets_collapse_all_activate), gpointer(this));
  g_signal_connect ((gpointer) style_insert, "activate", G_CALLBACK (on_style_insert_activate), gpointer(this));
  g_signal_connect ((gpointer) style_new, "activate", G_CALLBACK (on_style_new_activate), gpointer(this));
  g_signal_connect ((gpointer) style_properties, "activate", G_CALLBACK (on_style_properties_activate), gpointer(this));
  g_signal_connect ((gpointer) style_delete, "activate", G_CALLBACK (on_style_delete_activate), gpointer(this));
  g_signal_connect ((gpointer) quit1, "activate", G_CALLBACK (on_quit1_activate), gpointer(this));
  g_signal_connect ((gpointer) menuitem_edit, "activate", G_CALLBACK (on_edit1_activate), gpointer(this));
  g_signal_connect ((gpointer) cut1, "activate", G_CALLBACK (on_cut1_activate), gpointer(this));
  g_signal_connect ((gpointer) copy1, "activate", G_CALLBACK (on_copy1_activate), gpointer(this));
  g_signal_connect ((gpointer) paste1, "activate", G_CALLBACK (on_paste1_activate), gpointer(this));
  g_signal_connect ((gpointer) undo1, "activate", G_CALLBACK (on_undo1_activate), gpointer(this));
  g_signal_connect ((gpointer) redo1, "activate", G_CALLBACK (on_redo1_activate), gpointer(this));
  g_signal_connect ((gpointer) find1, "activate", G_CALLBACK (on_findspecial1_activate), gpointer(this));
  g_signal_connect ((gpointer) find_and_replace1, "activate", G_CALLBACK (on_find_and_replace1_activate), gpointer (this));
  g_signal_connect ((gpointer) find_in_notes1, "activate", G_CALLBACK (on_find_in_notes1_activate), gpointer(this));
  g_signal_connect ((gpointer) get_references_from_note, "activate", G_CALLBACK (on_get_references_from_note_activate), gpointer(this));
  g_signal_connect ((gpointer) menuitem_view, "activate", G_CALLBACK (on_menuitem_view_activate), gpointer(this));
  g_signal_connect ((gpointer) screen_font, "activate", G_CALLBACK (on_screen_font_activate), gpointer(this));
  g_signal_connect ((gpointer) printer_font, "activate", G_CALLBACK (on_printer_font_activate), gpointer(this));
  g_signal_connect ((gpointer) viewnotes, "activate", G_CALLBACK (on_viewnotes_activate), gpointer(this));
  g_signal_connect ((gpointer) screen_layout, "activate", G_CALLBACK (on_screen_layout_activate), gpointer(this));
  g_signal_connect ((gpointer) insert1, "activate", G_CALLBACK (on_insert1_activate), gpointer(this));
  g_signal_connect ((gpointer) standard_text_1, "activate", G_CALLBACK (on_standard_text_1_activate), gpointer (this));
  g_signal_connect ((gpointer) standard_text_2, "activate", G_CALLBACK (on_standard_text_2_activate), gpointer (this));
  g_signal_connect ((gpointer) standard_text_3, "activate", G_CALLBACK (on_standard_text_3_activate), gpointer (this));
  g_signal_connect ((gpointer) standard_text_4, "activate", G_CALLBACK (on_standard_text_4_activate), gpointer (this));
  g_signal_connect ((gpointer) current_reference1, "activate", G_CALLBACK (on_current_reference1_activate), gpointer (this));
  g_signal_connect ((gpointer) insert_style, "activate", G_CALLBACK (on_insert_style_activate), gpointer (this));
  g_signal_connect ((gpointer) insert_footnote, "activate", G_CALLBACK (on_insert_footnote_activate), gpointer (this));
  g_signal_connect ((gpointer) insert_endnote, "activate", G_CALLBACK (on_insert_endnote_activate), gpointer (this));
  g_signal_connect ((gpointer) insert_crossreference, "activate",  G_CALLBACK (on_insert_crossreference_activate), gpointer (this));
  g_signal_connect ((gpointer) next_verse1, "activate", G_CALLBACK (on_next_verse_activate), gpointer (this));
  g_signal_connect ((gpointer) previous_verse1, "activate", G_CALLBACK (on_previous_verse_activate), gpointer (this));
  g_signal_connect ((gpointer) next_chapter1, "activate", G_CALLBACK (on_next_chapter_activate), gpointer (this));
  g_signal_connect ((gpointer) previous_chapter1, "activate", G_CALLBACK (on_previous_chapter_activate), gpointer (this));
  g_signal_connect ((gpointer) next_book1, "activate", G_CALLBACK (on_next_book_activate), gpointer (this));
  g_signal_connect ((gpointer) previous_book1, "activate", G_CALLBACK (on_previous_book_activate), gpointer (this));
  g_signal_connect ((gpointer) next_reference1, "activate", G_CALLBACK (on_next_reference1_activate), gpointer(this));
  g_signal_connect ((gpointer) previous_reference1, "activate", G_CALLBACK (on_previous_reference1_activate), gpointer(this));
  g_signal_connect ((gpointer) next_reference_in_history1, "activate", G_CALLBACK (on_next_reference_in_history1_activate), gpointer(this));
  g_signal_connect ((gpointer) previous_reference_in_history1, "activate", G_CALLBACK(on_previous_reference_in_history1_activate), gpointer(this));
  g_signal_connect ((gpointer) reference1, "activate", G_CALLBACK (on_reference_activate), gpointer(this));
  g_signal_connect ((gpointer) text_area1, "activate", G_CALLBACK (on_text_area1_activate), gpointer(this));
  g_signal_connect ((gpointer) goto_bible_notes_area1, "activate", G_CALLBACK (on_goto_bible_notes_area1_activate), gpointer(this));
  g_signal_connect ((gpointer) references_area1, "activate", G_CALLBACK (on_tools_area1_activate), gpointer(this));
  g_signal_connect ((gpointer) notes_area1, "activate", G_CALLBACK (on_notes_area1_activate), gpointer(this));
  g_signal_connect ((gpointer) synchronize_other_programs2, "activate", G_CALLBACK (on_synchronize_other_programs2_activate), gpointer(this));
  g_signal_connect ((gpointer) check1, "activate", G_CALLBACK (on_check1_activate), gpointer(this));
  g_signal_connect ((gpointer) markers1, "activate", G_CALLBACK (on_markers1_activate), gpointer(this));
  g_signal_connect ((gpointer) validate_usfms1, "activate", G_CALLBACK (on_validate_usfms1_activate), gpointer(this));
  g_signal_connect ((gpointer) count_usfms1, "activate", G_CALLBACK (on_count_usfms1_activate), gpointer(this));
  g_signal_connect ((gpointer) compare_usfm1, "activate", G_CALLBACK (on_compare_usfm1_activate), gpointer(this));
  g_signal_connect ((gpointer) chapters_and_verses1, "activate", G_CALLBACK (on_chapters_and_verses1_activate), gpointer(this));
  g_signal_connect ((gpointer) count_characters, "activate", G_CALLBACK (on_count_characters_activate), gpointer(this));
  g_signal_connect ((gpointer) unwanted_patterns, "activate", G_CALLBACK (on_unwanted_patterns_activate), gpointer(this));
  g_signal_connect ((gpointer) check_capitalization, "activate", G_CALLBACK (on_check_capitalization_activate), gpointer(this));
  g_signal_connect ((gpointer) check_repetition, "activate", G_CALLBACK (on_check_repetition_activate), gpointer(this));
  g_signal_connect ((gpointer) unwanted_words, "activate", G_CALLBACK (on_unwanted_words_activate), gpointer(this));
  g_signal_connect ((gpointer) check_matching_pairs, "activate", G_CALLBACK (on_check_matching_pairs_activate), gpointer(this));
  g_signal_connect ((gpointer) word_count_inventory, "activate", G_CALLBACK (on_word_count_inventory_activate), gpointer(this));
  g_signal_connect ((gpointer) menutools, "activate", G_CALLBACK (on_menutools_activate), gpointer(this));
  g_signal_connect ((gpointer) line_cutter_for_hebrew_text1, "activate", G_CALLBACK (on_line_cutter_for_hebrew_text1_activate), gpointer(this));
  g_signal_connect ((gpointer) notes_preferences, "activate", G_CALLBACK (on_notes_preferences_activate), gpointer(this));
  g_signal_connect ((gpointer) printingprefs, "activate", G_CALLBACK (on_printingprefs_activate), gpointer(this));
  g_signal_connect ((gpointer) formatting_objects_processor, "activate", G_CALLBACK (on_formatting_objects_processor_activate), gpointer(this));
  g_signal_connect ((gpointer) reference_exchange1, "activate", G_CALLBACK (on_reference_exchange1_activate), gpointer(this));
  g_signal_connect ((gpointer) ignored_references1, "activate", G_CALLBACK (on_ignored_references1_activate), gpointer(this));
  g_signal_connect ((gpointer) prefs_books, "activate", G_CALLBACK (on_prefs_books_activate), gpointer(this));
  g_signal_connect ((gpointer) preferences_synchronization, "activate", G_CALLBACK (on_preferences_synchronization_activate), gpointer(this));
  g_signal_connect ((gpointer) preferences_debug, "activate", G_CALLBACK (on_preferences_debug_activate), gpointer(this));
  g_signal_connect ((gpointer) help1, "activate", G_CALLBACK (on_help1_activate), gpointer(this));
  g_signal_connect ((gpointer) system_log1, "activate", G_CALLBACK (on_system_log1_activate), gpointer(this));
  g_signal_connect ((gpointer) about1, "activate", G_CALLBACK (on_about1_activate), gpointer(this));
  g_signal_connect ((gpointer) button_back, "clicked", G_CALLBACK (on_button_back_clicked), gpointer(this));
  g_signal_connect ((gpointer) button_forward, "clicked", G_CALLBACK (on_button_forward_clicked), gpointer(this));
  g_signal_connect ((gpointer) comboboxentry_book, "changed", G_CALLBACK (on_combo_entry_book_changed), gpointer(this));
  g_signal_connect ((gpointer) spinbutton_book, "value_changed", G_CALLBACK (on_spinbutton_book_value_changed), gpointer(this));
  g_signal_connect ((gpointer) spinbutton_chapter, "value_changed", G_CALLBACK (on_spinbutton_chapter_value_changed), gpointer(this));
  g_signal_connect ((gpointer) spinbutton_verse, "value_changed", G_CALLBACK (on_spinbutton_verse_value_changed), gpointer(this));
  g_signal_connect ((gpointer) comboboxentry_chapter, "changed", G_CALLBACK (on_combo_entry_chapter_changed), gpointer(this));
  g_signal_connect ((gpointer) comboboxentry_verse, "changed", G_CALLBACK (on_combo_entry_verse_changed), gpointer(this));
  g_signal_connect_after ((gpointer) editor.textview_text, "move_cursor", G_CALLBACK (on_textview_edit_move_cursor), gpointer(this));
  g_signal_connect_after ((gpointer) editor.textview_text, "grab_focus", G_CALLBACK (on_textview_edit_grab_focus), gpointer(this));
  g_signal_connect ((gpointer) editor.textview_text, "motion-notify-event", G_CALLBACK (on_text_motion_notify_event), gpointer(this));
  g_signal_connect ((gpointer) editor.textview_text, "visibility-notify-event", G_CALLBACK (visibility_notify_event), gpointer(this));
  g_signal_connect ((gpointer) editor.textview_text, "event-after", G_CALLBACK (on_text_event_after), gpointer(this));
  g_signal_connect ((gpointer) editor.textview_text, "key-press-event", G_CALLBACK (text_key_press_event), gpointer(this));
  g_signal_connect ((gpointer) editor.textview_text, "button_press_event", G_CALLBACK (on_textview_edit_button_press_event), gpointer(this));
  g_signal_connect ((gpointer) editor.textview_notes, "button_press_event", G_CALLBACK (on_textview_footnotes_button_press_event), gpointer(this));
  g_signal_connect_after ((gpointer) editor.textview_notes, "move_cursor", G_CALLBACK (on_textview_footnotes_move_cursor), gpointer(this));
  g_signal_connect_after ((gpointer) editor.textview_notes, "grab_focus", G_CALLBACK (on_textview_footnotes_grab_focus), gpointer(this));
  g_signal_connect ((gpointer) button_note_ok, "clicked", G_CALLBACK (on_button_ok_clicked), gpointer(this));
  g_signal_connect ((gpointer) button_note_cancel, "clicked", G_CALLBACK (on_button_cancel_clicked), gpointer(this));
  g_signal_connect ((gpointer) notebook_tools, "switch_page", G_CALLBACK (on_notebook_tools_switch_page), gpointer(this));
  g_signal_connect ((gpointer) treeview_references, "key_press_event", G_CALLBACK (on_treeview_references_key_press_event), gpointer(this));
  g_signal_connect ((gpointer) treeview_references, "button_press_event", G_CALLBACK (on_treeview_references_button_press_event), gpointer(this));
  g_signal_connect ((gpointer) treeview_references, "popup_menu", G_CALLBACK (on_treeview_references_popup_menu), gpointer(this));
  g_signal_connect ((gpointer) treeview_references, "move_cursor", G_CALLBACK (on_treeview_references_move_cursor), gpointer(this));
  g_signal_connect ((gpointer) treeview_references, "cursor_changed", G_CALLBACK (on_treeview_references_cursor_changed), gpointer(this));
  g_signal_connect ((gpointer) textview_notes, "motion-notify-event", G_CALLBACK (notes_motion_notify_event), gpointer(this));
  g_signal_connect ((gpointer) textview_notes, "visibility-notify-event", G_CALLBACK (visibility_notify_event), gpointer(this));
  g_signal_connect ((gpointer) textview_notes, "key-press-event", G_CALLBACK (notes_key_press_event), gpointer(this));
  g_signal_connect ((gpointer) textview_notes, "event-after", G_CALLBACK (notes_event_after), gpointer(this));
  g_signal_connect ((gpointer) statusbutton_attention, "clicked", G_CALLBACK (on_statusbutton_attention_clicked), gpointer(this));
  g_signal_connect ((gpointer) treeview_styles, "key_press_event", G_CALLBACK (on_treeview_styles_key_press_event), gpointer(this));
  g_signal_connect ((gpointer) treeview_styles, "button_press_event", G_CALLBACK (on_treeview_styles_button_press_event), gpointer(this));
  g_signal_connect ((gpointer) treeview_styles, "popup_menu", G_CALLBACK (on_treeview_styles_popup_menu), gpointer(this));
  g_signal_connect ((gpointer) treeview_styles, "row_collapsed", G_CALLBACK (on_treeview_styles_row_collapsed), gpointer(this));
  g_signal_connect ((gpointer) treeview_styles, "row_expanded", G_CALLBACK (on_treeview_styles_row_expanded), gpointer(this));

  gtk_window_add_accel_group (GTK_WINDOW (mainwindow), accel_group);

  gtk_label_set_mnemonic_widget (GTK_LABEL (label_note_references), textview_note_references);
  gtk_label_set_mnemonic_widget (GTK_LABEL (label_note_category), combobox_note_category);
  gtk_label_set_mnemonic_widget (GTK_LABEL (label_note_project), combobox_note_project);

  splashscreen->percentage (50);

  // Store pointer to the two text buffers to simplify later use.
  // The reference count on the buffer is not incremented; 
  // the caller of this function won't own a new reference.
  // Therefore the buffers do not need to be freed.
  editor.textbuffer_notes = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor.textview_notes));
  textbuffer_notes = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_notes));

  // Signal handlers for the undo/redo function.
  g_signal_connect ((gpointer) editor.textbuffer_text, "insert_text", G_CALLBACK (on_textbuffer_edit_insert_text), gpointer(this));
  g_signal_connect ((gpointer) editor.textbuffer_text, "delete_range", G_CALLBACK (on_textbuffer_edit_delete_text), gpointer(this));
  g_signal_connect ((gpointer) editor.textbuffer_notes, "insert_text", G_CALLBACK (on_textbuffer_edit_insert_text), gpointer(this));
  g_signal_connect ((gpointer) editor.textbuffer_notes, "delete_range", G_CALLBACK (on_textbuffer_edit_delete_text), gpointer(this));

  // Tag for highlighting search words
  editor_reference_tag = gtk_text_buffer_create_tag (editor.textbuffer_text, "referencetag", "background", "khaki", NULL);

  // Initalize some variables.
  spinbutton_book_previous_value = 0;
  spinbutton_chapter_previous_value = 0;
  spinbutton_verse_previous_value = 0;
  grab_focus_event_id = 0;
  cursor_moved_delayer_event_id = 0;
  editor_position_cursor_at_verse_event_id = 0;
  go_to_new_reference_event_id = 0;
  go_to_new_reference_active = false;
  
  // Synchronization.
  attend_to_sync_project = false;
  attend_to_sync_all = false;
  {
    int msecs = genconfig->synchronize_project_minutes() * 60000;
    sync_source_id = g_timeout_add_full (G_PRIORITY_DEFAULT, msecs, GSourceFunc (synchronize_project_timeout), gpointer(this), NULL);
  }
  if (genconfig->synchronize_on_startup()) {
    SynchronizeProjects sp (0);
    attend_to_sync_all = sp.errors;
    attention_show_hide (attend_to_sync_all);
  }
  
  splashscreen->percentage (60);
  
  // Project initialization.
  initialize_project (true);
  // The display will not properly show the cursor always, because it has not
  // yet been created fully on program startup.
  g_timeout_add (1000, GSourceFunc (on_program_startup_timeout), gpointer(this));

  splashscreen->percentage (70);

  // Get the system for tracking the Bible references up and running.
  g_timeout_add (1000, GSourceFunc (mainwindow_on_tracker_timeout), gpointer(this));
  set_sensitivity_of_navigator_buttons ();

  // Automatic saving of the file, periodiodically.
  g_timeout_add (60000, GSourceFunc (mainwindow_on_save_timeout), gpointer(this));

  // Communication with BibleTime
  g_timeout_add (100, GSourceFunc (mainwindow_on_external_programs_timeout), gpointer(this));

  // Signal handling.
  // Block the signal of a pipe error that otherwise would kill bibledit.
  signal (SIGPIPE, SIG_IGN);
  // USR1 focuses Bibledit.
  signal (SIGUSR1, SIG_IGN);

  splashscreen->percentage (80);
  
  // Load previously saved references, if any.
  References references (liststore_references, treeview_references, treecolumn_references);
  references.load ();
  references.fill_store ();

  splashscreen->percentage (100);
  
  // Initialize the notes view.
  hovering_over_link = FALSE;
  hand_cursor = NULL;
  regular_cursor = NULL;
  hand_cursor = gdk_cursor_new (GDK_HAND2);
  regular_cursor = gdk_cursor_new (GDK_XTERM);

  g_timeout_add (100, GSourceFunc (on_display_notes_timeout), gpointer(this));
  notes_redisplay ();

  // Initialize NoteEditor object.
  note_editor = NULL;

  // Start the GUI updater.
  g_timeout_add (100, GSourceFunc (on_gui_timeout), gpointer(this));
  
  // Start the undo/redo timer.
  g_timeout_add (50, GSourceFunc (on_undo_timeout), gpointer (this));

  // Start bibledit http daemon.
  http_server_start ();
  g_timeout_add (300, GSourceFunc (on_check_httpd_timeout), gpointer(this));

  // Finally: show main window.
  gtk_widget_show (mainwindow);
  
  // Get rid of the splashscreen;
  delete splashscreen;
}


MainWindow::~MainWindow ()
{
  // Show splash screen.
  SplashScreen splashscreen (0);
  splashscreen.information ("Bibledit is shutting down");
  splashscreen.percentage (10);
  
  // Save the size and position of the program window.
  // The get_position function is broken, see the gtk documentation for reasons.
  // Anyway, for just now we'll leave the variables in configuration, and we hope
  // that it will be fixed later. The problem now is that the function will
  // return the value that was set with move(x,y). If the user moves the window
  // that is not reflected here, but it will keep returning the values set
  // with move(x,y).
  // If you want to change the default values when Bibledit starts, edit
  // the configuration file
  screen_layout_window_size_save (mainwindow);
  screen_layout_panes_position_save (hpaned1, vpaned1, vpaned_editor, vpaned_references);
  
  // Hide bibledit. Note: This is done after saving the window's size/position
  // to have that done properly.
  gtk_widget_hide (mainwindow);
  // Save text in editor
  splashscreen.percentage (20);
  editor_save ();
  // Shut the word database system down.
  // Wait until it is through with everything.
  /* At first the percentage ready was shown in the splash screen, but this
     gave some kind of segmentation fault, or another fault (it was not alwasys
     the same) in Gtk. Therefore it was removed. So the user has no feedback,
     and just has to wait patiently until bibledit it through shutting down.
  */
  splashscreen.percentage (40);
  // Save references.
  References references (liststore_references, treeview_references, treecolumn_references);
  references.get_loaded ();
  references.save ();  
  // Progress.
  splashscreen.percentage (70);
  // Stop possible thread that is displaying notes.
  stop_displaying_more_notes ();
  // Stop http daemon.
  http_server_stop ();
  // Destroy the configuration.
  delete genconfig;
  // Do shutdown actions in background.
  system ("bibledit --shutdown-actions &");
  splashscreen.percentage (100);
  // Destroying the window is done by gtk itself.
}


int MainWindow::run ()
{
  return gtk_dialog_run (GTK_DIALOG (mainwindow));
}


/*
|
|
|
|
|
Initialization
|
|
|
|
|
 */


void MainWindow::close_open_project (ustring project)
{
  // If we've no project, take one currently opened.
  if (project.empty()) 
    project = genconfig->project();
  // Close current project
  close ();
  // Open desired one.
  genconfig->project_set (project);
  initialize_project (true);
}


void MainWindow::initialize_project (bool init_book_selection)
{
  // If we've no project, or the project is not there, disable the menus and knock off.
  if (genconfig->project().empty () || (!project_exists (genconfig->project()))) {
    enable_or_disable_widgets (false);
    return;
  }

  // Update the titlebar.
  set_titlebar (genconfig->project());

  // Enable the menus.
  enable_or_disable_widgets (true);
  
  // Synchronize project's data.
  if (genconfig->synchronize_project_on_open ())
    synchronize_project ();
  
  // Project data needed too.
  ProjectConfiguration projectconfig ("");
  
  // Load the stylesheet.
  genconfig->stylesheet_set (projectconfig.stylesheet());
  stylesheet_open_named (genconfig->stylesheet());

  // Variable needed otherwise the navigation rumbles too much.
  settingcombos = true;

  // Put the names of the books in the combo.
  ustring gotobook;
  vector<ustring> books = project_get_books (genconfig->project());
  combobox_set_strings (comboboxentry_book, books);
  if (books.size() > 0)
    gotobook = books[0];

  // Combo has been filled: clear the anti-rumble variable.
  settingcombos = false;

  if (project_book_exists (genconfig->project(), genconfig->book())) {
    // Set the book to the one that was opened last.
    gotobook = genconfig->book();
  } else {
    // If the book does not exist, reset chapter and verse.
    genconfig->chapter_set ("1");
    genconfig->verse_set ("1");
  }

  // If the book's not in the project, bail out.
  if (!project_book_exists (genconfig->project(), gotobook))
    return;
  
  // See whether the desired chapter is in the book.
  vector<unsigned int> chapters = project_get_chapters (genconfig->project(), gotobook);
  if (chapters.size() == 0)
    return;
  set<unsigned int> chapterset (chapters.begin(), chapters.end());
  if (chapterset.find (convert_to_int (genconfig->chapter())) == chapterset.end())
    genconfig->chapter_set (convert_to_string (chapters[0]));

  // Clear some variables so that the new book will be loaded.
  editor_current_book.clear ();
  editor_current_chapter.clear ();
  editor_current_verse.clear ();

  // Go to the new reference.
  if (!gotobook.empty ()) {
    Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
    navigation.gotoreference (gotobook, genconfig->chapter(), genconfig->verse());
    go_to_new_reference ();
  }
    
  // Clear the references tracker.
  track.clear ();

  // Appearance of text in editor.
  // The font is now tied to the project, but also stored in the general
  // configuration.
  genconfig->editor_font_name_set (projectconfig.editor_font());
  editor_set_font ();
  
  // Set the available books for search/replace functions.
  if (init_book_selection) {
    set<ustring> selection;
    for (unsigned int i = 0; i < books.size (); i++) {
      selection.insert (books[i]);
    }
    session.selected_books (selection);    
  }
}


void MainWindow::enable_or_disable_widgets (bool enable)
{
  // Depending on whether a project has been opened, make some widgets (in)sensitive.
  gtk_widget_set_sensitive (close1, enable);
  gtk_widget_set_sensitive (properties1, enable);
  gtk_widget_set_sensitive (import1, enable);
  gtk_widget_set_sensitive (notes2, enable);
  gtk_widget_set_sensitive (menuitem_edit, enable);
  gtk_widget_set_sensitive (file_references, enable);
  gtk_widget_set_sensitive (export_project, enable);
  gtk_widget_set_sensitive (menuitem_view, enable);
  gtk_widget_set_sensitive (menuitem_goto, enable);
  gtk_widget_set_sensitive (compare_with1, enable);
  gtk_widget_set_sensitive (copy_project_to, enable);
  gtk_widget_set_sensitive (comboboxentry_book, enable);
  gtk_widget_set_sensitive (comboboxentry_chapter, enable);
  gtk_widget_set_sensitive (comboboxentry_verse, enable);
  if (!enable) {
    gtk_combo_box_set_active (GTK_COMBO_BOX (comboboxentry_book), -1);
    gtk_combo_box_set_active (GTK_COMBO_BOX (comboboxentry_chapter), -1);
    gtk_combo_box_set_active (GTK_COMBO_BOX (comboboxentry_verse), -1);
  }
  gtk_widget_set_sensitive (editor.textview_text, enable);
  // If project is closed no references can be printed because no text is available.
  gtk_widget_set_sensitive (print_references, enable);
  // If project closed, no text can be printed.
  gtk_widget_set_sensitive (print_project, enable);
  
}


/*
|
|
|
|
|
Menu callbacks
|
|
|
|
|
 */


void MainWindow::on_open1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->open ();
}


void MainWindow::open ()
{
  vector<ustring> projects = projects_get_all ();
  ListviewDialog dialog ("Open project", projects, genconfig->project());
  if (dialog.run () == GTK_RESPONSE_OK) {
    close ();
    genconfig->project_set (dialog.focus);
    initialize_project (true);
  }
}


void MainWindow::on_close1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->close ();
}


void MainWindow::close ()
{
  editor_save ();
  if (genconfig->synchronize_project_on_close ())
    synchronize_project ();
  // When disabling the comboboxes, they give a signal: disable that here.
  settingcombos = true;
  enable_or_disable_widgets (false);
  settingcombos = false;
  gtk_text_buffer_set_text (editor.textbuffer_text, "", -1);
  gtk_text_buffer_set_modified (editor.textbuffer_text, false);
  editor_current_book.clear ();
  editor_current_chapter.clear ();
  editor_current_verse.clear ();
  genconfig->project_set ("");
  set_titlebar ("");
}


void MainWindow::on_new1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->newproject ();
}


void MainWindow::newproject ()
{
  ProjectDialog projectdialog (true);
  if (projectdialog.run () == GTK_RESPONSE_OK) {
    close ();
    genconfig->project_set (projectdialog.newprojectname);
    initialize_project (true);
  }
}


void MainWindow::on_print_project_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_print_project ();
}


void MainWindow::on_print_project ()
{
  if (formatter_present (mainwindow)) {
    // Save any changes.
    editor_save();
    // Run the dialog for printing the project to pdf.
    int result;
    {
      PrintProjectDialog dialog (0);
      result = dialog.run ();
    }
    if (result == GTK_RESPONSE_OK) {
      ProgressWindow progresswindow ("Printing project", true);
      view_project_pdf (progresswindow);
    }
  }
}


void MainWindow::on_properties1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->editproject ();
}


void MainWindow::editproject ()
{
  // Show project dialog.
  ProjectDialog projectdialog (false);
  if (projectdialog.run () == GTK_RESPONSE_OK) {
    // As anything could have been changed to the project, take this course:
    close ();
    genconfig->project_set (projectdialog.newprojectname);
    initialize_project (true);
  }
}


void MainWindow::on_delete1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->deleteproject ();
}


void MainWindow::deleteproject ()
{
  // Gather all projects, but leave the current one out.
  vector <ustring> all_projects = projects_get_all ();
  vector<ustring> projects;
  for (unsigned int i = 0; i < all_projects.size(); i++)
    if (all_projects[i] != genconfig->project())
      projects.push_back (all_projects[i]);
  // User interface.
  ListviewDialog dialog ("Delete project", projects, "");
  if (dialog.run () == GTK_RESPONSE_OK) {
    int result;
    result = gtkw_dialog_question (mainwindow, "Are you sure you want to delete project " + dialog.focus + "?");
    if (result == GTK_RESPONSE_YES) {
      result = gtkw_dialog_question (mainwindow, "Are you really sure to delete project " + dialog.focus + ", something worth perhaps years of work?");
    }
    if (result == GTK_RESPONSE_YES) {
      project_delete (dialog.focus);
    }
  }
}


void MainWindow::on_quit1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  gtk_main_quit ();
}


void MainWindow::on_system_log1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->viewlog ();
}


void MainWindow::viewlog ()
{
  ShowScriptDialog showscript (0);
  showscript.run ();
}


void MainWindow::on_help1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  htmlbrowser ("localhost:51516", true);
}


void MainWindow::on_about1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->showabout ();
}


void MainWindow::showabout ()
{
  gtk_show_about_dialog (GTK_WINDOW (mainwindow), "version", PACKAGE_VERSION, "website", PACKAGE_BUGREPORT, NULL);
}


void MainWindow::on_undo1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->menu_undo ();
}


void MainWindow::menu_undo ()
{
  undo.undo (editor);
}


void MainWindow::on_redo1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->menu_redo ();
}


void MainWindow::menu_redo ()
{
  undo.redo (editor);
}


void MainWindow::on_edit1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->menu_edit ();
}


void MainWindow::menu_edit ()
{
  // Set the sensitivity of the items under the edit menu.
  gtk_widget_set_sensitive (undo1, undo.can_undo ());
  gtk_widget_set_sensitive (redo1, undo.can_redo ());
  
  // At present there does not seem to be a function that indicates
  // whether and which clipboard operations are possible. Therefore
  // the Copy, Paste and Cut menus are always active.

  // Enable/disable based on whether we're editing a note.
  bool enable;
  enable = (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook1)) == 1);
  // References can only be taken from a note when it is opened.
  gtk_widget_set_sensitive (get_references_from_note, enable);
}


void MainWindow::on_find_and_replace1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->menu_replace ();
}


void MainWindow::menu_replace ()
{
  // Before finding, save the current file.
  editor_save ();
  // Start find/replace dialog.
  vector <ustring> results;
  {
    ReplaceDialog replacedialog (0);
    if (replacedialog.run () == GTK_RESPONSE_OK) {
      results.assign (replacedialog.results.begin (), replacedialog.results.end ());
      References references (liststore_references, treeview_references, treecolumn_references);
      references.set_references (replacedialog.results);
      references.fill_store ();
    } else {
      return;
    }
  }
  // Replace text.
  if (results.size ()) {
    ustring prj = genconfig->project();
    ReplacingDialog replacedialog (results);
    replacedialog.run ();
    close ();
    genconfig->project_set (prj);
    initialize_project (false);
  } else {
    gtkw_dialog_info (mainwindow, "There was nothing to replace");
  }
}


void MainWindow::on_findspecial1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->menu_findspecial ();
}


void MainWindow::menu_findspecial ()
{
  // Before finding, save the current file.
  editor_save ();
  // Switch to the References Area.
  on_file_references ();
  // Start dialog.
  {
    SearchSpecialDialog dialog (&bibletime);
    if (dialog.run () != GTK_RESPONSE_OK)
      return;
  }
  // Carry out the search. 
  search_string (liststore_references, treeview_references, treecolumn_references, &bibletime);
}


void MainWindow::on_screen_font_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_screen_font ();
}


void MainWindow::on_screen_font ()
{
  GtkWidget *font_selector;
  font_selector = gtk_font_selection_dialog_new ("Screen font");
  gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (font_selector),
                                           genconfig->editor_font_name().c_str ());
  gtk_widget_show (font_selector);
  int result = gtk_dialog_run (GTK_DIALOG (font_selector));
  ustring s = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font_selector));
  gtk_widget_destroy (font_selector);
  if (result == GTK_RESPONSE_OK) {
    genconfig->editor_font_name_set (s);
    editor_set_font ();
    ProjectConfiguration projectconfig ("");
    projectconfig.editor_font_set (genconfig->editor_font_name());
  }
}


void MainWindow::on_printer_font_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_printer_font ();
}


void MainWindow::on_printer_font ()
{
  FontDialog fontdialog (0);
  fontdialog.run();
}


void MainWindow::on_import1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->menu_import ();
}


void MainWindow::menu_import ()
{
  ImportTextDialog dialog (0);
  int result = dialog.run ();
  if (result == GTK_RESPONSE_OK) {
    ustring prj = genconfig->project();
    close ();
    genconfig->project_set (prj);
    initialize_project (true);
  }
}


gboolean MainWindow::on_mainwindow_delete_event (GtkWidget       *widget,
                                        GdkEvent        *event,
                                        gpointer         user_data)
{
/*
  This solves a bug:
  When quitting the program though the menu, all went fine.
  But when quitting the program by clicking on the cross at the top of the program,
  a segmentation fault occurred.
  This segmentation occurred in the destructor of the object MainWindow.
  In the destructor properties of GTK were accessed, which obviously were 
  already in the process of being destroyed.
  This is the solution:
  When the window receives the delete_event (somebody clicks on the cross to
  close the program), the window is not closed, but instead a timeout is 
  installed that calls qtk_main_quit after a short while.
  The destructor of the object MainWindow can not access the properties of GTK
  without a segmentation fault.
  */
  g_timeout_add (10, GSourceFunc (gtk_main_quit), user_data);
  return true;
}


gboolean MainWindow::on_mainwindow_focus_in_event (GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
{
  ((MainWindow *) user_data)->on_mainwindow_focus_in (event);
  return FALSE;
}


void MainWindow::on_mainwindow_focus_in (GdkEventFocus *event)
{
  // When bibledit receives focus, immediately after that synchronize it with 
  // external programs.
  // No longer used now.
}


void MainWindow::on_insert1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_insert ();
}


void MainWindow::on_menu_insert ()
// Sets the labels of the underlying menu items right.
{
  // Write the proper labels.
  ustring std_txt = "Standard text ";
  ustring label;
  label = std_txt + "_1: " + genconfig->edit_note_standard_text_one ();
  gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (GTK_BIN (standard_text_1))), label.c_str());
  label = std_txt + "_2: " + genconfig->edit_note_standard_text_two ();
  gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (GTK_BIN (standard_text_2))), label.c_str());
  label = std_txt + "_3: " + genconfig->edit_note_standard_text_three ();
  gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (GTK_BIN (standard_text_3))), label.c_str());
  label = std_txt + "_4: " + genconfig->edit_note_standard_text_four ();
  gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (GTK_BIN (standard_text_4))), label.c_str());
  // Enable or disable depending on situation.
  bool enable;
  enable = (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook1)) == 1);
  gtk_widget_set_sensitive (standard_text_1, enable);
  gtk_widget_set_sensitive (standard_text_2, enable);
  gtk_widget_set_sensitive (standard_text_3, enable);
  gtk_widget_set_sensitive (standard_text_4, enable);
  // Allow inserting reference when we edit a note and the reference is different 
  // from any of the references loaded already.
  enable = false;
  // Get current reference.
  ustring reference = editor_current_book + " " + editor_current_chapter + ":" + editor_current_verse;
  if (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook1)) == 1) {
    // Get all references from the note.
    vector<ustring> references;
    vector<ustring> messages;
    notes_get_references_from_editor (note_editor->textbuffer_references, references, messages);
    // See whether the current reference is already in it.
    set<ustring> refs (references.begin(), references.end());
    if (refs.find (reference) == refs.end()) {
      // No, not yet, enable menu, so user can add it.
      enable = true;
    }      
  }
  // Update menu.
  label = "_Add " + reference + " to note";
  gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (GTK_BIN (current_reference1))), label.c_str());
  gtk_widget_set_sensitive (current_reference1, enable);
}


void MainWindow::on_menuitem_view_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menuitem_view ();
}


void MainWindow::on_menuitem_view ()
{
}


void MainWindow::on_notes_preferences_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_notes_preferences ();
}


void MainWindow::on_notes_preferences ()
{
  NotesDialog dialog (0);
  dialog.run();
}


void MainWindow::on_copy_project_to_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_copy_project_to ();
}


void MainWindow::on_copy_project_to ()
{
  EntryDialog dialog ("New project name", 
                      "Enter a name of a non-existent project\nwhere this project will be copied to.",
                      "");
  if (dialog.run () == GTK_RESPONSE_OK) {
    // Does the project exist?
    if (project_exists (dialog.entered_value)) {
      // Yes, give message that project exists.
      ustring error = "Project ";
      error.append (dialog.entered_value);
      error.append (" already exists.");
      error.append ("\nIf you still intend to copy the project,");
      error.append ("\ndelete project ");
      error.append (dialog.entered_value);
      error.append (" first.");
      gtkw_dialog_error (mainwindow, error);
    } else {
      // Ok, go ahead with the copy.
      project_copy (genconfig->project(), dialog.entered_value);
      // Give message when through.
      ustring message;
      message.append ("The project has been copied to a new project\n");
      message.append ("named ");
      message.append (dialog.entered_value);
      message.append (".");
      gtkw_dialog_info (mainwindow, message);
    }
  }
}


void MainWindow::on_compare_with1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_compare_with ();
}


void MainWindow::on_compare_with ()
{
  editor_save();
  int result;
  {
    CompareDialog dialog (0);
    result = dialog.run ();
  }
  if (result == GTK_RESPONSE_OK) {
    compare_with ();
  }
}


void MainWindow::on_printingprefs_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_printing_preferences ();
}


void MainWindow::on_printing_preferences ()
{
  PrintPreferencesDialog dialog (0);
  dialog.run();
}


void MainWindow::on_formatting_objects_processor_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_formatter ();
}


void MainWindow::on_formatter ()
{
  FormatterDialog dialog (0);
  dialog.run();
}


void MainWindow::on_parallel_bible_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_parallel_bible ();
}


void MainWindow::on_parallel_bible ()
{
  {
    ParallelBibleDialog dialog (0);
    if (dialog.run () != GTK_RESPONSE_OK)
      return;
  }
  editor_save ();
  view_parallel_bible_pdf ();
}


void MainWindow::on_screen_layout_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_screen_layout ();
}


void MainWindow::on_screen_layout ()
{
  bool currentposition = genconfig->tools_area_left();
  ScreenLayoutDialog dialog (0);
  if (dialog.run () == GTK_RESPONSE_OK) {
    screen_layout_tools_area_set (currentposition, vbox_left, vbox_right, vpaned1, notebook_tools);  
    screen_layout_vertical_pane_mirror (currentposition, hpaned1);
  }
}


void MainWindow::on_prefs_books_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_prefs_books ();
}


void MainWindow::on_prefs_books ()
{
  BookDialog dialog (genconfig->project());
  if (dialog.run () == GTK_RESPONSE_OK) {
    ustring project = genconfig->project();
    close ();
    genconfig->project_set (project);
    initialize_project (true);
  }
}


void MainWindow::on_preferences_debug_activate (GtkMenuItem *menuitem,  gpointer user_data)
{
  ((MainWindow *) user_data)->on_preferences_debug ();
}


void MainWindow::on_preferences_debug ()
// Toggle debug mode.
{
  session.debug (!session.debug ());
}


/*
|
|
|
|
|
Navigation
|
|
|
|
|
 */


void MainWindow::on_combo_entry_book_changed (GtkEditable * editable, gpointer user_data)
{
  ((MainWindow *) user_data)->on_combo_book_changed ();
}


void MainWindow::on_combo_book_changed ()
{
  // If we set the book programmatically, do nothing further.
  if (settingcombos)
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.gotobook();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_combo_entry_chapter_changed (GtkEditable * editable, gpointer user_data)
{
  ((MainWindow *) user_data)->on_combo_chapter_changed ();
}


void MainWindow::on_combo_chapter_changed ()
{
  if (settingcombos)
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.gotochapter();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_combo_entry_verse_changed (GtkEditable * editable, gpointer user_data)
{
  ((MainWindow *) user_data)->on_combo_verse_changed ();
}


void MainWindow::on_combo_verse_changed ()
{
  if (settingcombos)
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.gotoverse();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_next_verse_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_next_verse ();
}


void MainWindow::goto_next_verse ()
{
  // If we're still going to another reference, bail out.
  if (go_to_new_reference_active) 
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.nextverse();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_previous_verse_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_previous_verse ();
}


void MainWindow::goto_previous_verse ()
{
  // If we're still going to another reference, bail out.
  if (go_to_new_reference_active) 
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.previousverse();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_next_chapter_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_next_chapter ();
}


void MainWindow::goto_next_chapter ()
{
  // If we're still going to another reference, bail out.
  if (go_to_new_reference_active) 
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.nextchapter();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_previous_chapter_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_previous_chapter ();
}


void MainWindow::goto_previous_chapter ()
{
  // If we're still going to another reference, bail out.
  if (go_to_new_reference_active) 
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.previouschapter();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_next_book_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_next_book ();
}


void MainWindow::goto_next_book ()
{
  // If we're still going to another reference, bail out.
  if (go_to_new_reference_active) 
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.nextbook();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_previous_book_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_previous_book ();
}


void MainWindow::goto_previous_book ()
{
  // If we're still going to another reference, bail out.
  if (go_to_new_reference_active) 
    return;
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.previousbook();
  if (navigation.changed) {
    go_to_new_reference ();
  }
}


void MainWindow::on_reference_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_reference_interactive ();
}


void MainWindow::goto_reference_interactive ()
{
  GotoReferenceDialog dialog (editor_current_book, editor_current_chapter, editor_current_verse);
  if (dialog.run () == GTK_RESPONSE_OK) {
    if (dialog.newreference) {
      Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
      navigation.gotoreference (dialog.newbook, dialog.newchapter, dialog.newverse);
      if (navigation.changed) {
        go_to_new_reference ();
      }
    }
  }
}


void MainWindow::go_to_new_reference ()
// This starts the procedure to carries out a requested change of reference.

{
  // Keep postponing the actual handler if a new positioning request was 
  // received before the previous one was processed: destroy the GSource.
  if (go_to_new_reference_event_id) {
    GSource *source = g_main_context_find_source_by_id (NULL, go_to_new_reference_event_id);
    if (source) g_source_destroy (source);
  }
  go_to_new_reference_event_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 100, GSourceFunc (go_to_new_reference_delayer), gpointer(this), NULL);
}

  
bool MainWindow::go_to_new_reference_delayer (gpointer user_data)
{
  ((MainWindow *) user_data)->go_to_new_reference_executer ();
  return false;
}


void MainWindow::go_to_new_reference_executer ()
/*
This carries out requested changes of the reference and related tasks.
*/
{
  // Set we're busy
  go_to_new_reference_active = true;
  // Find out what needs to be changed: book, chapter and/or verse.
  ustring goto_book = combobox_get_active_string (comboboxentry_book);
  bool new_book = (goto_book != editor_current_book);
  editor_current_book = goto_book;
  ustring goto_chapter = combobox_get_active_string (comboboxentry_chapter);
  bool new_chapter = (goto_chapter != editor_current_chapter);
  editor_current_chapter = goto_chapter;
  ustring goto_verse = combobox_get_active_string (comboboxentry_verse);
  bool new_verse = (goto_verse != editor_current_verse);
  editor_current_verse = goto_verse;

  // See whether the current file should be saved.
  if (new_book || new_chapter) {
    editor_save ();
  }

  // With a new book, also load a new chapter.
  if (new_book) {
    new_chapter = true;
  }
  // Deal with a new chapter.
  if (new_chapter) {
    // Load chapter, if need be.
    editor_load_chapter ();
    // When loading a new chapter, we've also a new verse.
    new_verse = true;
  }
  
  if (new_book || new_chapter || new_verse)
  {
    // Position the cursor properly.
    // The positioning will be done whenever Gtk is idle.
    // This is because sometimes Gtk is slow in loading a new chapter.
    // So if the cursor positioning is coded straight after loading,
    // it will not work, as there is no text loaded yet.
    // But here we deal with that so that a delay is no longer needed. The trick:
    // Handle all pending events in GTK.
    while (gtk_events_pending ()) gtk_main_iteration ();
    editor_position_cursor_at_verse (goto_verse);
    // Send the reference to the windows outpost. Be aware it does not take
    // verss like 10a or 10-12; it takes numbers only like 10 or 12.
    if (genconfig->reference_exchange_send_to_bibleworks())
      windowsoutpost.BibleWorksReferenceSet (goto_book, goto_chapter, number_in_string(goto_verse));
    if (genconfig->reference_exchange_send_to_santafefocus())
      windowsoutpost.SantaFeFocusReferenceSet (goto_book, goto_chapter, number_in_string(goto_verse));
    // Update the notes view.
    notes_redisplay ();
    // If there is any note, make that note visible in the textview.
    editor.footnote_body_scroll_to ();
  }
  // Okay, we're through.
  go_to_new_reference_active = false;
}
  

void MainWindow::on_textview_edit_move_cursor (GtkTextView * textview, GtkMovementStep step, gint count,
                                               gboolean extend_selection, gpointer user_data)
{
  ((MainWindow *) user_data)->on_cursor_moved_delayer ();
}


void MainWindow::on_cursor_moved_delayer ()
{
  // Keep postponing the actual handler if a new cursor movement was detected
  // before the previous one was processed: destroy the GSource.
  if (cursor_moved_delayer_event_id) {
    GSource *source = g_main_context_find_source_by_id (NULL, cursor_moved_delayer_event_id);
    if (source) g_source_destroy (source);
  }
  cursor_moved_delayer_event_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 100, GSourceFunc (on_cursor_moved_delayer_handler), gpointer(this), NULL);
}


bool MainWindow::on_cursor_moved_delayer_handler (gpointer user_data)
{
  ((MainWindow *) user_data)->on_cursor_moved ();
  return false;
}


void MainWindow::on_cursor_moved ()
/*
When the cursor has moved, the navigation system needs to be updated
so that it shows the right reference. If the user was, for example
on MAT 1:10, and the cursor moves, the move might have brought him
to another reference, though this is not necessarily so. Therefore, as we 
don't know where the user is now after the cursor moved, we need to find
it out. The book is known, the chapter is known, because both stay the same.
The only thing we don't know is the verse. 
*/
{
  // Somebody thought that in gtkmm 2.4 the move_cursor signal was useless,
  // so removed it. We need it here, so the gtkmm library cannot be used.
  // We moved to the Gtk2 library.

  static int previous_cursor_line = 0;
  /* Initializing the value to 0 instead of -1 solves a Segmentation fault 
   * exception when no document was loaded.
   */
  GtkTextIter iterator;
  gtk_text_buffer_get_iter_at_mark (editor.textbuffer_text, &iterator,
                                    gtk_text_buffer_get_insert (editor.textbuffer_text));
  int line_of_cursor = gtk_text_iter_get_line (&iterator);
  if (line_of_cursor != previous_cursor_line) {
    previous_cursor_line = line_of_cursor;
    Highlight highlight (editor.textbuffer_text, editor.textview_text);
    highlight.line_at_cursor (editor.text_line_tag);
    Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
    navigation.gotoversenumber (cursor_get_verse_number ());
    go_to_new_reference ();
  }
  
  // If there is any note, make that note visible in the textview.
  editor.footnote_body_scroll_to ();
}


void MainWindow::on_textview_edit_grab_focus (GtkWidget * widget, gpointer user_data)
{
  ((MainWindow *) user_data)->on_grab_focus ();
}


void MainWindow::on_grab_focus ()
{
  // The purpose of this is to adjust the reference to the new position,
  // wherever the user clicks in the text.
  if (focus_programmatically_being_grabbed)
    return;
  if (grab_focus_event_id) {
    GSource *source = g_main_context_find_source_by_id (NULL, grab_focus_event_id);
    if (source) g_source_destroy (source);
  }
  grab_focus_event_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 10, GSourceFunc (mainwindow_on_grab_focus_delayed_handler), gpointer(this), NULL);
}


ustring MainWindow::cursor_get_verse_number ()
/*
This gets the verse number the cursor is on.
At the time the text was loaded in the editor, we added named tags.
We retrieve these tags here and decide from the name they have, which verse
we are on.
*/
{
  // Variable for the verse.
  ustring verse = "0";
  // Get an iterator at the cursor location.
  GtkTextIter iter;
  gtk_text_buffer_get_iter_at_mark (editor.textbuffer_text, &iter, gtk_text_buffer_get_insert (editor.textbuffer_text));
  // There is a special case, and that is when we move the cursor to the very 
  // end of the textbuffer. In this case it won't give the right verse.
  // Handle this case here: Move the iterator one character back.
  GtkTextIter enditer;
  gtk_text_buffer_get_end_iter (editor.textbuffer_text, &enditer);
  if (gtk_text_iter_compare (&iter, &enditer) == 0) {
    gtk_text_iter_backward_char (&iter);
  }
  // Get all tags at this iterator and look for the named tag that has a property
  // named "verse-tag" with a value of "1". If found, the name of this tag is 
  // the verse number we are now on.
  GSList *tags = NULL, *tagp = NULL;
  tags = gtk_text_iter_get_tags (&iter);
  for (tagp = tags;  tagp != NULL;  tagp = tagp->next) {
    GtkTextTag *tag = (GtkTextTag *) tagp->data;
    gint id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "verse-tag"));
    if (id == 1) {
      gchar *strval;
      g_object_get (tag, "name", &strval, NULL);
      verse = strval;
      if (strval)
        g_free (strval);
    }
  }
  // Return the verse info found.
  return verse; 
}


void MainWindow::editor_position_cursor_at_verse (const ustring& cursorposition)
// This function starts the procedure to move the cursor of the editor to the 
// verse given.
{
  editor_position_cursor_at_verse_cursorposition = cursorposition;
  // Keep postponing the actual handler if a new positioning request was 
  // received before the previous one was processed: destroy the GSource.
  if (editor_position_cursor_at_verse_event_id) {
    GSource *source = g_main_context_find_source_by_id (NULL, editor_position_cursor_at_verse_event_id);
    if (source) g_source_destroy (source);
  }
  editor_position_cursor_at_verse_event_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 100, GSourceFunc (editor_position_cursor_at_verse_postponer_handler), gpointer(this), NULL);
}


bool MainWindow::editor_position_cursor_at_verse_postponer_handler (gpointer user_data)
{
  ((MainWindow *) user_data)->editor_position_cursor_at_verse_executer ();
  return false;
}


void MainWindow::editor_position_cursor_at_verse_executer ()
{
  // Find out whether we need to reposition the cursor. We will not move the 
  // cursor or scroll to it when the cursor is already on the right verse.
  bool reposition = (editor_position_cursor_at_verse_cursorposition.compare (cursor_get_verse_number ()));
  // When the cursor is at the end of the buffer, it usually means that the buffer has just been filled.
  // So the cursor does need to be repositioned in this case.
  GtkTextIter  cursor_iterator;
  gtk_text_buffer_get_iter_at_mark (editor.textbuffer_text, &cursor_iterator, gtk_text_buffer_get_insert (editor.textbuffer_text));
  GtkTextIter enditer;
  gtk_text_buffer_get_end_iter (editor.textbuffer_text, &enditer);
  if (gtk_text_iter_compare (&cursor_iterator, &enditer) == 0)
    reposition = true;

  // Do the repositioning if needed.
  if (reposition) {
    // Grab focus here to get the scrolling done properly, and the user can type in it.
    focus_programmatically_being_grabbed = true;
    gtk_widget_grab_focus (editor.textview_text);
    focus_programmatically_being_grabbed = false;
    if (editor_position_cursor_at_verse_cursorposition == "0") {
      // Verse 0: beginning of file.
      if (gtk_text_buffer_get_line_count (editor.textbuffer_text) > 0) {
        GtkTextIter iter;
        gtk_text_buffer_get_iter_at_line (editor.textbuffer_text, &iter, 0);
        gtk_text_buffer_place_cursor (editor.textbuffer_text, &iter);
        gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (editor.textview_text), &iter, 0.1, false, 0, 0);
        while (gtk_events_pending ()) gtk_main_iteration ();
      }
    } else {
      // Go through all the lines and find out about the verse.
      for (int i = 0; i < gtk_text_buffer_get_line_count (editor.textbuffer_text); i++) {
        GtkTextIter begin;
        GtkTextIter end;
        gtk_text_buffer_get_iter_at_line (editor.textbuffer_text, &begin, i);
        gtk_text_buffer_get_iter_at_line (editor.textbuffer_text, &end, i + 1);
        ustring verse;
        GSList *tags = NULL, *tagp = NULL;
        tags = gtk_text_iter_get_tags (&begin);
        for (tagp = tags;  tagp != NULL;  tagp = tagp->next) {
          GtkTextTag *tag = (GtkTextTag *) tagp->data;
          gint id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "verse-tag"));
          if (id == 1) {
            gchar *strval;
            g_object_get (tag, "name", &strval, NULL);
            verse = strval;
            if (strval)
              g_free (strval);
          }
        }
        if (verse == editor_position_cursor_at_verse_cursorposition) {
          // Move the cursor to it.
          // Move it to the beginning of the text, if there is any.
          int offset = 4 + verse.length ();
          ustring s = gtk_text_buffer_get_text (editor.textbuffer_text, &begin, &end, false);
          int linelength = s.length ();
          linelength--;
          if (offset >= linelength)
            offset = linelength;
          gtk_text_buffer_get_iter_at_line_offset (editor.textbuffer_text, &begin, i, offset);
          gtk_text_buffer_place_cursor (editor.textbuffer_text, &begin);
          while (gtk_events_pending ()) gtk_main_iteration ();
          // Scroll also to it. It will scroll to the beginning of the text after the verse marker.
          // Alignment is needed to put the line being edited near the top of the window.
          gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (editor.textview_text), &begin, 0.1, false, 0, 0);
          while (gtk_events_pending ()) gtk_main_iteration ();
          break;
        }
      }
    }
  }

  // Highlight line at cursor and searchwords.
  Highlight highlight (editor.textbuffer_text, editor.textview_text);
  highlight.line_at_cursor (editor.text_line_tag);
  highlight.searchwords (editor_reference_tag, editor_position_cursor_at_verse_cursorposition);
}


void MainWindow::on_synchronize_other_programs2_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_synchronize_other_programs ();
}


void MainWindow::on_synchronize_other_programs ()
{
  if (genconfig->reference_exchange_send_to_bibleworks())
    windowsoutpost.BibleWorksReferenceSet (editor_current_book, editor_current_chapter, editor_current_verse);
  if (genconfig->reference_exchange_send_to_santafefocus())
    windowsoutpost.SantaFeFocusReferenceSet (editor_current_book, editor_current_chapter, editor_current_verse);
  if (genconfig->reference_exchange_send_to_bibletime())
    bibletime.sendreference (editor_current_book, editor_current_chapter, editor_current_verse);
}


void MainWindow::on_spinbutton_book_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
{
  ((MainWindow *) user_data)->on_spinbutton_book ();
}


void MainWindow::on_spinbutton_chapter_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
{
  ((MainWindow *) user_data)->on_spinbutton_chapter ();
}


void MainWindow::on_spinbutton_verse_value_changed (GtkSpinButton *spinbutton, gpointer user_data)
{
  ((MainWindow *) user_data)->on_spinbutton_verse ();
}


void MainWindow::on_spinbutton_book ()
{
  if (settingcombos)
    return;
  int value = int (gtk_adjustment_get_value (GTK_ADJUSTMENT (spinbutton_book_adj)));
  bool nextbook = (value < spinbutton_book_previous_value);
  unsigned int amount = abs (value - spinbutton_book_previous_value);
  for (unsigned int i = 0; i < amount; i++) {
    Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
    if (nextbook)
      navigation.nextbook();
    else
      navigation.previousbook();
    if (navigation.changed) {
      go_to_new_reference ();
    }
  }
  spinbutton_book_previous_value = value;
}


void MainWindow::on_spinbutton_chapter ()
{
  if (settingcombos)
    return;
  int value = int (gtk_adjustment_get_value (GTK_ADJUSTMENT (spinbutton_chapter_adj)));
  bool nextchapter = (value < spinbutton_chapter_previous_value);
  unsigned int amount = abs (value - spinbutton_chapter_previous_value);
  for (unsigned int i = 0; i < amount; i++) {
    Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
    if (nextchapter)
      navigation.nextchapter();
    else
      navigation.previouschapter();
    if (navigation.changed) {
      go_to_new_reference ();
    }
  }
  spinbutton_chapter_previous_value = value;
}


void MainWindow::on_spinbutton_verse ()
{
  if (settingcombos)
    return;
  int value = int (gtk_adjustment_get_value (GTK_ADJUSTMENT (spinbutton_verse_adj)));
  bool nextverse = (value < spinbutton_verse_previous_value);
  unsigned int amount = abs (value - spinbutton_verse_previous_value);
  for (unsigned int i = 0; i < amount; i++) {
    Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
    if (nextverse)
      navigation.nextverse();
    else
      navigation.previousverse();
    if (navigation.changed) {
      go_to_new_reference ();
    }
  }
  spinbutton_verse_previous_value = value;
}


bool MainWindow::on_program_startup_timeout (gpointer data)
{
  ((MainWindow *) data)->on_program_startup ();
  return false;
}


void MainWindow::on_program_startup ()
{
  // Scroll to the locaton of the cursor.
  GtkTextIter iter;
  gtk_text_buffer_get_iter_at_mark (editor.textbuffer_text, &iter, gtk_text_buffer_get_insert (editor.textbuffer_text));
  gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (editor.textview_text), &iter, 0.1, false, 0, 0);
}


/*
|
|
|
|
|
Tracker
|
|
|
|
|
 */


void MainWindow::on_button_forward_clicked (GtkButton * button, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_next_reference ();
}


void MainWindow::on_next_reference_in_history1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_next_reference ();
}


void MainWindow::goto_next_reference ()
{
  set_next_or_previous_reference (true);
}


void MainWindow::on_button_back_clicked (GtkButton * button, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_previous_reference ();
}


void MainWindow::on_previous_reference_in_history1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->goto_previous_reference ();
}


void MainWindow::goto_previous_reference ()
{
  set_next_or_previous_reference (false);
}


void MainWindow::set_sensitivity_of_navigator_buttons ()
{
  // Enables or disables each navigator button, depending on whether references for it are available.
  gtk_widget_set_sensitive (button_back, track.previous_reference_available ());
  gtk_widget_set_sensitive (button_forward, track.next_reference_available ());
  gtk_widget_set_sensitive (previous_reference_in_history1, track.previous_reference_available ());
  gtk_widget_set_sensitive (next_reference_in_history1, track.next_reference_available ());
}


bool MainWindow::mainwindow_on_tracker_timeout (gpointer data)
{
  return ((MainWindow *) data)->on_tracker_timeout ();
}


bool MainWindow::on_tracker_timeout ()
{
  // Drive the Bible reference tracker.
  track.tick (combobox_get_active_string (comboboxentry_book),
              combobox_get_active_string (comboboxentry_chapter),
              combobox_get_active_string (comboboxentry_verse));
  set_sensitivity_of_navigator_buttons ();
  return true;
}


void MainWindow::set_next_or_previous_reference (bool next)
{
  ustring book;
  ustring chapter;
  ustring verse;
  if (next)
    track.get_next_reference (book, chapter, verse);
  else
    track.get_previous_reference (book, chapter, verse);
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.gotoreference (book, chapter, verse);
  if (navigation.changed) {
    go_to_new_reference ();
  }
  set_sensitivity_of_navigator_buttons ();
}


bool MainWindow::mainwindow_on_grab_focus_delayed_handler (gpointer data)
{
  return ((MainWindow *) data)->on_grab_focus_delayed_handler ();
}


bool MainWindow::on_grab_focus_delayed_handler ()
/*
If the user clicks in the editor window, and straight after that
the verse where the cursor is, is asked, we get a reply 
indicating the verse where the cursor was prior to clicking.
This delayed handler solves that.
*/
{
  // Update the navigation system.
  Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
  navigation.gotoversenumber (cursor_get_verse_number ());
  Highlight highlight (editor.textbuffer_text, editor.textview_text);
  highlight.line_at_cursor (editor.text_line_tag);
  go_to_new_reference ();

  // If there is any note, make that note visible in the textview.
  editor.footnote_body_scroll_to ();

  return false;
}


void MainWindow::on_text_area1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_text_area_activate();
}


void MainWindow::on_text_area_activate ()
{
  gtk_widget_grab_focus (editor.textview_text);
}


void MainWindow::on_goto_bible_notes_area1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_bible_notes_area_activate();
}


void MainWindow::on_bible_notes_area_activate ()
{
  gtk_widget_grab_focus (editor.textview_notes);
}


void MainWindow::on_tools_area1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_tools_area_activate();
}


void MainWindow::on_tools_area_activate ()
{
  // See who's got focus.
  bool refs_focused = GTK_WIDGET_HAS_FOCUS (treeview_references);
  bool styles_focused = GTK_WIDGET_HAS_FOCUS (treeview_styles);
  bool note_focused = GTK_WIDGET_HAS_FOCUS (combobox_note_category)
                    | GTK_WIDGET_HAS_FOCUS (textview_note_references)
                    | GTK_WIDGET_HAS_FOCUS (combobox_note_project)
                    | GTK_WIDGET_HAS_FOCUS (textview_note_logbook);
  // If the references have focus now, switch to the styles.
  if (refs_focused) {
    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 1);
    gtk_widget_grab_focus (treeview_styles);      
  }
  // If the styles have focus now, switch to the note parts.
  else if (styles_focused) {
    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 2);
    gtk_widget_grab_focus (textview_note_references);
  }
  // If the note parts have focus now, switch to the references.
  else if (note_focused) {
    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 0);
    gtk_widget_grab_focus (treeview_references);
  }
  // If none has focus, focus the one that currently shows.
  else {
    switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook_tools))) {
      case 0:
        gtk_widget_grab_focus (treeview_references);
        break;
      case 1:
        gtk_widget_grab_focus (treeview_styles);      
        break;
      case 2:
        gtk_widget_grab_focus (textview_note_references);      
        break;
    }
  }    
}


void MainWindow::on_notes_area1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_notes_area_activate();
}


void MainWindow::on_notes_area_activate ()
{
  if (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook1)) == 0)
    gtk_widget_grab_focus (textview_notes);
  else
    gtk_widget_grab_focus (textview_note);
}


/*
|
|
|
|
|
Editing
|
|
|
|
|
 */


void MainWindow::editor_load_chapter ()
// Loads the chapter in the editor.
{
  editor.chapter_load (convert_to_int (combobox_get_active_string (comboboxentry_chapter)), NULL);
  undo.clear (editor);
}


void MainWindow::editor_save ()
// Save the book if it has been changed in the editor.
{
  editor.chapter_save ();
}


bool MainWindow::mainwindow_on_save_timeout (gpointer data)
{
  return ((MainWindow *) data)->on_save_timeout ();
}


bool MainWindow::on_save_timeout ()
{
  editor_save ();
  return true;
}


void MainWindow::editor_set_font ()
{
  PangoFontDescription *font_desc = NULL;
  font_desc = pango_font_description_from_string (genconfig->editor_font_name().c_str ());
  // Text editors gets this font.
  gtk_widget_modify_font (editor.textview_text, font_desc);
  // Translation note editor gets this font also.
  gtk_widget_modify_font (textview_notes, font_desc);
  gtk_widget_modify_font (textview_note, font_desc);
  // Footnote editors have this font, but smaller.
  gint fontsize = pango_font_description_get_size (font_desc);
  fontsize = gint (fontsize * PANGO_SCALE_SMALL);
  pango_font_description_set_size (font_desc, fontsize);
  gtk_widget_modify_font (editor.textview_notes, font_desc);
  // Free memory.
  pango_font_description_free (font_desc);
}


/*
|
|
|
|
|
Clipboard
|
|
|
|
|
 */


void MainWindow::on_cut1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_cut ();
}


void MainWindow::on_cut ()
{
  GtkClipboard *clipboard;
  clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
  if (GTK_WIDGET_HAS_FOCUS (editor.textview_text)) {
    // Copy usfm code to clipboard.
    ustring code (editor.text_get_selection ());
    gtk_clipboard_set_text (clipboard, code.c_str(), -1);    
    // Remove text from editor.
    GtkTextIter startiter, enditer;
    gtk_text_buffer_get_iter_at_mark (editor.textbuffer_text, &startiter, gtk_text_buffer_get_insert (editor.textbuffer_text));
    gtk_text_buffer_get_iter_at_mark (editor.textbuffer_text, &enditer, gtk_text_buffer_get_selection_bound (editor.textbuffer_text));
    gtk_text_buffer_delete (editor.textbuffer_text, &startiter, &enditer);
    // Reformat text
    editor.format ();
  }
  if (GTK_WIDGET_HAS_FOCUS (editor.textview_notes)) {
    gtk_text_buffer_cut_clipboard (editor.textbuffer_notes, clipboard, true);
  }
  if (GTK_WIDGET_HAS_FOCUS (textview_notes))
    gtk_text_buffer_cut_clipboard (textbuffer_notes, clipboard, true);
  if (GTK_WIDGET_HAS_FOCUS (textview_note))
    gtk_text_buffer_cut_clipboard (note_editor->textbuffer_note, clipboard, true);
  if (GTK_WIDGET_HAS_FOCUS (textview_note_references))
    gtk_text_buffer_cut_clipboard (note_editor->textbuffer_references, clipboard, true);
}


void MainWindow::on_copy1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_copy ();
}


void MainWindow::on_copy ()
{
  GtkClipboard *clipboard;
  clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
  if (GTK_WIDGET_HAS_FOCUS (editor.textview_text)) {
    // In case of the text editor, we cannot jut copy text to the clipboard, but
    // we copy the usfm code instead.
    gtk_clipboard_set_text (clipboard, editor.text_get_selection ().c_str(), -1);
  }
  if (GTK_WIDGET_HAS_FOCUS (editor.textview_notes)) {
    gtk_text_buffer_copy_clipboard (editor.textbuffer_notes, clipboard);
  }
  if (GTK_WIDGET_HAS_FOCUS (textview_notes))
    gtk_text_buffer_copy_clipboard (textbuffer_notes, clipboard);
  if (GTK_WIDGET_HAS_FOCUS (textview_note))
    gtk_text_buffer_copy_clipboard (note_editor->textbuffer_note, clipboard);
  if (GTK_WIDGET_HAS_FOCUS (textview_note_references))
    gtk_text_buffer_copy_clipboard (note_editor->textbuffer_references, clipboard);
}


void MainWindow::on_paste1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_paste ();
}


void MainWindow::on_paste ()
{
  GtkClipboard *clipboard;
  clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
  if (GTK_WIDGET_HAS_FOCUS (editor.textview_text)) {
    gtk_text_buffer_paste_clipboard (editor.textbuffer_text, clipboard, NULL, true);
    editor.format (); 
  }
  if (GTK_WIDGET_HAS_FOCUS (editor.textview_notes)) {
    gtk_text_buffer_paste_clipboard (editor.textbuffer_notes, clipboard, NULL, true);
  }
  if (GTK_WIDGET_HAS_FOCUS (textview_notes))
    gtk_text_buffer_paste_clipboard (textbuffer_notes, clipboard, NULL, true);
  if (GTK_WIDGET_HAS_FOCUS (textview_note))
    gtk_text_buffer_paste_clipboard (note_editor->textbuffer_note, clipboard, NULL, true);
  if (GTK_WIDGET_HAS_FOCUS (textview_note_references))
    gtk_text_buffer_paste_clipboard (note_editor->textbuffer_references, clipboard, NULL, true);
}


/*
|
|
|
|
|
Backups
|
|
|
|
|
 */


/*
|
|
|
|
|
Tools Area
|
|
|
|
|
 */


void MainWindow::on_notebook_tools_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer user_data)
{
  ((MainWindow *) user_data)->notebook_tools_switch_page (page_num);  
}


void MainWindow::notebook_tools_switch_page (guint page_num)
{
  // Store the page number in the configuration.
  genconfig->tools_area_page_number_set (page_num);
  // If the user switches to another page, and the note is being edited, do not 
  // return to the page displayed previously, but leave it as it is.
  if (note_editor)
    note_editor->previous_tools_page = -1;
}


void MainWindow::on_file_references_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_file_references ();
}


void MainWindow::on_file_references ()
{
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 0);
}




/*
|
|
|
|
|
List store and reference handling
|
|
|
|
|
 */


gboolean MainWindow::on_treeview_references_key_press_event (GtkWidget * widget, GdkEventKey * event, gpointer user_data)
{
  /* Pressing Return on the keyboard, or Enter on the numerical keypad
   * make us go to the reference.
   */
  if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter)
    ((MainWindow *) user_data)->on_list_goto ();
  // Pressing Delete takes the reference(s) out that have been selected.
  if (event->keyval == GDK_Delete || event->keyval == GDK_KP_Delete)
    ((MainWindow *) user_data)->on_delete_references ();
  return FALSE;
}


gboolean MainWindow::on_treeview_references_button_press_event (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
  // Double-clicking a references makes us go to the reference.
  if (event->type == GDK_2BUTTON_PRESS) {
    ((MainWindow *) user_data)->on_list_goto ();
    return true;
  }
  // Popup menu handler.
  if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
    ((MainWindow *) user_data)->show_references_popup_menu (widget, event);
    return true;
  }  
  return false;
}


void MainWindow::on_list_goto ()
// Handler for when the user pressed Enter in the list and wants to go to a reference.
{
  try
  {
    // Get the string the user selected.
    GtkTreeSelection *selection;
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_references));
    gtk_tree_selection_selected_foreach (selection, mainwindow_selection_foreach_function, gpointer(this));
    // Decode into book, chapter and verse.
    ustring book;
    ustring chapter;
    ustring verse;
    decode_reference (selected_reference, book, chapter, verse);
    // Jump to the reference.
    Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
    navigation.gotoreference (book, chapter, verse);
    if (navigation.changed) {
      go_to_new_reference ();
    }
  }
  catch (exception & ex)
  {
    cerr << ex.what () << endl;
  }
}


void MainWindow::mainwindow_selection_foreach_function (GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data)
{
  gchar *book;
  gtk_tree_model_get (model, iter, 0, &book, -1);
  ((MainWindow *) data)->selected_reference = book;
  g_free (book);
}


void MainWindow::on_open_references1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_open_references ();
}


void MainWindow::on_open_references ()
{
  GtkWidget *dialog;
  dialog = gtk_file_chooser_dialog_new ("Open File", GTK_WINDOW (mainwindow),
    GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
    GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
  gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), genconfig->references_file().c_str ());
  int result = gtk_dialog_run (GTK_DIALOG (dialog));
  if (result == GTK_RESPONSE_ACCEPT) {
    ustring s = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
    // Allow for up to three words to search for in these references.
    ustring searchword1, searchword2, searchword3;
    vector <ustring> import_references_searchwords = session.import_references_searchwords ();
    for (unsigned int i = 0; i < import_references_searchwords.size(); i++) {
      if (i == 0) searchword1 = import_references_searchwords[i];
      if (i == 1) searchword2 = import_references_searchwords[i];
      if (i == 2) searchword3 = import_references_searchwords[i];
    }
    Entry3Dialog dialog2 ("Search for", true, "Optionally enter _1st searchword", searchword1, "Optionally enter _2nd searchword", searchword2, "Optioanlly enter _3rd searchword", searchword3);
    result = dialog2.run();
    if (result == GTK_RESPONSE_OK) {
      searchword1 = dialog2.entered_value1;
      searchword2 = dialog2.entered_value2;
      searchword3 = dialog2.entered_value3;
      import_references_searchwords.clear();
      if (!searchword1.empty())
        import_references_searchwords.push_back (searchword1);
      if (!searchword2.empty())
        import_references_searchwords.push_back (searchword2);
      if (!searchword3.empty())
        import_references_searchwords.push_back (searchword3);
      session.import_references_searchwords (import_references_searchwords);
      genconfig->references_file_set (s);
      References references (liststore_references, treeview_references, treecolumn_references);
      references.load (genconfig->references_file());
      references.fill_store ();
      if (import_references_searchwords.size() > 0) {
        session.highlights_clear();
        for (unsigned int i = 0; i < import_references_searchwords.size(); i++)
          session.highlights_add (import_references_searchwords[i], false, false, false, false, atRaw, false, false, false, false, false, false, false, false);
      }
    }
  }
  gtk_widget_destroy (dialog);
}


void MainWindow::on_references_save_as_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_save_references ();
}


void MainWindow::on_save_references ()
{
  try
  {
    GtkWidget *dialog;
    dialog = gtk_file_chooser_dialog_new ("Save to a file", GTK_WINDOW (mainwindow),
      GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
    gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), genconfig->references_file().c_str ());
    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
      ustring s = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
      genconfig->references_file_set (s);
      References references (liststore_references, treeview_references, treecolumn_references);
      // Hack: set references with a dummy, then load the real ones from the editor.
      vector <ustring> dummy;
      references.set_references (dummy);
      references.get_loaded ();
      references.save (s);
    }
    gtk_widget_destroy (dialog);  
  }
  catch (exception & ex)
  {
    cerr << "Saving references: " << ex.what () << endl;
  }
}


void MainWindow::on_print_references_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_print_references ();
}


void MainWindow::on_print_references ()
{
  // Activate references area.
  on_file_references ();
  // Is our formatter there?
  if (formatter_present (mainwindow)) {
    // Save any changes.
    editor_save();
    // Load refs from the editor.
    References references (liststore_references, treeview_references, treecolumn_references);
    references.get_loaded();
    vector<ustring> refs;
    references.get_references (refs);
    if (refs.empty()) {
      gtkw_dialog_info (mainwindow, "There are no references to print");
    } else {
      // Run the function for printing the references.
      ProgressWindow progresswindow ("Printing references", true);
      view_references_pdf (refs, progresswindow);
    }
  }
}


void MainWindow::on_close_references_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_clear_references ();
}


void MainWindow::on_clear_references ()
{
  References references (liststore_references, treeview_references, treecolumn_references);
  references.fill_store ();
  session.highlights_clear ();
}


void MainWindow::on_delete_references_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_delete_references ();
}


void MainWindow::on_delete_references ()
{
  // Delete each selected row.
  GtkTreeSelection *selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_references));
  vector < GtkTreeIter > iters;
  gtk_tree_selection_selected_foreach (selection, MainWindow::on_references_collect_iters, gpointer (&iters));
  for (unsigned int i = 0; i < iters.size (); i++)
  {
    GtkTreeIter iter = iters[i];
    gtk_list_store_remove (liststore_references, &iter);
  }
  // Update heading.
  References references (liststore_references, treeview_references, treecolumn_references);
  references.get_loaded ();
  references.set_header ();
}


void MainWindow::on_references_collect_iters (GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, gpointer data)
{
  ((vector < GtkTreeIter > *)data)->push_back (*iter);
}


void MainWindow::on_next_reference1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_next_reference ();
}


void MainWindow::on_next_reference ()
{
  /* 
   * This goes to the next reference, if there is any.
   * If no item has been selected it chooses the first, if it's there.
   */
  // Show references area.
  on_file_references ();
  // Select next reference in the list.
  References references (liststore_references, treeview_references, treecolumn_references);
  references.goto_next ();
  // Actually open the reference in the editor.
  on_list_goto ();
}


void MainWindow::on_previous_reference1_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_previous_reference ();
}


void MainWindow::on_previous_reference ()
{
  /* 
   * This goes to the previous reference, if there is any.
   * If no item has been selected it chooses the first, if it's there.
   */
  // Show references area.
  on_file_references ();
  // Select previous reference in the list.
  References references (liststore_references, treeview_references, treecolumn_references);
  references.goto_previous ();
  // Actually open the reference in the editor.
  on_list_goto ();
}


void MainWindow::on_ignored_references1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_ignored_references ();
}


void MainWindow::on_ignored_references ()
{
  vector<ustring> hidden_references;
  hidden_references = references_hidden_ones_load ();
  EditListDialog dialog (&hidden_references, "Hidden references", 
    "of references and comments that will never be shown in the reference area.",
    true, false, true, false, false, false);
  if (dialog.run() == GTK_RESPONSE_OK)
    references_hidden_ones_save (hidden_references);
}


gboolean MainWindow::on_treeview_references_popup_menu (GtkWidget *widget, gpointer user_data)
{
  ((MainWindow *) user_data)->treeview_references_popup_menu (widget);
  return true; // Do not call the original handler.
}


void MainWindow::treeview_references_popup_menu (GtkWidget *widget)
{
  show_references_popup_menu (widget, NULL);
}


void MainWindow::on_reference_hide_activate (GtkMenuItem * menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_reference_hide ();
}


void MainWindow::on_reference_hide ()
// Deals with hiding references.
{
  // Load currently hidden references.
  vector <ustring> hidden_references;
  hidden_references = references_hidden_ones_load ();
  // Get the model.
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_references));
  // Get all selected iterators.
  GtkTreeSelection *selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_references));
  vector < GtkTreeIter > iters;
  gtk_tree_selection_selected_foreach (selection, MainWindow::on_references_collect_iters, gpointer (&iters));
  // Get the strings describing the references, and add them to the ones already loaded.
  for (unsigned int i = 0; i < iters.size (); i++)
  {
    ustring hidden_reference;
    gchar *str_data1;
    gchar *str_data2;
    gtk_tree_model_get (model, &iters[i], 0, &str_data1, 1, &str_data2, -1);
    hidden_reference = str_data1;
    hidden_reference.append (" ");
    hidden_reference.append (str_data2);
    g_free (str_data1);
    g_free (str_data2);
    hidden_references.push_back (hidden_reference);
  }
  // Save new list of hidden refs.
  references_hidden_ones_save (hidden_references);
  // Actually delete them from the window, for user feedback.
  on_delete_references ();
}


void MainWindow::show_references_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
{
  int button, event_time;
  if (event) {
    button = event->button;
    event_time = event->time;
  } else {
    button = 0;
    event_time = gtk_get_current_event_time ();
  }
  gtk_menu_popup (GTK_MENU (file_references_menu), NULL, NULL, NULL, NULL, button, event_time);
}


gboolean MainWindow::on_treeview_references_move_cursor (GtkTreeView *treeview, GtkMovementStep step, gint count, gpointer user_data)
{
  return false;
}


void MainWindow::on_treeview_references_cursor_changed (GtkTreeView *treeview, gpointer user_data)
{
  ((MainWindow *) user_data)->treeview_references_display_quick_reference ();
}


void MainWindow::treeview_references_display_quick_reference ()
{
  // Clear the quick reference area.
  GtkTextBuffer * buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_quick_refs));
  gtk_text_buffer_set_text (buffer, "", 0);
  // Get the model.
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_references));
  // Get all selected iterators.
  GtkTreeSelection *selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_references));
  vector <GtkTreeIter> iters;
  gtk_tree_selection_selected_foreach (selection, MainWindow::on_references_collect_iters, gpointer (&iters));
  // Get the first selected reference, if there is any.
  if (iters.size() == 0)
    return;
  ustring reference;
  gchar *str_data;
  gtk_tree_model_get (model, &iters[0], 0, &str_data, -1);
  reference = str_data;
  g_free (str_data);
  // Get the reference decoded.
  ustring book, chapter, verse;
  decode_reference (reference, book, chapter, verse);
  // Get / display the verse.
  ustring text;
  text = project_retrieve_verse (genconfig->project(), book, convert_to_int (chapter), verse);
  gtk_text_buffer_insert_at_cursor (buffer, text.c_str (), -1);
  gtk_text_buffer_insert_at_cursor (buffer, "\n", -1);
}


/*
|
|
|
|
|
Undo / Redo
|
|
|
|
|
 */


void MainWindow::on_textbuffer_edit_insert_text (GtkTextBuffer * textbuffer, GtkTextIter * arg1, gchar * arg2, gint arg3, gpointer user_data)
{
  // As the documentation of this callback is not so good (gtk+ 2.6 was checked),
  // here follows some extra info.
  // textbuffer is the buffer where the text was inserted.
  // arg1 is the iterator pointing to the location where the insert was done.
  // arg2 is the string that was inserted.
  // arg3 is the length of the string that was inserted.
  ((MainWindow *) user_data)->on_textbuffer_edit_insert_delete ();
}


void MainWindow::on_textbuffer_edit_delete_text (GtkTextBuffer * textbuffer, GtkTextIter * arg1, GtkTextIter * arg2, gpointer user_data)
{
  // As the documentation of this callback is not so good (gtk+ 2.6 was checked),
  // here follows some extra info.
  // textbuffer is the buffer where text was deleted from.
  // arg1 is the iterator pointing to the beginning of the text to be deleted.
  // arg2 is the iterator pointing to the end of the text to be deleted.
  // Function is called before the actual delete operation takes place.
  ((MainWindow *) user_data)->on_textbuffer_edit_insert_delete ();
}


void MainWindow::on_textbuffer_edit_insert_delete ()
// Gets fired on inserting or deleting text in editor.
{
  undo.text_changed (editor);
}


bool MainWindow::on_undo_timeout (gpointer data)
{
  return ((MainWindow *) data)->undo_timeout ();
}


bool MainWindow::undo_timeout ()
{
  if (undo.tick ()) {
    undo.store_snapshot (editor);
  }
  // Timer keeps going.
  return true;
}


/*
|
|
|
|
|
Bibledit Windows Outpost
BibleTime
|
|
|
|
|
*/


bool MainWindow::mainwindow_on_external_programs_timeout (gpointer data)
{
  return ((MainWindow *) data)->on_external_programs_timeout ();
}


bool MainWindow::on_external_programs_timeout ()
{
  // Deal with exchanging references between Bibledit and BibleTime.
  // The trick of the trade here is that we look which of the two made a change.
  // If Bibledit made a change, then it sends its reference to BibleTime.
  // And vice versa.
  // This avoids race conditions, i.e. they keep sending
  // references to each other, and the reference keeps changing between the 
  // one Bibledit had and the one BibleTime had.
  
  // A reference is taken from BibleTime only when it changed reference.
  bool got_new_reference = false;
  if (genconfig->reference_exchange_receive_from_bibletime()) {
    ustring btbook, btchapter, btverse;
    bool got_reference = false;
    got_reference = bibletime.getreference (btbook, btchapter, btverse);
    if (got_reference) {
      ustring new_reference;
      new_reference = btbook + btchapter + btverse;
      if (new_reference != bibletime_previous_reference) {
        bibletime_previous_reference = new_reference;
        Navigation navigation (comboboxentry_book, comboboxentry_chapter, comboboxentry_verse, &settingcombos);
        navigation.gotoreference (btbook, btchapter, btverse);
        if (navigation.changed) {
          go_to_new_reference ();
        }
        got_new_reference = true;
      }
    }
  }

  // The reference is sent to BibleTime only after it changed.
  // But when we received a new reference, nothing will be sent, 
  // to avoid the race condition, that both Bibledit and BibleTime keep 
  // changing between two references on their own.
  if (!got_new_reference) {
    if (genconfig->reference_exchange_send_to_bibletime()) {
      ustring bibledit_bt_new_reference = editor_current_book + editor_current_chapter + editor_current_verse;
      if (bibledit_bt_new_reference != bibledit_bt_previous_reference) {
        bibledit_bt_previous_reference = bibledit_bt_new_reference;
        bibletime.sendreference (editor_current_book, editor_current_chapter, editor_current_verse);
      }    
    }
  }

  return true;
}


void MainWindow::on_reference_exchange1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_reference_exchange ();
}


void MainWindow::on_reference_exchange ()
{
  ReferenceExchangeDialog dialog (0);
  dialog.run();
}


gboolean MainWindow::on_textview_edit_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  ((MainWindow *) user_data)->on_texteditor_click (widget, event);
  return FALSE;
}


gboolean MainWindow::on_textview_footnotes_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  ((MainWindow *) user_data)->on_texteditor_click (widget, event);
  return FALSE;
}


void MainWindow::on_texteditor_click (GtkWidget * widget, GdkEventButton *event)
{
  // Double-clicking sends the word to Toolbox.
  if (event->type == GDK_2BUTTON_PRESS) {
    // Get the textbuffer.
    GtkTextBuffer * textbuffer = NULL;
    if (widget == editor.textview_text)
      textbuffer = editor.textbuffer_text;
    if (widget == editor.textview_notes)
      textbuffer = editor.textbuffer_notes;
    // Proceed if buffer found.
    if (textbuffer) {
      // Get the word.
      GtkTextIter enditer;
      GtkTextIter startiter;
      gtk_text_buffer_get_iter_at_mark (textbuffer, &enditer, gtk_text_buffer_get_insert (textbuffer));
      if (!gtk_text_iter_ends_word (&enditer))
        gtk_text_iter_forward_word_end (&enditer);
      startiter = enditer;
      gtk_text_iter_backward_word_start (&startiter);
      ustring word = gtk_text_buffer_get_text (textbuffer, &startiter, &enditer, false);
      // Send it to toolbox.
      send_word_to_toolbox (word);
    }
  }
}


void MainWindow::send_word_to_toolbox (const ustring& word)
{
  gw_message ("Sending to Toolbox: " + word);
  windowsoutpost.SantaFeFocusWordSet (word);
}


/*
|
|
|
|
|
Title bar and status bar
|
|
|
|
|
*/


void MainWindow::set_titlebar (const ustring& project)
{
  ustring title ("Bibledit");
  if (project.length() > 0) title.append (" - " + project);
  gtk_window_set_title (GTK_WINDOW (mainwindow), title.c_str());
}


/*
int context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar1), "");
gtk_statusbar_push (GTK_STATUSBAR (statusbar1), context_id, configuration->project.c_str ());
*/


bool MainWindow::on_gui_timeout (gpointer data)
{
  ((MainWindow *) data)->on_gui ();
  return true;
}


void MainWindow::on_gui ()
{
  // The accelerators for undo and redo (Control(+Shift)-Z) stop working after
  // the widget has been set to insensitive and back to sensitive again.
  // As this may happen often, here we keep setting the accelerators.
  gtk_widget_remove_accelerator (undo1, accel_group, GDK_Z, GDK_CONTROL_MASK);
  gtk_widget_add_accelerator (undo1, "activate", accel_group, GDK_Z, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
  gtk_widget_remove_accelerator (redo1, accel_group, GDK_Z, GdkModifierType (GDK_CONTROL_MASK | GDK_SHIFT_MASK));
  gtk_widget_add_accelerator (redo1, "activate", accel_group, GDK_Z, GdkModifierType (GDK_CONTROL_MASK | GDK_SHIFT_MASK), GTK_ACCEL_VISIBLE);
}


/*
|
|
|
|
|
Notes editor
|
|
|
|
|
 */


gboolean MainWindow::notes_motion_notify_event (GtkWidget *text_view, GdkEventMotion *event, gpointer user_data)
{
  return ((MainWindow *) user_data)->on_notes_pointer_moved (text_view, event);
}


gboolean MainWindow::on_notes_pointer_moved (GtkWidget *text_view, GdkEventMotion *event)
// Update the cursor image if the pointer moved. 
{
  gint x, y;
  gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET,
                                         gint(event->x), gint(event->y), &x, &y);
  set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
  gdk_window_get_pointer (text_view->window, NULL, NULL, NULL);
  return false;
}


void MainWindow::set_cursor_if_appropriate (GtkTextView *text_view, gint x, gint y)
/* Looks at all tags covering the position (x, y) in the text view, 
 * and if one of them is a link, change the cursor to the "hands" cursor
 * typically used by web browsers.
 */
{
  GSList *tags = NULL, *tagp = NULL;
  GtkTextBuffer *buffer;
  GtkTextIter iter;
  gboolean hovering = FALSE;
  buffer = gtk_text_view_get_buffer (text_view);
  gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
  tags = gtk_text_iter_get_tags (&iter);
  for (tagp = tags;  tagp != NULL;  tagp = tagp->next) {
    GtkTextTag *tag = (GtkTextTag *) tagp->data;
    gint id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "id"));
    if (id != 0) {
      hovering = TRUE;
      break;
    }
  }
  if (hovering != hovering_over_link) {
    hovering_over_link = hovering;
    if (hovering_over_link)
      gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor);
    else
      gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor);
  }
  if (tags) 
    g_slist_free (tags);
}


gboolean MainWindow::visibility_notify_event (GtkWidget *text_view, GdkEventVisibility *event, gpointer user_data)
{
  return ((MainWindow *) user_data)->on_visibility_notified (text_view, event);
}


gboolean MainWindow::on_visibility_notified (GtkWidget *text_view, GdkEventVisibility *event)
/* Also update the cursor image if the window becomes visible
 * (e.g. when a window covering it got iconified).
 */
{
  gint wx, wy, bx, by;
  gdk_window_get_pointer (text_view->window, &wx, &wy, NULL);
  gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, wx, wy, &bx, &by);
  set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), bx, by);
  return false;
}


gboolean MainWindow::notes_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
  return ((MainWindow *) user_data)->on_notes_key_press_event (widget, event);
}


gboolean MainWindow::on_notes_key_press_event (GtkWidget *widget, GdkEventKey *event)
/*
Links can be activated by pressing Enter.
Notes can be deleted by pressing Delete.
 */
{
  GtkTextIter iter;
  GtkTextIter start;
  GtkTextIter end;
  GtkTextBuffer *buffer;
  switch (event->keyval) {
    case GDK_Return: 
    case GDK_KP_Enter:
      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
      gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
      notes_edit_if_link (widget, &iter);
      break;
    case GDK_Delete: 
    case GDK_KP_Delete:
      buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
      gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
      notes_delete_if_link (widget, &start, &end);
      break;
    default:
      break;
  }
  return false;
}


void MainWindow::notes_event_after (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
  ((MainWindow *) user_data)->on_notes_event_after (widget, event);  
}


void MainWindow::on_notes_event_after (GtkWidget *text_view, GdkEvent *ev)
// Notes links can also be activated by clicking.
// References are obtained by control-click.
{
  GtkTextIter start, end, iter;
  GtkTextBuffer *buffer;
  GdkEventButton *event;
  gint x, y;
  if (ev->type != GDK_BUTTON_RELEASE)
    return;
  event = (GdkEventButton *)ev;
  if (event->button != 1)
    return;
  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
  // We shouldn't follow a link if the user has selected something.
  gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
  if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
    return;
  // Get iterator at clicking location.
  gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET,
                                         gint(event->x), gint(event->y), &x, &y);
  gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y);
  // Depending on whether the control key was down, take appropriate action.
  if (keyboard_control_state (event)) {
    // Ctrl down: get references.
    notes_get_references_from_link (text_view, &iter);
  } else {
    // Control not active: edit note.
    notes_edit_if_link (text_view, &iter);
  } 
}


void MainWindow::notes_edit_if_link (GtkWidget *text_view, GtkTextIter *iter)
/* Looks at all tags covering the position of iter in the text view, 
 * and if one of them is a link, follow it by showing the page identified
 * by the data attached to it.
 */
{
  GSList *tags = NULL, *tagp = NULL;
  tags = gtk_text_iter_get_tags (iter);
  for (tagp = tags;  tagp != NULL;  tagp = tagp->next) {
    GtkTextTag *tag = (GtkTextTag *) tagp->data;
    gint id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "id"));
    if (id != 0) {
      notes_fill_edit_screen (id, false);
      break;
    }
  }
  if (tags) 
    g_slist_free (tags);
}


void MainWindow::on_new_note_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_new_note ();  
}


void MainWindow::on_new_note () 
{
  // If we are currently editing a note, do nothing.
  if (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook1)) > 0)
    return;

  // Get the unique id for the new note.
  int id = notes_database_get_unique_id ();
  // Create the new note.
  notes_fill_edit_screen (id, true);
}


void MainWindow::notes_delete_if_link (GtkWidget *text_view, GtkTextIter *start, GtkTextIter *end)
/* Looks at all tags covering the positions of the iterator, from start to end,
   in the text view, and if there are links among them, delete it using the 
   data attached to it.
 */
{
  // Storage for the list of ids to delete.
  set <gint> ids;
  // Ensure text iterators go from low to high.
  gtk_text_iter_order (start, end);
  // Go through the range from start to end.
  // Collect the ids of the notes to be deleted.
  GtkTextIter iter;
  iter = * start;
  while (gtk_text_iter_in_range (&iter, start, end) || gtk_text_iter_equal (&iter, start)) {
    GSList *tags = NULL, *tagp = NULL;
    tags = gtk_text_iter_get_tags (&iter);
    for (tagp = tags;  tagp != NULL;  tagp = tagp->next) {
      GtkTextTag *tag = (GtkTextTag *) tagp->data;
      gint id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "id"));
      if (id != 0) {
        ids.insert(id);
      }
    }
    if (tags) 
      g_slist_free (tags);
    gtk_text_iter_forward_char (&iter);
  }
  // Get vector with ids to delete, and delete all notes that are in it.
  vector<gint> ids_to_delete (ids.begin(), ids.end());
  if (ids_to_delete.size() > 0) {
    if (gtkw_dialog_question (mainwindow, "Are you sure you want to delete these project notes?") != GTK_RESPONSE_YES)
      return;
    for (unsigned int i = 0; i < ids_to_delete.size(); i++)
      notes_delete_one(ids_to_delete[i]);
    // Redisplay.
    if (ids_to_delete.size() > 0)
      notes_redisplay();
  }
}


void MainWindow::on_delete_note_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_delete_note();
}


void MainWindow::on_delete_note ()
{
  // There was a bug of an infinite loop when a note was deleted through the menu,
  // while the notes view was not focused. Solved here.
  if (GTK_WIDGET_HAS_FOCUS (textview_notes)) {
    GtkTextIter start;
    GtkTextIter end;
    gtk_text_buffer_get_selection_bounds (textbuffer_notes, &start, &end);
    notes_delete_if_link (textview_notes, &start, &end);
  }
}


void MainWindow::on_viewnotes_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_view_notes ();
}


void MainWindow::on_view_notes ()
{
  ShowNotesDialog dialog (0);
  if (dialog.run() == GTK_RESPONSE_OK)
    notes_redisplay ();
}

void MainWindow::notes_redisplay ()
{
  // Reset the timer, so that the display will occur shortly.
  on_display_notes_timer = 0;
}


void MainWindow::on_find_in_notes1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->find_in_notes ();
}


void MainWindow::find_in_notes ()
{
  // Start dialog.
  {
    FindNoteDialog findnotedialog (0);
    if (findnotedialog.run () == GTK_RESPONSE_OK) {
      // Stop possible previous thread displaying notes.
      stop_displaying_more_notes ();
      // Store ids to display.
      notes_ids_to_display.assign (findnotedialog.ids.begin(), findnotedialog.ids.end());
      // Clear buffer.
      gtk_text_buffer_set_text (textbuffer_notes, "", -1);
      // Display all those ids.
      notes_ids_to_display_pointer = 0;
      g_idle_add (GSourceFunc (on_note_display_one), gpointer(this));
    }
  }
}


void MainWindow::on_import_notes_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_import_notes ();
}


void MainWindow::on_import_notes ()
{
  ImportNotesDialog dialog (0);
  if (dialog.run () == GTK_RESPONSE_APPLY) {
    notes_redisplay ();
  }
}


void MainWindow::on_export_notes_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_export_notes ();
}


void MainWindow::on_export_notes ()
{
  int result;
  ustring filename;
  ExportNotesFormat format;
  bool save_all_notes;
  {
    ExportNotesDialog dialog (0);
    result = dialog.run();
    filename = dialog.filename;
    format = dialog.exportnotesformat;
    save_all_notes = dialog.save_all_notes;
  }
  if (result == GTK_RESPONSE_OK) {
    export_translation_notes (filename, format, notes_ids_to_display, save_all_notes, mainwindow);    
  }
}


void MainWindow::on_button_cancel_clicked (GtkButton *button, gpointer user_data)
{
  ((MainWindow *) user_data)->on_notes_button_cancel ();
}


void MainWindow::on_notes_button_cancel ()
{
  // Do standard functions for both ok and cancel.
  on_notes_button_ok_cancel ();
}


void MainWindow::on_button_ok_clicked (GtkButton *button, gpointer user_data)
{
  ((MainWindow *) user_data)->on_notes_button_ok ();
}


void MainWindow::on_notes_button_ok ()
{
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    /*
    Validate and normalize the references.
    Bad ones are removed and a message will be given.
    If no valid references remain, stop the whole transaction and give a message.
    */
    ustring encoded_references;
    ustring osis_references;
    // Get and validate all references from the textview.
    {
      // Store references.
      vector<ustring> references;
      // Store possible messages here for later display.
      vector<ustring> messages;
      // Get all references from the editor.
      notes_get_references_from_editor (note_editor->textbuffer_references, references, messages);
      // Sort the references so they appear nicely in the editor.
      sort_references (references);
      // Encode all references.
      for (unsigned int i = 0; i < references.size(); i++) {
        // Encode the reference.
        ustring book;
        ustring chapter;
        ustring verse;
        decode_reference (references[i], book, chapter, verse);
        vector<int> verses = verses_encode (verse);
        int book_chapter = reference_to_numerical_equivalent (book, chapter, "0");
        for (unsigned int i2 = 0; i2 < verses.size(); i2++) {
          encoded_references.append(" ");
          encoded_references.append (convert_to_string (int (book_chapter + verses[i2])));
        }
        // Store the references in OSIS format too.
        int index = books_english_to_id (book);
        ustring osis_book = books_id_to_osis (index);
        ustring osis_reference = osis_book + "." + chapter + "." + verse;
        if (!osis_references.empty())
          osis_references.append (" ");
        osis_references.append (osis_reference);
      }
      encoded_references.append (" ");
      // See whether there are messages to display.
      if (messages.size() > 0) {
        ustring message;
        for (unsigned int i = 0; i < messages.size(); i++) {
          message.append (messages[i]);
          message.append ("\n");
        }
        gtkw_dialog_error (mainwindow, message);
      }
    }
    // See whether any references are left. If not give a message.
    if (encoded_references.empty()) {
      gtkw_dialog_error (mainwindow, "No valid references. Note was not stored");
      return;
    }
    // Connect to database and start transaction.
    rc = sqlite3_open(notes_database_filename ().c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    rc = sqlite3_exec (db, "begin;", NULL, NULL, &error);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    // Delete previous data with "id".
    gchar * sql;
    sql = g_strdup_printf ("delete from %s where id = %d;", TABLE_NOTES, note_editor->id);
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    // Put new data in the database.
    // ID (integer), we take variable "myid"
    // References (text), we take variable "encoded_references"
    // Project (text)
    ustring project = combobox_get_active_string (combobox_note_project);
    // Status (integer) This field is not used, and could be reused.
    // Category (text)
    ustring category = combobox_get_active_string (combobox_note_category);
    // Note (text)
    ustring note;
    {
      vector<ustring> lines;
      textbuffer_get_lines (note_editor->textbuffer_note, lines);
      for (unsigned int i = 0; i < lines.size(); i++) {
        if (!note.empty())
          note.append("\n");
        note.append(lines[i]);
      }
    }
    // Trim off extra newlines at the end, and ensure it always has one.
    note = trim(note);
    note.append ("\n");
    // Apostrophies need to be doubled before storing them.
    note = double_apostrophy (note);
    // Casefolded (text)
    ustring casefolded = note.casefold();
    // Date created. Variabele note_info_date_created
    // Date modified.
    int date_modified;
    date_modified = date_time_julian_day_get_current ();
    // Username. Use: note_info_user_created
    // Logbook (text)
    ustring logbook;
    {
      // Get and clean the lines.
      vector<ustring> lines;
      textbuffer_get_lines (note_editor->textbuffer_logbook, lines);
      for (unsigned int i = 0; i < lines.size(); i++) {
        if (!logbook.empty())
          logbook.append("\n");
        logbook.append(lines[i]);
      }
      // Trim off extra newlines at the end.
      logbook = trim(logbook);
      // Now add new data to the logbook.
      ustring date_user_text = date_time_julian_human_readable (date_modified, true);
      date_user_text.append (", ");
      date_user_text.append (g_get_real_name());
      date_user_text.append (" ");
      if (note_editor->newnote) {
        if (!logbook.empty())
          logbook.append ("\n");
        logbook.append (date_user_text);
        logbook.append ("created a new note, category \"");
        logbook.append (category);
        logbook.append ("\", project \"");
        logbook.append (project);   
        logbook.append ("\".");
      } else {
        vector<ustring> actions;
        if (gtk_text_buffer_get_modified (note_editor->textbuffer_note)) {
          actions.push_back ("modified the note");
        }
        if (category != note_editor->previous_category) {
          actions.push_back ("changed the category to \"" + category + "\"");
        }
        if (project != note_editor->previous_project) {
          actions.push_back ("changed the project to \"" + project + "\"");
        }
        if (actions.size() > 0) {
          if (!logbook.empty())
            logbook.append ("\n");
          logbook.append (date_user_text);
          for (unsigned int i = 0; i < actions.size(); i++) {
            if (i > 0)
              logbook.append (", ");
            logbook.append (actions[i]);
          }
          logbook.append (".");
        }
      }
      // Apostrophies need to be doubled before storing them.
      logbook = double_apostrophy (logbook);
    }
    // Insert data in database.
    sql = g_strdup_printf ("insert into %s values (%d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s');", TABLE_NOTES, note_editor->id, encoded_references.c_str(), osis_references.c_str(), project.c_str(), category.c_str(), note.c_str(), casefolded.c_str(), note_editor->date_created, date_modified, note_editor->created_by.c_str(), logbook.c_str());
    rc = sqlite3_exec (db, sql, NULL, NULL, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    // Commit the transaction.
    rc = sqlite3_exec (db, "commit;", NULL, NULL, &error);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.  
  sqlite3_close (db);
  // Do standard functions for both ok and cancel.
  on_notes_button_ok_cancel ();
  // New note, or note edited, so display notes again.
  notes_redisplay ();
}


void MainWindow::on_notes_button_ok_cancel ()  
// Functions common to both the ok and cancel buttons.
{
  // Show the normal notes display again.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook1), 0);
  // Focus widget that was focused previously.
  // This must be done after switching the page of the notebook,
  // to ensure the widget (usually the text editor) does indeed get focus.
  gtk_window_set_focus (GTK_WINDOW (mainwindow), note_editor->previous_focus);
  gtk_widget_grab_focus (note_editor->previous_focus);
  // Same for Tools Area tab that displayed previously (unless user changed it).
  if (note_editor->previous_tools_page >= 0)
    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), note_editor->previous_tools_page);
  // Clear some widgets.
  combobox_clear_strings (combobox_note_category);
  gtk_text_buffer_set_text (note_editor->textbuffer_references, "", -1);
  combobox_clear_strings (combobox_note_project);  
  gtk_label_set_text (GTK_LABEL (label_note_created_on), "");
  gtk_label_set_text (GTK_LABEL (label_note_created_by), "");
  gtk_label_set_text (GTK_LABEL (label_note_edited_on), "");
  gtk_text_buffer_set_text (note_editor->textbuffer_logbook, "", -1);
  // Switch notebook so widgets hide.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook3), 1);
  // Destroy NoteEditor object.
  if (note_editor)
    delete note_editor;
  note_editor = NULL;
}


void MainWindow::notes_fill_edit_screen (int id, bool newnote)
/*
When a new note is made, or an existing one edited, this function
sets up the edit screen.
*/
{
  // Create the NoteEditor object.
  if (note_editor)
    delete note_editor;
  note_editor = new NoteEditor (0);
  // Save variables.
  note_editor->id = id;
  note_editor->newnote = newnote;
  
  // Switch notebook so the widgets show.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook3), 0);
  
  // Initialize pointers to the text buffers.
  note_editor->textbuffer_note = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_note));
  note_editor->textbuffer_references = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_note_references));
  note_editor->textbuffer_logbook = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_note_logbook));

  // Save the widget that had the focus, so that when the notes had been edited,
  // the same widget gets the focus again.
  note_editor->previous_focus = gtk_window_get_focus (GTK_WINDOW (mainwindow));
  // Same for the tab that now displays in the Tools Area.
  int tools_page_displayed_previously = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook_tools));
  
  // Fetch the data for the note from the database. And fill comboboxes.
  // Or in case of a new note, deal appropriately with that.
  sqlite3 *db;
  int rc;
  char *error = NULL;
  try
  {
    rc = sqlite3_open(notes_database_filename ().c_str (), &db);
    if (rc) {
      throw runtime_error (sqlite3_errmsg(db));
    }
    SqliteReader sqlitereader (0);
    char * sql;
    sql = g_strdup_printf ("select ref_osis, project, category, note, created, modified, user, logbook from %s where id = %d;", TABLE_NOTES, id);
    rc = sqlite3_exec(db, sql, sqlitereader.callback, &sqlitereader, &error);
    g_free (sql);
    if (rc != SQLITE_OK) {
      throw runtime_error (error);
    }
    if ((sqlitereader.ustring0.size() > 0) || newnote) {
      ustring reference;
      gtk_text_buffer_set_text (note_editor->textbuffer_references, "", -1);
      if (newnote) {
        // New note, so get the current reference from the editor.
        reference = editor_current_book + " " + editor_current_chapter + ":" + editor_current_verse;
        gtk_text_buffer_insert_at_cursor (note_editor->textbuffer_references, reference.c_str(), -1);
        gtk_text_buffer_insert_at_cursor (note_editor->textbuffer_references, "\n", -1);
      } else {
        // Existing note, so get the reference(s) from the database.
        reference = sqlitereader.ustring0[0];
        // Read the reference(s) and show them.
        Parse parse (reference, false);
        for (unsigned int i = 0; i < parse.words.size(); i++) {
          ustring book, chapter, verse;
          reference_discover ("", "", "", parse.words[i], book, chapter, verse);
          ustring ref = book + " " + chapter + ":" + verse;
          gtk_text_buffer_insert_at_cursor (note_editor->textbuffer_references, ref.c_str(), -1);
          gtk_text_buffer_insert_at_cursor (note_editor->textbuffer_references, "\n", -1);
        }
      }
      // Read the note.
      ustring note;
      if (newnote) {
        // In case of a new note indicate to the user what to do, that is, 
        // how to create a new note.
        note = "Type the text of the note here and select button OK to save it.";
      } else {
        note = sqlitereader.ustring3[0];
      }
      gtk_text_buffer_set_text (note_editor->textbuffer_note, note.c_str(), -1);
      gtk_text_buffer_set_modified (note_editor->textbuffer_note, false);
      if (newnote) {
        // Select the informative text so that is disappears as soon as the user
        // starts to type.
        GtkTextIter start;
        GtkTextIter end;
        gtk_text_buffer_get_bounds (note_editor->textbuffer_note, &start, &end);
        gtk_text_buffer_move_mark_by_name (note_editor->textbuffer_note, "insert", &start);
        gtk_text_buffer_move_mark_by_name (note_editor->textbuffer_note, "selection_bound", &end);
      }
      /*
      Fill the category combo.
      */
      {
        ReadText rt (notes_categories_filename());
        combobox_set_strings (combobox_note_category, rt.lines);
        if (rt.lines.size() > 0)
          combobox_set_string (combobox_note_category, rt.lines[0]);
      }
      // Read the "category" variable.
      {
        if (!newnote) {
          ustring category = sqlitereader.ustring2[0];
          combobox_set_string (combobox_note_category, category);
        }
      }
      // Read the project. Fill the combo.
      {
        ustring project;
        if (newnote) {
          project = genconfig->project();
        } else {
          project = sqlitereader.ustring1[0];
        }
        vector<ustring> projects;
        if (project != "All")
          projects.push_back(project);
        if (genconfig->project() != project)
          projects.push_back(genconfig->project());
        projects.push_back("All");
        combobox_set_strings (combobox_note_project, projects);
        combobox_set_string (combobox_note_project, project);
      }
      // Read the date created.
      {
        // Fetch and store variable for display and later use.
        if (newnote) {
          note_editor->date_created = date_time_julian_day_get_current ();
        } else {
          note_editor->date_created = convert_to_int (sqlitereader.ustring4[0]);
        }
        ustring s;
        s = "Created on " + date_time_julian_human_readable (note_editor->date_created, true);
        gtk_label_set_text (GTK_LABEL (label_note_created_on), s.c_str());        
      }
      // Read the date modified.
      {
        if (newnote) {
          note_editor->date_modified = date_time_julian_day_get_current ();
        } else {
          note_editor->date_modified = convert_to_int (sqlitereader.ustring5[0]);
        }
        ustring s;
        s = "Edited on " + date_time_julian_human_readable (note_editor->date_modified, true);
        gtk_label_set_text (GTK_LABEL (label_note_edited_on), s.c_str());        
      }
      // Read the user that created the note.
      {
        if (newnote) {
          note_editor->created_by = g_get_real_name();
        } else {
          note_editor->created_by = sqlitereader.ustring6[0];
        }
        ustring s;
        s = "Created by " + note_editor->created_by;
        gtk_label_set_text (GTK_LABEL (label_note_created_by), s.c_str());        
      }
      // Read the logbook.
      {
        ustring logbook;
        if (!newnote)
          logbook = sqlitereader.ustring7[0];
        gtk_text_buffer_set_text (note_editor->textbuffer_logbook, logbook.c_str(), -1);
      }
    }
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
  // Close connection.  
  sqlite3_close (db);

  // Store category and project.
  note_editor->previous_category = combobox_get_active_string (combobox_note_category);
  note_editor->previous_project = combobox_get_active_string (combobox_note_project);
 
  // Switch screen to displaying the tabs for editing.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook1), 1);
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 2);
  // Store current page, so we can switch back to it later.
  note_editor->previous_tools_page = tools_page_displayed_previously;
  // Focus the widget the user is most likely going to type in.
  gtk_widget_grab_focus (textview_note);
}


void MainWindow::note_insert_date_and_text (const ustring& text)
{
  // If buffer does not end with a new line, insert one.
  GtkTextIter enditer;
  gtk_text_buffer_get_end_iter (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_note)), &enditer);
  if (!gtk_text_iter_starts_line (&enditer)) {
    gtk_text_buffer_insert (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_note)), &enditer, "\n", -1);
  }
  // Insert message at the end of the note.
  ustring message;
  message.append (g_get_real_name());
  message.append (": ");
  message.append (text);
  message.append (".");
  gtk_text_buffer_get_end_iter (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_note)), &enditer);
  gtk_text_buffer_insert (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview_note)), &enditer, message.c_str(), -1);
}


void MainWindow::on_standard_text_1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_standard_text (menuitem);
}


void MainWindow::on_standard_text_2_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_standard_text (menuitem);
}


void MainWindow::on_standard_text_3_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_standard_text (menuitem);
}


void MainWindow::on_standard_text_4_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_standard_text (menuitem);
}


void MainWindow::on_current_reference1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_standard_text (menuitem);
}


void MainWindow::on_insert_standard_text (GtkMenuItem *menuitem)
{
  // Find out which standard text to insert, and where to insert it, and how.
  ustring standardtext;
  bool addspace = false;
  GtkWidget * textview = textview_note;
  if (menuitem == GTK_MENU_ITEM (standard_text_1)) {
    standardtext = genconfig->edit_note_standard_text_one ();
    addspace = true;
    textview = textview_note;
  } else if (menuitem == GTK_MENU_ITEM (standard_text_2)) {
    standardtext = genconfig->edit_note_standard_text_two ();
    addspace = true;
    textview = textview_note;
  } else if (menuitem == GTK_MENU_ITEM (standard_text_3)) {
    standardtext = genconfig->edit_note_standard_text_three ();
    addspace = true;
    textview = textview_note;
  } else if (menuitem == GTK_MENU_ITEM (standard_text_4)) {
    standardtext = genconfig->edit_note_standard_text_four ();
    addspace = true;
    textview = textview_note;
  } else if (menuitem == GTK_MENU_ITEM (current_reference1)) {
    standardtext = editor_current_book + " " + editor_current_chapter + ":" + editor_current_verse;
    addspace = false;
    textview = textview_note_references;
  }
  // Add space.
  if (addspace)
    standardtext.append (" ");
  // If text was selected, erase that text.
  {
    GtkTextIter iter1, iter2;
    if (gtk_text_buffer_get_selection_bounds (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)), &iter1, &iter2)) {
      gtk_text_buffer_delete (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)), &iter1, &iter2);
    }
  }
  // If buffer does not end with a new line, insert one.
  GtkTextIter enditer;
  gtk_text_buffer_get_end_iter (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)), &enditer);
  if (!gtk_text_iter_starts_line (&enditer)) {
    gtk_text_buffer_insert (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)), &enditer, "\n", -1);
  }
  // Message.
  ustring message;
  // Add the standard text.
  message.append (standardtext);
  // Insert message at the end of the note.
  gtk_text_buffer_get_end_iter (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)), &enditer);
  gtk_text_buffer_insert (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)), &enditer, message.c_str(), -1);
}


void MainWindow::stop_displaying_more_notes ()
// Stop the process of displaying notes.
{
  notes_ids_to_display.clear();      
  g_usleep (1000);
}


bool MainWindow::on_display_notes_timeout (gpointer data)
{
  return ((MainWindow *) data)->on_display_notes ();
}


bool MainWindow::on_display_notes ()
/*
The menu sometimes gives two callbacks to display notes. If notes are displayed
twice that is not efficient use of resources, and leads to a slow reaction
in the experience of the user.
To solve this problem a timer is kept running. Each time the menu wants to 
(re)display notes, it resets that timer. Only when the timer reaches a certain
value notes will be displayed. 
The overall effect is that these two callbacks result in displaying notes once,
and it happens with a short delay.
*/
{
  // See whether it's time to (re)display notes.
  on_display_notes_timer++;
  if (on_display_notes_timer == 4) {
    // Do not fill the screen while editing a note. 
    // Filling the screen while editing the notes is not useful and only
    // makes bibledit slow in the experience of the user.
    if (gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook1)) != 0)
      return true;
    // Fill the notes screen.
    // Stop possible previous thread displaying notes.
    stop_displaying_more_notes ();
    // Get actual verse.
    ustring reference = editor_current_book + " " + editor_current_chapter + ":" + editor_current_verse;
    // Select notes for display.  
    notes_select (notes_ids_to_display, reference);
    // Clear buffer.
    gtk_text_buffer_set_text (textbuffer_notes, "", -1);
    // Display the notes. This is done when the editor is idle, and one note
    // at a time, so that the program remains responsive.
    notes_ids_to_display_pointer = 0;
    // To start this as a thread does not seem to work well, therefore we use
    // the idle handler.
    g_idle_add (GSourceFunc (on_note_display_one), gpointer(this));
  }
  return true;
}


bool MainWindow::on_note_display_one (gpointer data)
{
  return ((MainWindow *) data)->note_display_one ();
}


bool MainWindow::note_display_one ()
{
  if (notes_ids_to_display_pointer < notes_ids_to_display.size()) {
    notes_display_one (textview_notes, textbuffer_notes, notes_ids_to_display[notes_ids_to_display_pointer]);
  }
  notes_ids_to_display_pointer++;
  if (notes_ids_to_display_pointer < notes_ids_to_display.size())
    // Not yet ready: allow for next note to be displayed.
    return true;
  else {
    // We're through. Do not clear the container, because export notes might need it.
    return false;
  }
}


void MainWindow::on_get_references_from_note_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_get_references_from_note ();
}


void MainWindow::on_get_references_from_note ()
{
  // Store references.
  vector<ustring> references;
  // Store possible messages here, but they will be dumped.
  vector<ustring> messages;
  // Get all references from the editor.
  if (note_editor)
    notes_get_references_from_editor (note_editor->textbuffer_references, references, messages);
  // Sort the references so they appear nicely in the editor.
  sort_references (references);
  // Set none searchwords.
  session.highlights_clear();
  // Set references.
  References references2 (liststore_references, treeview_references, treecolumn_references);
  references2.set_references (references);
  references2.fill_store ();
  // Display the References Area
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 0);
}


void MainWindow::notes_get_references_from_link (GtkWidget *text_view, GtkTextIter *iter)
// If there is a link at iter, get the references from it.
{
  // Store references we get.
  vector<ustring> references;
  // Gets all tags at the iterator.
  GSList *tags = NULL, *tagp = NULL;
  tags = gtk_text_iter_get_tags (iter);
  for (tagp = tags;  tagp != NULL;  tagp = tagp->next) {
    GtkTextTag *tag = (GtkTextTag *) tagp->data;
    gint id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "id"));
    if (id != 0) {
      // Fetch the references for the note from the database.
      sqlite3 *db;
      int rc;
      char *error = NULL;
      try
      {
        rc = sqlite3_open(notes_database_filename ().c_str (), &db);
        if (rc)
          throw runtime_error (sqlite3_errmsg(db));
        SqliteReader sqlitereader (0);
        char * sql;
        sql = g_strdup_printf ("select ref_osis from %s where id = %d;", TABLE_NOTES, id);
        rc = sqlite3_exec(db, sql, sqlitereader.callback, &sqlitereader, &error);
        g_free (sql);
        if (rc != SQLITE_OK)
          throw runtime_error (error);
        if ((sqlitereader.ustring0.size() > 0)) {
          ustring reference;
          reference = sqlitereader.ustring0[0];
          // Read the reference(s).
          Parse parse (reference, false);
          for (unsigned int i = 0; i < parse.words.size(); i++) {
            ustring book, chapter, verse;
            reference_discover ("", "", "", parse.words[i], book, chapter, verse);
            ustring ref = book + " " + chapter + ":" + verse;
            references.push_back (ref);
          }
        }
      }
      catch (exception & ex)
      {
        gw_critical (ex.what ());
      }
      // Close connection.  
      sqlite3_close (db);
      break;
    }
  }
  if (tags) 
    g_slist_free (tags);
  // Set references.
  References references2 (liststore_references, treeview_references, treecolumn_references);
  references2.set_references (references);
  references2.fill_store ();
  // Display the References Area
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 0);
}



/*
|
|
|
|
|
Export
|
|
|
|
|
*/


void MainWindow::on_export_usfm_files_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_export_usfm_files ();
}


void MainWindow::on_export_usfm_files ()
{
  editor_save();
  export_to_usfm (mainwindow);
}


void MainWindow::on_to_bibleworks_version_compiler_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_to_bibleworks_version_compiler ();
}


void MainWindow::on_to_bibleworks_version_compiler ()
{
  editor_save();
  export_to_bibleworks (mainwindow);
}


void MainWindow::on_export_to_sword_module_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_export_to_sword_module ();
}


void MainWindow::on_export_to_sword_module ()
{
  editor_save();
  export_to_sword_interactive ();
  bibletime.reloadmodules ();
}


/*
|
|
|
|
|
Checks
|
|
|
|
|
*/


void MainWindow::on_check1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_check ();
}


void MainWindow::on_menu_check ()
{
  // Switch to the References Area.
  on_file_references ();
}


void MainWindow::on_markers1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_check_markers ();
}


void MainWindow::on_menu_check_markers ()
{
}


void MainWindow::on_validate_usfms1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_check_markers_validate ();
}


void MainWindow::on_menu_check_markers_validate ()
{
  editor_save ();
  scripture_checks_validate_usfms (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_count_usfms1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_check_markers_count ();
}


void MainWindow::on_menu_check_markers_count ()
{
  editor_save ();
  scripture_checks_count_usfms ();
}


void MainWindow::on_compare_usfm1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_check_markers_compare ();
}


void MainWindow::on_menu_check_markers_compare ()
{
  editor_save ();
  scripture_checks_compare_usfms (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_chapters_and_verses1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_check_chapters_and_verses();
}


void MainWindow::on_menu_check_chapters_and_verses ()
{
  editor_save ();
  scripture_checks_chapters_verses (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_count_characters_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_count_characters();
}


void MainWindow::on_count_characters ()
{
  editor_save ();
  scripture_checks_count_characters ();
}


void MainWindow::on_unwanted_patterns_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_unwanted_patterns ();
}


void MainWindow::on_unwanted_patterns ()
{
  editor_save ();
  scripture_checks_unwanted_patterns (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_check_capitalization_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_check_capitalization();
}


void MainWindow::on_check_capitalization ()
{
  editor_save ();
  scripture_checks_capitalization (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_check_repetition_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_check_repetition();
}


void MainWindow::on_check_repetition ()
{
  editor_save ();
  scripture_checks_repetition (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_check_matching_pairs_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_check_matching_pairs();
}


void MainWindow::on_check_matching_pairs ()
{
  editor_save ();
  scripture_checks_matching_pairs (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_unwanted_words_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_unwanted_words();
}


void MainWindow::on_unwanted_words ()
{
  editor_save ();
  scripture_checks_unwanted_words (liststore_references, treeview_references, treecolumn_references);
}


void MainWindow::on_word_count_inventory_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_word_count_inventory();
}


void MainWindow::on_word_count_inventory ()
{
  editor_save ();
  scripture_checks_word_inventory (liststore_references, treeview_references, treecolumn_references);
}


bool MainWindow::on_check_httpd_timeout (gpointer data)
{
  ((MainWindow *) data)->on_check_httpd ();
  return true;
}


void MainWindow::on_check_httpd ()
{
  // See if the file containing the httpd's requests is there.
  ustring filename = gw_build_filename (directories_get_temp(), "bibledit.httpd.request");
  if (!g_file_test (filename.c_str(), G_FILE_TEST_IS_REGULAR)) return;
  // Get contents.
  gchar *contents;
  g_file_get_contents (filename.c_str(), &contents, NULL, NULL);
  if (!contents) return;
  // Remove file.
  unlink (filename.c_str());
  // Look for a signature in the contents.
  ustring signature = "search-whole-word=";
  if (g_strrstr (contents, signature.c_str())) {
    // Bibledit presents itself.
    gtk_window_present (GTK_WINDOW (mainwindow));
    ustring text (contents);
    size_t position = text.find (signature);
    text.erase (0, position + signature.length());
    position = text.find (" ");
    ustring word = text.substr (0, position);
    session.searchword (word);  
    session.search_case_sensitive (true);
    session.search_current_book (false);
    session.search_current_chapter (false);
    session.search_globbing (false);
    session.search_start_word_match (true);
    session.search_end_word_match (true);
    session.search_page (1);
    session.searchresultstype (sstLoad);
    session.highlights_clear();
    session.highlights_add (session.searchword(), session.search_case_sensitive(), session.search_globbing(), session.search_start_word_match(), session.search_end_word_match(), atRaw, false, false, false, false, false, false, false, false);
    search_string (liststore_references, treeview_references, treecolumn_references, &bibletime);    
  }
  // Free memory.
  g_free (contents);
}


/*
|
|
|
|
|
Styles
|
|
|
|
|
*/


void MainWindow::on_insert_style_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_insert_style ();
}


void MainWindow::on_menu_insert_style ()
{
  // Set the right page and focus the right treeview to enable the user to start
  // inserting the style using the keyboard.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 1);
  gtk_widget_grab_focus (treeview_styles);
}


void MainWindow::on_file_styles (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_menu_file_styles ();
}


void MainWindow::on_menu_file_styles ()
{
  // Show the Styles Area.
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook_tools), 1);
  // Prepare some variables to be used to disable or enable menu items.
  bool edit_mode = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (stylesheet_edit_mode));
  vector<ustring> selected_recently_used_styles = styletree_get_focused_recently_used_styles (treeview_styles); 
  vector<ustring> selected_regular_styles = styletree_get_focused_regular_styles (treeview_styles);
  vector<ustring> selected_categories = styletree_get_focused_categories (treeview_styles);
  bool stylesheet_open = !genconfig->stylesheet().empty();
  // Sensitivity of Insert style.
  gtk_widget_set_sensitive (style_insert, ((selected_recently_used_styles.size() + selected_regular_styles.size()) == 1));
  // Sensitivity of Expand/Collapse all.
  gtk_widget_set_sensitive (stylesheets_expand_all, stylesheet_open);
  gtk_widget_set_sensitive (stylesheets_collapse_all, stylesheet_open);
  // Sensitivity of New style.
  gtk_widget_set_sensitive (style_new, edit_mode && stylesheet_open);
  // Sensitivity of style Properties.
  gtk_widget_set_sensitive (style_properties, edit_mode && ((selected_recently_used_styles.size() + selected_regular_styles.size()) == 1));
  // Sensitivity of Delete style.
  gtk_widget_set_sensitive (style_delete, edit_mode && ((selected_recently_used_styles.size() + selected_regular_styles.size() + selected_categories.size()) > 0));
  // Sensitivity of Delete stylesheet.
  gtk_widget_set_sensitive (stylesheets_delete, stylesheet_open);
  // Sensitivity of Rename stylesheet.
  gtk_widget_set_sensitive (stylesheets_rename, stylesheet_open);
  // Sensitivity of Export stylesheet.
  gtk_widget_set_sensitive (stylesheets_export, stylesheet_open);
}


void MainWindow::on_stylesheet_switch_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheet_switch ();
}


void MainWindow::on_stylesheet_switch ()
{
  OpenStylesheetDialog dialog (osdtSwitch, genconfig->stylesheet());
  if (dialog.run() == GTK_RESPONSE_OK) {
    // Save the name of the stylesheet in two locations.
    genconfig->stylesheet_set (dialog.stylesheet);
    if (!genconfig->project().empty()) {
      ProjectConfiguration projectconfig ("");
      projectconfig.stylesheet_set (dialog.stylesheet);
    }
    // Open the sheet.
    stylesheet_open_named (genconfig->stylesheet());
  }
}


void MainWindow::stylesheet_open_named (const ustring& stylesheet)
{
  // Clear store.
  gtk_tree_store_clear (treestore_styles);
  // Load recently used styles.
  styletree_load_recently_used_styles (treestore_styles, GTK_TREE_VIEW (treeview_styles));
  // Load stylesheet itself.
  styletree_load_stylesheet (treestore_styles, stylesheet, GTK_TREE_VIEW (treeview_styles));
  // Set gui.
  ustring s = "Stylesheet " + stylesheet;  
  gtk_label_set_text (GTK_LABEL (statuslabel_stylesheet), s.c_str());
}


void MainWindow::on_stylesheet_edit_mode_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheet_edit_mode ();
}


void MainWindow::on_stylesheet_edit_mode ()
{
}


void MainWindow::on_stylesheets_new_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheets_new ();
}


void MainWindow::on_stylesheets_new ()
{
  // Get the name for the new stylesheet.
  ustring name;
  EntryDialog dialog ("New stylesheet", "Enter the name for the new stylesheet", "");
  if (dialog.run () == GTK_RESPONSE_OK) {
    name = dialog.entered_value;
    // If it exists already, do not create a new one.
    if (stylesheet_exists (name)) {
      gtkw_dialog_error (mainwindow, "A stylesheet with this name already exists.");
    } else {
      stylesheet_create_new (name);
      // Save the name of the stylesheet in two locations.
      genconfig->stylesheet() = name;
      if (!genconfig->project().empty()) {
        ProjectConfiguration projectconfig ("");
        projectconfig.stylesheet_set (name);
      }
      stylesheet_open_named (name);
    }
  }
}


void MainWindow::on_stylesheets_delete_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheets_delete ();
}


void MainWindow::on_stylesheets_delete ()
{
  OpenStylesheetDialog dialog (osdtDelete, genconfig->stylesheet());
  if (dialog.run() == GTK_RESPONSE_OK) {
    if (gtkw_dialog_question (mainwindow, "Do you really want to delete stylesheet " + dialog.stylesheet + "?") == GTK_RESPONSE_YES) {
      stylesheet_delete (dialog.stylesheet);
    }
  }
}


void MainWindow::on_stylesheets_rename_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheets_rename ();
}


void MainWindow::on_stylesheets_rename ()
{
  styletree_rename_stylesheet (mainwindow);
  stylesheet_open_named (genconfig->stylesheet());
}


void MainWindow::on_stylesheets_import_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheets_import ();
}


void MainWindow::on_stylesheets_import ()
{
  if (styletree_import_stylesheet (mainwindow)) {
    stylesheet_open_named (genconfig->stylesheet());
  } 
}


void MainWindow::on_stylesheets_export_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheets_export ();
}


void MainWindow::on_stylesheets_export ()
{
  styletree_export_stylesheet (mainwindow);
}


void MainWindow::on_style_new_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_style_new ();
}


void MainWindow::on_style_new ()
{
  // Do nothing if edit mode is off or no stylesheet is open.
  if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (stylesheet_edit_mode)))
    return;
  if (genconfig->stylesheet().empty())
    return;
  EntryDialog dialog ("New style", "Marker", "");
  if (dialog.run() == GTK_RESPONSE_OK) {
    // Clean up input, as some people tend to insert the backslash too.
    ustring input = trim (dialog.entered_value);
    {
      size_t position = input.find ("\\");
      if (position != string::npos)
        input.erase (position, 1);
    }
    // Check that the marker does not already exist.
    bool marker_exists = false;
    vector<ustring> styles = stylesheet_get_markers (genconfig->stylesheet(), NULL);
    for (unsigned int i = 0; i < styles.size(); i++) {
      if (input == styles[i])
        marker_exists = true;
    }
    if (marker_exists) {
      gtkw_dialog_error (mainwindow, "This marker already exists in the stylesheet");
    } else {
      #define ENTER_THE_NAME_HERE "Enter the name here"
      stylesheet_new_style (genconfig->stylesheet(), input, ENTER_THE_NAME_HERE, "Enter the description here.");
      stylesheet_open_named (genconfig->stylesheet());      
      ustring focus = dialog.entered_value + " " + ENTER_THE_NAME_HERE;
      styletree_focus_string (treeview_styles, focus);
    }
  }
}


void MainWindow::on_style_properties_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_style_properties ();
}


void MainWindow::on_style_properties ()
{
  // Get the first focused style.
  ustring style = styletree_get_focused_style (treeview_styles);
  // Do nothing if none.
  if (style.empty())
    return;
  // Edit the style.
  StylesheetDialog dialog (genconfig->stylesheet(), style);
  if (dialog.run() == GTK_RESPONSE_OK) {
    // Reopen sheet and focus the style.
    stylesheet_open_named (genconfig->stylesheet());
    styletree_focus_string (treeview_styles, style + " " + dialog.name);  
  }
}


void MainWindow::on_style_delete_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_style_delete ();
}


void MainWindow::on_style_delete ()
{
  // Do nothing if edit mode is off or no styles have been selected.
  if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (stylesheet_edit_mode)))
    return;
  // Get focused items.
  vector<ustring> focused_recently_used_styles;
  vector<ustring> focused_regular_styles;
  vector<ustring> focused_categories;
  focused_recently_used_styles = styletree_get_focused_recently_used_styles (treeview_styles);
  focused_regular_styles = styletree_get_focused_regular_styles (treeview_styles);
  focused_categories = styletree_get_focused_categories (treeview_styles);  
  // How many items have been selected?
  int selected_count;
  selected_count = focused_recently_used_styles.size() + focused_regular_styles.size() + focused_categories.size();
  if (selected_count == 0)
    return;
  // Find the text of the item just before the first focused item.
  ustring string_before_focus = styletree_get_string_before_focus (treeview_styles);
  // Delete the styles.
  for (unsigned int i = 0; i < focused_recently_used_styles.size(); i++) {
    styletree_clear_recently_used_style (focused_recently_used_styles[i]);
  }
  for (unsigned int i = 0; i < focused_regular_styles.size(); i++) {
    stylesheet_delete_style (genconfig->stylesheet(), focused_regular_styles[i]);
  }
  styletree_delete_categories (focused_categories);
  stylesheet_open_named (genconfig->stylesheet());
  // Focus on the string just before the deleted ones(s).
  styletree_focus_string (treeview_styles, string_before_focus);
}


gboolean MainWindow::on_treeview_styles_key_press_event (GtkWidget * widget, GdkEventKey * event, gpointer user_data)
{
  // Pressing Enter inserts the style.
  if (keyboard_enter_pressed (event)) {
    ((MainWindow *) user_data)->on_style_insert ();
  }
  // Pressing Delete deletes the selected style(s).
  if (keyboard_delete_pressed (event)) {
    ((MainWindow *) user_data)->on_style_delete ();
  }
  // Pressing Insert creates a new style.
  if (keyboard_insert_pressed (event)) {
    ((MainWindow *) user_data)->on_style_new ();
  }
  // Collapse or expand a category.
  if (keyboard_left_arrow_pressed (event)) {
    return ((MainWindow *) user_data)->on_style_collapse ();
  }
  if (keyboard_right_arrow_pressed (event)) {
    return ((MainWindow *) user_data)->on_style_expand ();
  }
  return FALSE;
}


gboolean MainWindow::on_treeview_styles_button_press_event (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
  return ((MainWindow *) user_data)->on_treeview_styles_button_press (widget, event);
}


bool MainWindow::on_treeview_styles_button_press (GtkWidget * widget, GdkEventButton * event)
{
  // Double-clicking a style inserts it or if the edit mode is on, edits it.
  if (event->type == GDK_2BUTTON_PRESS) {
    bool edit_mode = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (stylesheet_edit_mode));
    if (edit_mode) {
      on_style_properties ();
    } else {
      on_style_insert ();
    }
    return true;
  }
  // Popup menu handler.
  if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
    show_styles_popup_menu (widget, event);
    return true;
  }  
  return false;
}


gboolean MainWindow::on_treeview_styles_popup_menu (GtkWidget *widget, gpointer user_data)
{
  ((MainWindow *) user_data)->treeview_styles_popup_menu (widget);
  return true; // Do not call the original handler.
}


void MainWindow::treeview_styles_popup_menu (GtkWidget *widget)
{
  show_styles_popup_menu (widget, NULL);
}


void MainWindow::show_styles_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
{
  int button, event_time;
  if (event) {
    button = event->button;
    event_time = event->time;
  } else {
    button = 0;
    event_time = gtk_get_current_event_time ();
  }
  on_menu_file_styles ();
  gtk_menu_popup (GTK_MENU (style_menu), NULL, NULL, NULL, NULL, button, event_time);
}


void MainWindow::on_treeview_styles_row_collapsed (GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data)
{
  ((MainWindow *) user_data)->on_treeview_styles_collapsed_expanded (iter, path, false);
}


void MainWindow::on_treeview_styles_row_expanded (GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data)
{
  ((MainWindow *) user_data)->on_treeview_styles_collapsed_expanded (iter, path, true);
}


void MainWindow::on_treeview_styles_collapsed_expanded (GtkTreeIter *iter, GtkTreePath *path, bool expand)
{
  styletree_store_state (treestore_styles, iter, expand);
}


void MainWindow::on_stylesheets_expand_all_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheets_expand_all ();
}


void MainWindow::on_stylesheets_expand_all ()
{
  gtk_tree_view_expand_all (GTK_TREE_VIEW (treeview_styles));
  // Work around a bug in Gtk2.
  // When this function is called from the menu, the widget does not redraw.
  gtk_widget_queue_draw (treeview_styles);
}


void MainWindow::on_stylesheets_collapse_all_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_stylesheets_collapse_all ();
}


void MainWindow::on_stylesheets_collapse_all ()
{
  gtk_tree_view_collapse_all (GTK_TREE_VIEW (treeview_styles));
}


void MainWindow::on_style_insert_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_style_insert ();
}


void MainWindow::on_style_insert ()
{
  // Get the focused style(s).
  ustring selected_style = styletree_get_focused_style (treeview_styles);
  // Only proceed when a style has been selected.
  if (selected_style.empty())
    return;
  // Get the Style object.
  Style style (genconfig->stylesheet(), selected_style, false);
  // Assemble the markers(s).
  bool has_endmarker = stylesheet_style_has_endmarker (style);
  ustring beginmarker = usfm_get_full_opening_marker (selected_style);
  ustring endmarker;
  if (has_endmarker)
    endmarker = usfm_get_full_closing_marker (selected_style);
  // If there is a selection, remember the iterator, and unselect it.
  GtkTextIter start, end;
  if (gtk_text_buffer_get_selection_bounds (editor.textbuffer_text, &start, &end)) {
    gtk_text_buffer_select_range (editor.textbuffer_text, &start, &start);
    // Insert the endmarker, if needed.
    if (has_endmarker) {
      gtk_text_buffer_insert (editor.textbuffer_text, &end, endmarker.c_str(), -1);
    }
    // Insert the marker itself, at the cursor position.
    gtk_text_buffer_insert_at_cursor (editor.textbuffer_text, beginmarker.c_str(), -1);
  } else {
    // No selection: assemble marker to insert, and insert it.
    ustring marker = beginmarker + endmarker;
    gtk_text_buffer_insert (editor.textbuffer_text, &start, marker.c_str(), -1);
    // Place the cursor properly.
    gtk_text_buffer_get_selection_bounds (editor.textbuffer_text, &start, &end);
    gtk_text_iter_backward_chars (&start, endmarker.length());
    gtk_text_buffer_place_cursor (editor.textbuffer_text, &start);
  }
  // Update recently used styles.
  styletree_use_style (treestore_styles, treeview_styles, selected_style);
  // Focus the style we selected.
  ustring complete_style = selected_style + " " + style.name;
  styletree_focus_string (treeview_styles, complete_style);
  // Focus editor.
  gtk_widget_grab_focus (editor.textview_text);
}


bool MainWindow::on_style_expand ()
{
  return styletree_expand_collapse (treeview_styles, true);
}


bool MainWindow::on_style_collapse ()
{
  return styletree_expand_collapse (treeview_styles, false);
}


/*
|
|
|
|
|
Footnotes, endnotes, crossreferences
|
|
|
|
|
*/


void MainWindow::on_insert_footnote_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_footnote ();
}


void MainWindow::on_insert_footnote ()
{
  InsertNoteDialog dialog (indtFootnote, editor.textbuffer_text);
  if (dialog.run() == GTK_RESPONSE_OK) {
    editor.format (); 
  }
}


void MainWindow::on_insert_endnote_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_endnote ();
}


void MainWindow::on_insert_endnote ()
{
  InsertNoteDialog dialog (indtEndnote, editor.textbuffer_text);
  if (dialog.run() == GTK_RESPONSE_OK) {
    editor.format (); 
  }
}


void MainWindow::on_insert_crossreference_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_insert_crossreferencenote ();
}


void MainWindow::on_insert_crossreferencenote ()
{
  InsertNoteDialog dialog (indtCrossreference, editor.textbuffer_text);
  if (dialog.run() == GTK_RESPONSE_OK) {
    editor.format (); 
  }
}


/*
|
|
|
|
|
Formatted view
|
|
|
|
|
*/


gboolean MainWindow::on_text_motion_notify_event (GtkWidget *textview, GdkEventMotion *event, gpointer user_data)
{
  return ((MainWindow *) user_data)->text_motion_notify_event (textview, event);
}

  
gboolean MainWindow::text_motion_notify_event (GtkWidget *textview, GdkEventMotion *event)
// Update the cursor image if the pointer moved. 
{
  // Switched off as we have no need of a hand-cursor at present.
  return false;
  gint x, y;
  gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (textview), GTK_TEXT_WINDOW_WIDGET,
                                         gint(event->x), gint(event->y), &x, &y);
  set_cursor_if_appropriate (GTK_TEXT_VIEW (textview), x, y);
  gdk_window_get_pointer (textview->window, NULL, NULL, NULL);
  return false;
}


void MainWindow::on_text_event_after (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
  ((MainWindow *) user_data)->text_event_after (widget, event);  
}


void MainWindow::text_event_after (GtkWidget *textview, GdkEvent *ev)
/* Links can also be activated by clicking.
 */
{
  GtkTextIter start, end, iter;
  GtkTextBuffer *buffer;
  GdkEventButton *event;
  gint x, y;
  if (ev->type != GDK_BUTTON_RELEASE)
    return;
  event = (GdkEventButton *)ev;
  if (event->button != 1)
    return;
  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
  // We shouldn't follow a link if the user has selected something.
  gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
  if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
    return;
  gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (textview), GTK_TEXT_WINDOW_WIDGET,
                                         gint(event->x), gint(event->y), &x, &y);
  gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (textview), &iter, x, y);
  text_edit_if_link (textview, &iter);
}


void MainWindow::text_edit_if_link (GtkWidget *textview, GtkTextIter *iter)
/* Looks at all tags covering the position of iter in the text view, 
 * and if one of them is a link, follow it by showing the page identified
 * by the data attached to it.
 */
{
  GSList *tags = NULL, *tagp = NULL;
  tags = gtk_text_iter_get_tags (iter);
  for (tagp = tags;  tagp != NULL;  tagp = tagp->next) {
    GtkTextTag *tag = (GtkTextTag *) tagp->data;
    gint id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "id"));
    if (id != 0) {
      EditorObject editorobject (editor.editorobjects[id]);
      switch (editorobject.type) {
        case eotNone: 
          break;
        case eotFootnote:
        case eotEndnote:
        case eotCrossreference:
          break;
      }
    }
  }
  if (tags) 
    g_slist_free (tags);
}


gboolean MainWindow::text_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
  return ((MainWindow *) user_data)->on_text_key_press_event (widget, event);
}


gboolean MainWindow::on_text_key_press_event (GtkWidget *widget, GdkEventKey *event)
// Handle the keyboard events in the text editor.
{
  switch (event->keyval) {
    case GDK_BackSpace: 
    case GDK_Delete: 
    case GDK_KP_Delete:
    {
      if (editor.footnote_caller_remove (event->keyval == GDK_BackSpace)) {
        return true;
      }
      break;
    }
    default:
    {
      break;
    }
  }
  return false;
}


void MainWindow::on_textview_footnotes_move_cursor (GtkTextView * textview, GtkMovementStep step, gint count, gboolean extend_selection, gpointer user_data)
{
  ((MainWindow *) user_data)->on_textview_footnotes_cursor_moved ();
}


void MainWindow::on_textview_footnotes_cursor_moved ()
{
  editor.footnote_caller_scroll_to ();
}


void MainWindow::on_textview_footnotes_grab_focus (GtkWidget * widget, gpointer user_data)
{
  ((MainWindow *) user_data)->on_textview_footnotes_focus_grabbed ();
}


void MainWindow::on_textview_footnotes_focus_grabbed ()
{
  editor.footnote_caller_scroll_to ();
}


/*
|
|
|
|
|
Synchronization
|
|
|
|
|
*/


void MainWindow::on_synchronize_projects_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_synchronize_projects ();
}


void MainWindow::on_synchronize_projects ()
{
  // Save any changes.
  editor_save ();
  // Run dialog and do all things there.
  SynchronizeDialog dialog (0);
  dialog.run ();
  // In case the currently opened book was updated, reopen the project.
  close_open_project ("");
  // Update gui in case problems were still left or were solved.
  SynchronizeProjects sp (0);
  attend_to_sync_all = sp.errors;
  attention_show_hide (attend_to_sync_all);
}


void MainWindow::on_statusbutton_attention_clicked  (GtkButton *button, gpointer user_data)
{
  ((MainWindow *) user_data)->on_statusbutton_attention ();
}


void MainWindow::on_statusbutton_attention ()
{
  ustring message;
  if (attend_to_sync_project || attend_to_sync_all) {
    message.append ("The synchronization state needs attention.\n"
                    "See menu File - Project - Synchronize.\n");
  }
  if (!message.empty())
    gtkw_dialog_warning (mainwindow, message);
}


void MainWindow::attention_show_hide (bool show)
{
  if (show)
    gtk_widget_show (statusbutton_attention);
  else
    gtk_widget_hide (statusbutton_attention);
}


void MainWindow::on_preferences_synchronization_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_preferences_synchronization ();
}


void MainWindow::on_preferences_synchronization ()
{
  SynchronizationDialog dialog (0);
  if (dialog.run() == GTK_RESPONSE_OK) {
    // Set possible new timeout.
    GSource *source = g_main_context_find_source_by_id (NULL, sync_source_id);
    if (source) g_source_destroy (source);
    int msecs = genconfig->synchronize_project_minutes() * 60000;
    sync_source_id = g_timeout_add_full (G_PRIORITY_DEFAULT, msecs, GSourceFunc (synchronize_project_timeout), gpointer(this), NULL);
  }
}


bool MainWindow::synchronize_project_timeout (gpointer data)
{
  ((MainWindow *) data)->on_synchronize_project_timeout ();
  return true;
}


void MainWindow::on_synchronize_project_timeout ()
{
  if (genconfig->synchronize_project_regularly())
    synchronize_project ();
}


void MainWindow::synchronize_project ()
{
  // Save text in editor.
  editor_save ();
  // Sync project.
  SynchronizeProject sp (genconfig->project());
  // Set gui in case of errors.
  attend_to_sync_project = sp.errors;
  attention_show_hide (attend_to_sync_project || attend_to_sync_all);
  // If the book we have open is updated, close and reopen project.
  if (sp.books_updated.find (genconfig->book()) != sp.books_updated.end()) {
    if (!genconfig->project().empty()) {
      close_open_project ("");
      gw_message (genconfig->book() +  " was updated: project reopened");
    }
  }
}


/*
|
|
|
|
|
Tools
|
|
|
|
|
*/


void MainWindow::on_menutools_activate (GtkMenuItem *menuitem, gpointer user_data)
{
}


void MainWindow::on_line_cutter_for_hebrew_text1_activate (GtkMenuItem *menuitem, gpointer user_data)
{
  ((MainWindow *) user_data)->on_line_cutter_for_hebrew_text ();
}


void MainWindow::on_line_cutter_for_hebrew_text ()
{
  LineCutterDialog dialog (0);
  if (dialog.run () == GTK_RESPONSE_OK) {
    close_open_project ("");
  }    
}

Generated by  Doxygen 1.6.0   Back to index