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

dialoginsertnote.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 "libraries.h"
#include <glib.h>
#include "dialoginsertnote.h"
#include "utilities.h"
#include "directories.h"
#include "combobox.h"
#include "dialogentry.h"
#include "gwrappers.h"
#include "notetemplate.h"
#include "usfmtools.h"
#include "stylesheetutils.h"
#include "shell.h"
#include "generalconfig.h"
#include "session.h"


enum NumberingType {ntAutomatic, ntNone, ntCharacter};


InsertNoteDialog::InsertNoteDialog (NoteType dialogtype, GtkTextBuffer * textbuffer)
{
  GeneralConfiguration genconfig (0);
  mydialogtype = dialogtype;
  mytextbuffer = textbuffer;
  allow_entry_activate = true;

  insertnotedialog = gtk_dialog_new ();
  ustring title = "Insert ";
  switch (dialogtype) {
    case indtFootnote:
      title.append ("footnote");
      break;
    case indtEndnote:
      title.append ("endnote");
      break;
    case indtCrossreference:
      title.append ("crossreference");
      break;
  }
  gtk_window_set_title (GTK_WINDOW (insertnotedialog), title.c_str());
  gtk_window_set_position (GTK_WINDOW (insertnotedialog), GTK_WIN_POS_CENTER_ON_PARENT);
  gtk_window_set_modal (GTK_WINDOW (insertnotedialog), TRUE);
  gtk_window_set_resizable (GTK_WINDOW (insertnotedialog), FALSE);
  gtk_window_set_destroy_with_parent (GTK_WINDOW (insertnotedialog), TRUE);
  gtk_window_set_type_hint (GTK_WINDOW (insertnotedialog), GDK_WINDOW_TYPE_HINT_DIALOG);

  dialog_vbox1 = GTK_DIALOG (insertnotedialog)->vbox;
  gtk_widget_show (dialog_vbox1);

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

  hbox1 = gtk_hbox_new (FALSE, 2);
  gtk_widget_show (hbox1);
  gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (hbox1), 1);

  label1 = gtk_label_new_with_mnemonic ("N_umbering");
  gtk_widget_show (label1);
  gtk_box_pack_start (GTK_BOX (hbox1), label1, FALSE, FALSE, 0);

  GSList *radiobutton_numbering_automatic_group = NULL;
  
  radiobutton_numbering_automatic = gtk_radio_button_new_with_mnemonic (NULL, "Automatic");
  gtk_widget_show (radiobutton_numbering_automatic);
  gtk_box_pack_start (GTK_BOX (hbox1), radiobutton_numbering_automatic, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_numbering_automatic), radiobutton_numbering_automatic_group);
  radiobutton_numbering_automatic_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_numbering_automatic));

  radiobutton_numbering_none = gtk_radio_button_new_with_mnemonic (NULL, "None");
  gtk_widget_show (radiobutton_numbering_none);
  gtk_box_pack_start (GTK_BOX (hbox1), radiobutton_numbering_none, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_numbering_none), radiobutton_numbering_automatic_group);
  radiobutton_numbering_automatic_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_numbering_none));

  radiobutton_numbering_character = gtk_radio_button_new_with_mnemonic (NULL, "Character");
  gtk_widget_show (radiobutton_numbering_character);
  gtk_box_pack_start (GTK_BOX (hbox1), radiobutton_numbering_character, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_numbering_character), radiobutton_numbering_automatic_group);
  radiobutton_numbering_automatic_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_numbering_character));

  entry_numbering = gtk_entry_new ();
  gtk_widget_show (entry_numbering);
  gtk_box_pack_start (GTK_BOX (hbox1), entry_numbering, TRUE, TRUE, 0);
  gtk_entry_set_max_length (GTK_ENTRY (entry_numbering), 3);
  gtk_entry_set_activates_default (GTK_ENTRY (entry_numbering), TRUE);
  gtk_entry_set_width_chars (GTK_ENTRY (entry_numbering), 3);

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

  checkbutton_automatic_reference = gtk_check_button_new_with_mnemonic ("Automatically insert the current _reference");
  gtk_widget_show (checkbutton_automatic_reference);
  gtk_box_pack_start (GTK_BOX (vbox1), checkbutton_automatic_reference, FALSE, FALSE, 0);

  hbox2 = gtk_hbox_new (FALSE, 2);
  gtk_widget_show (hbox2);
  gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (hbox2), 1);

  checkbutton_chapter = gtk_check_button_new_with_mnemonic ("C_hapter");
  gtk_widget_show (checkbutton_chapter);
  gtk_box_pack_start (GTK_BOX (hbox2), checkbutton_chapter, FALSE, FALSE, 0);

  entry_reference_separator = gtk_entry_new ();
  gtk_widget_show (entry_reference_separator);
  gtk_box_pack_start (GTK_BOX (hbox2), entry_reference_separator, FALSE, FALSE, 0);
  gtk_entry_set_max_length (GTK_ENTRY (entry_reference_separator), 3);
  gtk_entry_set_width_chars (GTK_ENTRY (entry_reference_separator), 3);

  checkbutton_verse = gtk_check_button_new_with_mnemonic ("_Verse");
  gtk_widget_show (checkbutton_verse);
  gtk_box_pack_start (GTK_BOX (hbox2), checkbutton_verse, FALSE, FALSE, 0);

  entry_reference_suffix = gtk_entry_new ();
  gtk_widget_show (entry_reference_suffix);
  gtk_box_pack_start (GTK_BOX (hbox2), entry_reference_suffix, FALSE, FALSE, 0);
  gtk_entry_set_max_length (GTK_ENTRY (entry_reference_suffix), 5);
  gtk_entry_set_width_chars (GTK_ENTRY (entry_reference_suffix), 5);

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

  label_automatic_reference = gtk_label_new ("");
  gtk_widget_show (label_automatic_reference);
  gtk_box_pack_start (GTK_BOX (hbox2), label_automatic_reference, FALSE, FALSE, 0);

  // Add content button.
  
  hseparator5 = gtk_hseparator_new ();
  gtk_widget_show (hseparator5);
  gtk_box_pack_start (GTK_BOX (vbox1), hseparator5, TRUE, TRUE, 6);

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

  button_add = gtk_button_new ();
  gtk_widget_show (button_add);
  gtk_box_pack_start (GTK_BOX (hbox6), button_add, FALSE, FALSE, 0);

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

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

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

  label4 = gtk_label_new_with_mnemonic ("_Add content");
  gtk_widget_show (label4);
  gtk_box_pack_start (GTK_BOX (hbox7), label4, FALSE, FALSE, 0);

  // Templates.
  
  hseparator3 = gtk_hseparator_new ();
  gtk_widget_show (hseparator3);
  gtk_box_pack_start (GTK_BOX (vbox1), hseparator3, TRUE, TRUE, 6);

  label2 = gtk_label_new_with_mnemonic ("_Templates");
  gtk_widget_show (label2);
  gtk_box_pack_start (GTK_BOX (vbox1), label2, FALSE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);

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

  combobox_templates = gtk_combo_box_new_text ();
  gtk_widget_show (combobox_templates);
  gtk_box_pack_start (GTK_BOX (hbox3), combobox_templates, TRUE, TRUE, 0);
  GTK_WIDGET_SET_FLAGS (combobox_templates, GTK_CAN_FOCUS);
  
  button_template_new = gtk_button_new_from_stock ("gtk-new");
  gtk_widget_show (button_template_new);
  gtk_box_pack_start (GTK_BOX (hbox3), button_template_new, FALSE, FALSE, 0);

  button_template_delete = gtk_button_new_from_stock ("gtk-delete");
  gtk_widget_show (button_template_delete);
  gtk_box_pack_start (GTK_BOX (hbox3), button_template_delete, FALSE, FALSE, 0);

  dialog_action_area1 = GTK_DIALOG (insertnotedialog)->action_area;
  gtk_widget_show (dialog_action_area1);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);

  cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
  gtk_widget_show (cancelbutton1);
  gtk_dialog_add_action_widget (GTK_DIALOG (insertnotedialog), cancelbutton1, GTK_RESPONSE_CANCEL);
  GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT);

  okbutton1 = gtk_button_new_from_stock ("gtk-ok");
  gtk_widget_show (okbutton1);
  gtk_dialog_add_action_widget (GTK_DIALOG (insertnotedialog), okbutton1, GTK_RESPONSE_OK);
  GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);

  g_signal_connect ((gpointer) radiobutton_numbering_automatic, "toggled", G_CALLBACK (on_radiobutton_numbering_toggled), gpointer(this));
  g_signal_connect ((gpointer) radiobutton_numbering_none, "toggled", G_CALLBACK (on_radiobutton_numbering_toggled), gpointer(this));
  g_signal_connect ((gpointer) radiobutton_numbering_character, "toggled", G_CALLBACK (on_radiobutton_numbering_toggled), gpointer(this));
  g_signal_connect ((gpointer) entry_numbering, "activate", G_CALLBACK (on_entry_numbering_activate), gpointer(this));
  g_signal_connect ((gpointer) checkbutton_automatic_reference, "toggled", G_CALLBACK (on_checkbutton_automatic_reference_toggled), gpointer(this));
  g_signal_connect ((gpointer) checkbutton_chapter, "toggled", G_CALLBACK (on_checkbutton_chapter_toggled), gpointer(this));
  g_signal_connect ((gpointer) entry_reference_separator, "changed", G_CALLBACK (on_entry_reference_separator_changed), gpointer(this));
  g_signal_connect ((gpointer) entry_reference_separator, "activate", G_CALLBACK (on_entry_reference_separator_activate), gpointer(this));
  g_signal_connect ((gpointer) checkbutton_verse, "toggled", G_CALLBACK (on_checkbutton_verse_toggled), gpointer(this));
  g_signal_connect ((gpointer) entry_reference_suffix, "changed", G_CALLBACK (on_entry_reference_suffix_changed), gpointer(this));
  g_signal_connect ((gpointer) entry_reference_suffix, "activate", G_CALLBACK (on_entry_reference_suffix_activate), gpointer(this));
  g_signal_connect ((gpointer) button_add, "clicked", G_CALLBACK (on_button_add_clicked), gpointer(this));
  g_signal_connect ((gpointer) combobox_templates, "changed", G_CALLBACK (on_combobox_templates_changed), gpointer(this));
  g_signal_connect ((gpointer) button_template_new, "clicked", G_CALLBACK (on_button_template_new_clicked), gpointer(this));
  g_signal_connect ((gpointer) button_template_delete, "clicked", G_CALLBACK (on_button_template_delete_clicked), gpointer(this));
  g_signal_connect ((gpointer) okbutton1, "clicked", G_CALLBACK (on_okbutton1_clicked), gpointer(this));

  gtk_label_set_mnemonic_widget (GTK_LABEL (label2), combobox_templates);

  // Load available content markers.
  vector<Style> styles;
  stylesheet_get_styles (genconfig.stylesheet(), styles);
  for (unsigned int i = 0; i < styles.size(); i++) {
    switch (dialogtype) {
      case indtFootnote:
      case indtEndnote:
      {
        if (styles[i].type == stFootEndNote) {
          if ((styles[i].subtype == fentStandardContent)
           || (styles[i].subtype == fentContent)
           || (styles[i].subtype == fentContentWithEndmarker)
           || (styles[i].subtype == fentParagraph)) {
             content_markers.push_back (styles[i].marker);
             content_endmarkers.push_back (styles[i].subtype == fentContentWithEndmarker);
             content_names.push_back (styles[i].name);
           }
        }
        break;
      }
      case indtCrossreference:
      {
        if (styles[i].type == stCrossreference) {
          if ((styles[i].subtype == ctStandardContent)
           || (styles[i].subtype == ctContent)
           || (styles[i].subtype == ctContentWithEndmarker)) {
             content_markers.push_back (styles[i].marker);
             content_endmarkers.push_back (styles[i].subtype == ctContentWithEndmarker);
             content_names.push_back (styles[i].name);
           }
        }
        break;
      }
    }
  }

  // Set gui.
  ustring template_name;
  switch (dialogtype) {
    case indtFootnote:
      template_name = genconfig.insert_footnote_template();
      break;
    case indtEndnote:
      template_name = genconfig.insert_endnote_template();
      break;
    case indtCrossreference:
      template_name = genconfig.insert_xref_template();
      break;
  }
  templates_load (template_name);
  on_combobox_templates ();
}


InsertNoteDialog::~InsertNoteDialog ()
{
  gtk_widget_destroy (insertnotedialog);
}


int InsertNoteDialog::run ()
{
  return gtk_dialog_run (GTK_DIALOG (insertnotedialog));
}


void InsertNoteDialog::on_radiobutton_numbering_toggled (GtkToggleButton *togglebutton, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_radobutton_numbering (togglebutton);
}


void InsertNoteDialog::on_radobutton_numbering (GtkToggleButton *togglebutton)
{
  gtk_label_set_mnemonic_widget (GTK_LABEL (label1), GTK_WIDGET (togglebutton));
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radiobutton_numbering_character))) {
    gtk_widget_set_sensitive (entry_numbering, true);
  } else {
    gtk_widget_set_sensitive (entry_numbering, false);
  }
}


int InsertNoteDialog::numbering_get ()
{
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radiobutton_numbering_none)))
    return ntNone;
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radiobutton_numbering_character)))
    return ntCharacter;
  return ntAutomatic;
}


void InsertNoteDialog::numbering_set (int numbering)
{
  NumberingType numberingtype = (NumberingType) numbering;
  switch (numberingtype) {
    case ntAutomatic:
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_numbering_automatic), true);
      on_radobutton_numbering (GTK_TOGGLE_BUTTON (radiobutton_numbering_automatic));
      break;
    case ntNone:
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_numbering_none), true);
      on_radobutton_numbering (GTK_TOGGLE_BUTTON (radiobutton_numbering_none));
      break;
    case ntCharacter:
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_numbering_character), true);
      on_radobutton_numbering (GTK_TOGGLE_BUTTON (radiobutton_numbering_character));
      break;
  }
  
}


void InsertNoteDialog::on_entry_numbering_activate (GtkEntry *entry, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->focus_next_entry (entry);
}


void InsertNoteDialog::on_checkbutton_automatic_reference_toggled (GtkToggleButton *togglebutton, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_checkbutton_automatic_reference ();
}


void InsertNoteDialog::on_checkbutton_automatic_reference ()
{
  bool active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_automatic_reference));
  gtk_widget_set_sensitive (checkbutton_chapter, active);
  gtk_widget_set_sensitive (checkbutton_verse, active);
  gtk_widget_set_sensitive (entry_reference_suffix, active);
  gtk_widget_set_sensitive (label_automatic_reference, active);
  on_checkbutton_chapter ();
  on_checkbutton_verse ();
}


void InsertNoteDialog::on_checkbutton_chapter_toggled (GtkToggleButton *togglebutton, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_checkbutton_chapter ();
}


void InsertNoteDialog::on_checkbutton_chapter ()
{
  separator_sensitive_set ();
  reference_get ();
}


void InsertNoteDialog::separator_sensitive_set ()
{
  bool sensitive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_automatic_reference));
  if (sensitive)
    sensitive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_chapter));
  if (sensitive)
    sensitive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_verse));
  gtk_widget_set_sensitive (entry_reference_separator, sensitive);
}


void InsertNoteDialog::on_entry_reference_separator_changed (GtkEditable *editable, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_entry_reference_separator_changed2 ();
}


void InsertNoteDialog::on_entry_reference_separator_changed2 ()
{
  reference_get ();
}


void InsertNoteDialog::on_entry_reference_separator_activate (GtkEntry *entry, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->focus_next_entry (entry);
}


void InsertNoteDialog::on_checkbutton_verse_toggled (GtkToggleButton *togglebutton, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_checkbutton_verse ();
}


void InsertNoteDialog::on_checkbutton_verse ()
{
  separator_sensitive_set ();
  reference_get ();
}


void InsertNoteDialog::on_entry_reference_suffix_changed (GtkEditable *editable, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_entry_reference_suffix_changed2 ();
}


void InsertNoteDialog::on_entry_reference_suffix_changed2 ()
{
  reference_get ();
}


void InsertNoteDialog::on_entry_reference_suffix_activate (GtkEntry *entry, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->focus_next_entry (entry);
}


ustring InsertNoteDialog::reference_get ()
// Returns the reference as is going to be inserted in the note.
// Also set the label accordingly.
{
  // Variable for result.
  ustring result;
  // Configuration
  GeneralConfiguration genconfig (0);
  // If the separator widget is sensitive, get the chapter and verse.
  if (GTK_WIDGET_SENSITIVE (entry_reference_separator)) {
    result = genconfig.chapter() 
           + gtk_entry_get_text (GTK_ENTRY (entry_reference_separator))
           + genconfig.verse();
  } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_chapter))) {
    result = genconfig.chapter();
  } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_verse))) {
    result = genconfig.verse();
  }
  // Add the suffix.
  result.append (gtk_entry_get_text (GTK_ENTRY (entry_reference_suffix)));
  // See whether we to insert it.
  if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_automatic_reference)))
    result.clear();
  // Set the label.
  ustring label;
  if (!result.empty())
    label = "(" + result + ")";
  gtk_label_set_text (GTK_LABEL (label_automatic_reference), label.c_str());
  // Return result.
  return result;
}


void InsertNoteDialog::on_entry_content_activate (GtkEntry *entry, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->focus_next_entry (entry);
}


void InsertNoteDialog::on_button_content_clicked (GtkButton *button, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_button_content_remove (button);
}


void InsertNoteDialog::on_button_content_remove (GtkButton *button)
{
  // Get the offset of the widget to remove.
  int widget_offset = -1;
  for (unsigned int i = 0; i < button_contents.size(); i++) {
    if (GTK_WIDGET (button) == button_contents[i])
      widget_offset = i;
  }
  // Widget not found: bail out.
  if (widget_offset < 0)
    return;
  // Destroy the widgets.
  gtk_widget_destroy (vbox2s[widget_offset]);
  // Remove widget's pointers.
  vector_remove_content (vbox2s, widget_offset);
  vector_remove_content (combobox_styles, widget_offset);
  vector_remove_content (entry_contents, widget_offset);
  vector_remove_content (checkbutton_contents, widget_offset);
  vector_remove_content (button_contents, widget_offset);
}


void InsertNoteDialog::vector_remove_content (vector<GtkWidget *>& container, int offset)
{
  vector<GtkWidget *>::iterator iter;
  iter = container.begin();
  for (int i = 0; i < offset; i++)
    iter++;
  container.erase (iter);    
}


void InsertNoteDialog::on_button_add_clicked (GtkButton *button, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_button_add ();
}


void InsertNoteDialog::on_button_add ()
// Adds a new content entry to the gui.
{
  GtkWidget *vbox2;
  GtkWidget *hseparator4;
  GtkWidget *combobox_style;
  GtkWidget *entry_content;
  GtkWidget *hbox4;
  GtkWidget *checkbutton_content;
  GtkWidget *button_content;
  GtkWidget *alignment1;
  GtkWidget *hbox5;
  GtkWidget *image1;
  GtkWidget *label3;
  
  vbox2 = gtk_vbox_new (FALSE, 1);
  gtk_widget_show (vbox2);
  gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (vbox2), 1);

  hseparator4 = gtk_hseparator_new ();
  gtk_widget_show (hseparator4);
  gtk_box_pack_start (GTK_BOX (vbox2), hseparator4, TRUE, TRUE, 6);

  combobox_style = gtk_combo_box_new_text ();
  gtk_widget_show (combobox_style);
  gtk_box_pack_start (GTK_BOX (vbox2), combobox_style, TRUE, TRUE, 0);

  entry_content = gtk_entry_new ();
  gtk_widget_show (entry_content);
  gtk_box_pack_start (GTK_BOX (vbox2), entry_content, FALSE, FALSE, 0);

  hbox4 = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hbox4);
  gtk_box_pack_start (GTK_BOX (vbox2), hbox4, TRUE, TRUE, 0);

  checkbutton_content = gtk_check_button_new_with_mnemonic ("Remember content");
  gtk_widget_show (checkbutton_content);
  gtk_box_pack_start (GTK_BOX (hbox4), checkbutton_content, TRUE, TRUE, 0);

  button_content = gtk_button_new ();
  gtk_widget_show (button_content);
  gtk_box_pack_start (GTK_BOX (hbox4), button_content, FALSE, FALSE, 0);

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

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

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

  label3 = gtk_label_new_with_mnemonic ("Remove");
  gtk_widget_show (label3);
  gtk_box_pack_start (GTK_BOX (hbox5), label3, FALSE, FALSE, 0);
  
  g_signal_connect ((gpointer) entry_content, "activate", G_CALLBACK (on_entry_content_activate), gpointer(this));
  g_signal_connect ((gpointer) button_content, "clicked", G_CALLBACK (on_button_content_clicked), gpointer(this));

  gtk_box_reorder_child (GTK_BOX (vbox1), vbox2, vbox2s.size() + 4);

  vector<ustring> lines;
  for (unsigned int i = 0; i < content_markers.size(); i++) {
    ustring line;
    line.append (content_names[i] + " (" + usfm_get_full_opening_marker (content_markers[i]));
    if (content_endmarkers[i])
      line.append ("..." + usfm_get_full_closing_marker (content_markers[i]));
    line.append (")");
    lines.push_back (line);
  }
  combobox_set_strings (combobox_style, lines);
  if (lines.size() > 0)
    combobox_set_string (combobox_style, lines[0]);

  vbox2s.push_back(vbox2);
  combobox_styles.push_back(combobox_style);
  entry_contents.push_back(entry_content);
  checkbutton_contents.push_back(checkbutton_content);
  button_contents.push_back(button_content);
}


ustring InsertNoteDialog::template_filename_get (const ustring& template_name)
{
  ustring filename;
  switch (mydialogtype) {
    case indtFootnote:
      filename = "template-footnote-";
      break;
    case indtEndnote:
      filename = "template-endnote-";
      break;
    case indtCrossreference:
      filename = "template-crossreference-";
      break;
  }
  filename.append (template_name);
  return filename;
}


void InsertNoteDialog::templates_load (const ustring& template_name)
{
  ReadFiles rd (directories_get_configuration (), template_filename_get (""), "");
  for (unsigned int i = 0; i < rd.files.size(); i++)
    rd.files[i].erase (0, template_filename_get ("").length());
  if (rd.files.size() == 0)
    rd.files.push_back ("");
  combobox_set_strings (combobox_templates, rd.files);
  for (unsigned int i = 0; i < rd.files.size(); i++) {
    if (rd.files[i] == template_name) {
      combobox_set_string (combobox_templates, template_name);
    }
  }
}


void InsertNoteDialog::on_combobox_templates_changed (GtkComboBox *combobox, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_combobox_templates ();
}


void InsertNoteDialog::on_combobox_templates ()
// On a change of template, reload the values in the gui.
{
  // Load the template.
  ustring template_name = combobox_get_active_string (combobox_templates);
  NoteTemplate notetemplate (gw_build_filename (directories_get_configuration (), template_filename_get (template_name)), mydialogtype, false);
  // Set values in the fixed gui.
  gtk_entry_set_text (GTK_ENTRY (entry_numbering), notetemplate.anchor.c_str());
  gtk_entry_set_text (GTK_ENTRY (entry_reference_separator), notetemplate.reference_division.c_str());
  gtk_entry_set_text (GTK_ENTRY (entry_reference_suffix), notetemplate.reference_suffix.c_str());
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_chapter), notetemplate.reference_chapter);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_verse), notetemplate.reference_verse);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_automatic_reference), notetemplate.automatic_reference);
  // Clear away the dynamic gui.
  while (button_contents.size() > 0)
    on_button_content_remove (GTK_BUTTON (button_contents[0]));
  // Rebuild the dynamic gui.
  for (unsigned int i = 0; i < notetemplate.content_markers.size(); i++) {
    on_button_add ();
    combobox_set_string (combobox_styles[i], notetemplate.content_markers[i]);
    if (notetemplate.content_remembers[i])
      gtk_entry_set_text (GTK_ENTRY (entry_contents[i]), notetemplate.content_texts[i].c_str());
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_contents[i]), notetemplate.content_remembers[i]);
  }
  // Set remainder of gui.
  numbering_set (notetemplate.numbering);
  on_checkbutton_automatic_reference ();
  // Focus first content entry widget, if it is there.
  allow_entry_activate = true;
  focus_next_entry (GTK_ENTRY (entry_reference_suffix));
}


void InsertNoteDialog::on_button_template_new_clicked (GtkButton *button, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_button_template_new ();
}


void InsertNoteDialog::on_button_template_new ()
{
  EntryDialog dialog ("Template", "Enter a name for a new template", "");
  dialog.run ();
  ustring command;
  command = "touch";
  command.append (shell_quote_space (gw_build_filename (directories_get_configuration (), template_filename_get (dialog.entered_value))));
  system (command.c_str());
  templates_load (dialog.entered_value);
}


void InsertNoteDialog::on_button_template_delete_clicked (GtkButton *button, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_button_template_delete ();
}


void InsertNoteDialog::on_button_template_delete ()
{
  ustring filename = gw_build_filename (directories_get_configuration (), template_filename_get (combobox_get_active_string (combobox_templates)));
  unlink (filename.c_str());
  templates_load ("");
}


void InsertNoteDialog::focus_next_entry (GtkEntry * entry)
/*
The point of this function is that, when an entry is focused and it gets 
activated (by Enter), then the next entry should be focused.
This enables the user to quickly navigate through the gui and enter values.
At the end the Ok button should be focused.
*/
{
  // There is a mechanism in place that any entry that activates within
  // a millisecond after the previos one, will not be handles.
  // This is because for some reason if an entry gets focus, it immediately
  // give the activated signal, so activating the next, and the next, until the
  // end of the chain.
  if (!allow_entry_activate)
    return;
  allow_entry_activate = false;
  g_timeout_add (1, GSourceFunc (on_timeout), gpointer (this));
  GtkWidget * widget = GTK_WIDGET (entry);
  int current_entry = 0;
  if (widget == entry_numbering)
    current_entry = 1;
  else if (widget == entry_reference_separator)
    current_entry = 2;
  else if (widget == entry_reference_suffix)
    current_entry = 3;
  else {
    for (unsigned int i = 0; i < entry_contents.size(); i++)
      if (GTK_WIDGET_HAS_FOCUS (entry_contents[i]))
        current_entry = 4;
  }
  switch (current_entry) {
    case 0:
    {
      if (GTK_WIDGET_SENSITIVE (entry_numbering)) {
        gtk_widget_grab_focus (entry_numbering);
        break;
      }
    }
    case 1:
    {
      if (GTK_WIDGET_SENSITIVE (entry_reference_separator)) {
        gtk_widget_grab_focus (entry_reference_separator);
        break;
      }
    }
    case 2:
    {
      if (GTK_WIDGET_SENSITIVE (entry_reference_suffix)) {
        gtk_widget_grab_focus (entry_reference_suffix);
        break;
      }
    }
    case 3:
    {
      if (entry_contents.empty())
        break;
      gtk_widget_grab_focus (entry_contents[0]);
      break;
    }
    case 4:
    {
      unsigned int focused_entry = 0;
      for (unsigned int i = 0; i < entry_contents.size(); i++) {
        if (GTK_WIDGET_HAS_FOCUS (entry_contents[i]))
          focused_entry = i;
      }
      focused_entry++;
      if (focused_entry < entry_contents.size()) {
        gtk_widget_grab_focus (entry_contents[focused_entry]);
        break;
      }
    }
    case 5:
    {
      gtk_widget_grab_focus (okbutton1);
    }
  }
}


bool InsertNoteDialog::on_timeout (gpointer data)
{
  ((InsertNoteDialog *) data)->timeout ();
  return false;  
}


void InsertNoteDialog::timeout ()
{
  allow_entry_activate = true;
}

void InsertNoteDialog::on_okbutton1_clicked (GtkButton *button, gpointer user_data)
{
  ((InsertNoteDialog *) user_data)->on_okbutton ();
}


void InsertNoteDialog::on_okbutton ()
{
  // Save the current gui.
  GeneralConfiguration genconfig (0);
  NoteTemplate notetemplate (gw_build_filename (directories_get_configuration (), template_filename_get (combobox_get_active_string (combobox_templates))), mydialogtype, true);
  notetemplate.numbering = numbering_get ();
  notetemplate.anchor = gtk_entry_get_text (GTK_ENTRY (entry_numbering));
  notetemplate.automatic_reference = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_automatic_reference));
  notetemplate.reference_chapter = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_chapter));
  notetemplate.reference_division = gtk_entry_get_text (GTK_ENTRY (entry_reference_separator));
  notetemplate.reference_verse = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_verse));
  notetemplate.reference_suffix = gtk_entry_get_text (GTK_ENTRY (entry_reference_suffix));
  notetemplate.content_markers.clear();
  notetemplate.content_texts.clear();
  notetemplate.content_remembers.clear();
  for (unsigned int i = 0; i < vbox2s.size(); i++) {
    notetemplate.content_markers.push_back (combobox_get_active_string (combobox_styles[i]));
    notetemplate.content_texts.push_back (gtk_entry_get_text (GTK_ENTRY (entry_contents[i])));
    notetemplate.content_remembers.push_back (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_contents[i])));
  }
  switch (mydialogtype) {
    case indtFootnote:
    {
      genconfig.insert_footnote_template_set (combobox_get_active_string (combobox_templates));
      break;
    }
    case indtEndnote:
    {
      genconfig.insert_endnote_template_set (combobox_get_active_string (combobox_templates));
      break;
    }
    case indtCrossreference:
    {
      genconfig.insert_xref_template_set (combobox_get_active_string (combobox_templates));
      break;
    }
  }
  // Assemble the note to be inserted.
  ustring note;
  // Get some markers.
  ustring note_marker;
  ustring reference_marker;
  switch (mydialogtype) {
    case indtFootnote:
    {
      note_marker = "f";
      reference_marker = "fr";
      break;
    }
    case indtEndnote:
    {
      note_marker = "fe";
      reference_marker = "fr";
      break;
    }
    case indtCrossreference:
    {
      note_marker = "x";
      reference_marker = "xo";
      break;
    }
  }
  // Add note opener and numbering.
  note.append (usfm_get_full_opening_marker (note_marker));
  if (notetemplate.numbering == 0)
    note.append ("+");
  else if (notetemplate.numbering == 1)
    note.append ("-");
  else
    note.append (notetemplate.anchor);
  note.append (" ");
  // Deal with the reference.
  ustring reference = reference_get ();
  if (!reference.empty()) {
    note.append (usfm_get_full_opening_marker (reference_marker));
    note.append (reference);
  }
  // Add possible content.
  for (unsigned int i = 0; i < notetemplate.content_markers.size(); i++) {
    ustring marker;  
    size_t position, length;
    bool b;
    usfm_search_marker (notetemplate.content_markers[i], marker, position, length, b);
    if (!notetemplate.content_texts[i].empty()) {
      note.append (usfm_get_full_opening_marker (marker));
      note.append (notetemplate.content_texts[i]);
      for (unsigned int i2 = 0; i2 < content_markers.size(); i2++) {
        if (marker == content_markers[i2]) {
          if (content_endmarkers[i2]) {
            note.append (usfm_get_full_closing_marker (marker));
          }
        }
      }
      // Automatically add a space.
      note = trim (note);
      note.append (" ");
    }
  }
  // Remove last space.
  note = trim (note);
  // Add closing marker.
  note.append (usfm_get_full_closing_marker (note_marker));
  // Insert the note in the editor.
  gtk_text_buffer_insert_at_cursor (mytextbuffer, note.c_str(), -1);
}


// Todo give more space when using \ft.
// Todo Note templates. Instead of “new' do “save as”, and keep the settings as they are.

Generated by  Doxygen 1.6.0   Back to index