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

dialogprintorderportion.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 "dialogprintorderportion.h"
#include "utilities.h"
#include "bible.h"
#include "dialogselectchapters.h"
#include "projectutils.h"
#include "books.h"
#include "scripture_reordered.h"
#include "projectconfig.h"


enum { COLUMN_BOOK, COLUMN_INCLUDE, COLUMN_PORTION, NUM_COLUMNS };


PrintOrderPortionDialog::PrintOrderPortionDialog (int dummy):
  genconfig (0)
{
  printorderportiondialog = gtk_dialog_new ();
  gtk_window_set_title (GTK_WINDOW (printorderportiondialog), "Book order and portion");
  gtk_window_set_position (GTK_WINDOW (printorderportiondialog), GTK_WIN_POS_CENTER_ON_PARENT);
  gtk_window_set_modal (GTK_WINDOW (printorderportiondialog), TRUE);
  gtk_window_set_destroy_with_parent (GTK_WINDOW (printorderportiondialog), TRUE);
  gtk_window_set_type_hint (GTK_WINDOW (printorderportiondialog), GDK_WINDOW_TYPE_HINT_DIALOG);

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

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

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

  treeview1 = gtk_tree_view_new ();
  gtk_widget_show (treeview1);
  gtk_container_add (GTK_CONTAINER (scrolledwindow1), treeview1);
  gtk_widget_set_size_request (treeview1, -1, 400);
  gtk_tree_view_set_reorderable (GTK_TREE_VIEW (treeview1), TRUE);

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

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

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

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

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

  label5 = gtk_label_new_with_mnemonic ("Old _Testament");
  gtk_widget_show (label5);
  gtk_box_pack_start (GTK_BOX (hbox3), label5, FALSE, FALSE, 0);

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

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

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

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

  label6 = gtk_label_new_with_mnemonic ("_New Testament");
  gtk_widget_show (label6);
  gtk_box_pack_start (GTK_BOX (hbox4), label6, FALSE, FALSE, 0);

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

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

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

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

  label7 = gtk_label_new_with_mnemonic ("_All books");
  gtk_widget_show (label7);
  gtk_box_pack_start (GTK_BOX (hbox5), label7, FALSE, FALSE, 0);

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

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

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

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

  label8 = gtk_label_new_with_mnemonic ("C_urrent book");
  gtk_widget_show (label8);
  gtk_box_pack_start (GTK_BOX (hbox6), label8, FALSE, FALSE, 0);

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

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

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

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

  label9 = gtk_label_new_with_mnemonic ("_Standard order");
  gtk_widget_show (label9);
  gtk_box_pack_start (GTK_BOX (hbox8), label9, FALSE, FALSE, 0);

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

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

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

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

  label10 = gtk_label_new_with_mnemonic ("_Portion");
  gtk_widget_show (label10);
  gtk_box_pack_start (GTK_BOX (hbox9), label10, FALSE, FALSE, 0);

  dialog_action_area1 = GTK_DIALOG (printorderportiondialog)->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 (printorderportiondialog), 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 (printorderportiondialog), okbutton1, GTK_RESPONSE_OK);
  GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);

  g_signal_connect ((gpointer) treeview1, "cursor_changed",
                    G_CALLBACK (on_treeview1_cursor_changed),
                    gpointer(this));
  g_signal_connect ((gpointer) button_ot, "clicked",
                    G_CALLBACK (on_button_ot_clicked),
                    gpointer(this));
  g_signal_connect ((gpointer) button_nt, "clicked",
                    G_CALLBACK (on_button_nt_clicked),
                    gpointer(this));
  g_signal_connect ((gpointer) button_all, "clicked",
                    G_CALLBACK (on_button_all_clicked),
                    gpointer(this));
  g_signal_connect ((gpointer) button_current, "clicked",
                    G_CALLBACK (on_button_current_clicked),
                    gpointer(this));
  g_signal_connect ((gpointer) button_standard_order, "clicked",
                    G_CALLBACK (on_button_standard_order_clicked),
                    gpointer(this));
  g_signal_connect ((gpointer) button_portion, "clicked",
                    G_CALLBACK (on_button_portion_clicked),
                    gpointer(this));
  g_signal_connect ((gpointer) okbutton1, "clicked",
                    G_CALLBACK (on_okbutton1_clicked),
                    gpointer(this));

  gtk_widget_grab_focus (treeview1);
  gtk_widget_grab_default (okbutton1);

  // Storage, renderer, column and selection.
  store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING);
  gtk_tree_view_set_model (GTK_TREE_VIEW (treeview1), GTK_TREE_MODEL (store));
  g_object_unref (store);
  GtkCellRenderer * renderer;
  renderer = gtk_cell_renderer_text_new ();
  column1 = gtk_tree_view_column_new_with_attributes ("Book", renderer, "text", COLUMN_BOOK, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview1), column1);
  renderer = gtk_cell_renderer_toggle_new ();
  g_signal_connect (renderer, "toggled", G_CALLBACK (include_toggled), store);
  column2 = gtk_tree_view_column_new_with_attributes ("Include", renderer, "active", COLUMN_INCLUDE, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview1), column2);
  renderer = gtk_cell_renderer_text_new ();
  column3 = gtk_tree_view_column_new_with_attributes ("Portion", renderer, "text", COLUMN_PORTION, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview1), column3);
  select = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1));
  gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);

  // Load content.
  ScriptureReordered scripture_reordered (genconfig.project());
  GtkTreeIter iter;
  for (unsigned int i = 0; i < scripture_reordered.reordered_books.size(); i++) {
    gtk_list_store_append (store, &iter);
    bool include = scripture_reordered.reordered_includes[i];  
    gtk_list_store_set (store, &iter, COLUMN_BOOK, scripture_reordered.reordered_books[i].c_str (), COLUMN_INCLUDE, include, COLUMN_PORTION, scripture_reordered.reordered_portions[i].c_str(), -1);
  }

  // Set rest of gui.
  on_treeview1_cursor ();
}


PrintOrderPortionDialog::~PrintOrderPortionDialog ()
{
  gtk_widget_destroy (printorderportiondialog);
}


int PrintOrderPortionDialog::run ()
{
  return gtk_dialog_run (GTK_DIALOG (printorderportiondialog));
}


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


void PrintOrderPortionDialog::on_okbutton ()
{
  // Containers.
  vector<ustring> reordered_books;
  vector<bool> reordered_includes;
  vector<ustring> reordered_portions;
  // Get the model
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview1));
  // Some variables needed.
  GtkTreeIter iter;
  gboolean valid;
  gint index = 0;
  // Get the first iter in the store.
  valid = gtk_tree_model_get_iter_first (model, &iter);
  while (valid) {
    // Produce path.
    GtkTreePath * path = NULL;
    path = gtk_tree_path_new_from_indices (index, -1);
    // Walk through the list, reading each row
    gchar *str_book;
    gboolean include_data;
    gchar *str_portion;
    gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COLUMN_BOOK, &str_book, COLUMN_INCLUDE, &include_data, COLUMN_PORTION, &str_portion, -1);
    reordered_books.push_back (str_book);
    reordered_includes.push_back (include_data);
    reordered_portions.push_back (str_portion);
    // Free some data.
    gtk_tree_path_free (path);
    g_free (str_book);
    g_free (str_portion);
    // Next row.
    valid = gtk_tree_model_iter_next (model, &iter);
    index++;
  }
  // Save reordered books.
  ProjectConfiguration projectconfig ("");
  projectconfig.reordered_books_set (reordered_books);
  projectconfig.reordered_includes_set (reordered_includes);
  projectconfig.reordered_portions_set (reordered_portions);
}


void PrintOrderPortionDialog::on_button_ot_clicked (GtkButton *button, gpointer user_data)
{
  ((PrintOrderPortionDialog *) user_data)->on_button_ot ();
}


void PrintOrderPortionDialog::on_button_ot ()
{
  set <ustring> books;
  for (unsigned int i = BOOKS_OT_FIRST_ID; i <= BOOKS_OT_LAST_ID; i++)
    books.insert (books_id_to_english (i));
  books_include (books);
}


void PrintOrderPortionDialog::on_button_nt_clicked (GtkButton *button, gpointer user_data)
{
  ((PrintOrderPortionDialog *) user_data)->on_button_nt ();
}


void PrintOrderPortionDialog::on_button_nt ()
{
  set <ustring> books;
  for (unsigned int i = BOOKS_NT_FIRST_ID; i <= BOOKS_NT_LAST_ID; i++)
    books.insert (books_id_to_english (i));
  books_include (books);
}


void PrintOrderPortionDialog::on_button_all_clicked (GtkButton *button, gpointer user_data)
{
  ((PrintOrderPortionDialog *) user_data)->on_button_all ();
}


void PrintOrderPortionDialog::on_button_all ()
{
  vector<ustring> scripture_books = project_get_books (genconfig.project());
  set <ustring> books (scripture_books.begin(), scripture_books.end());
  books_include (books);
}


void PrintOrderPortionDialog::on_button_current_clicked (GtkButton *button, gpointer user_data)
{
  ((PrintOrderPortionDialog *) user_data)->on_button_current ();
}


void PrintOrderPortionDialog::on_button_current ()
{
  set <ustring> books;
  books.insert (genconfig.book());
  books_include (books);
}


void PrintOrderPortionDialog::on_button_standard_order_clicked (GtkButton *button, gpointer user_data)
{
  ((PrintOrderPortionDialog *) user_data)->on_button_standard_order ();
}


void PrintOrderPortionDialog::on_button_standard_order ()
{
  // Get the model
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview1));
  // Get the selection.
  GtkTreeSelection * selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1));
  // Go through all the Bible books.
  for (unsigned int i = BOOKS_OT_FIRST_ID; i <= BOOKS_NT_LAST_ID; i++) {
    // Get English bookname, e.g. Matthew.
    ustring book = books_id_to_english (i);
    // Some variables needed to iterate through the model.
    GtkTreeIter iter;
    gboolean valid;
    gint index = 0;
    // Get the first iter in the store.
    valid = gtk_tree_model_get_iter_first (model, &iter);
    // Go through the store.
    while (valid) {
      // Produce path.
      GtkTreePath * path = NULL;
      path = gtk_tree_path_new_from_indices (index, -1);
      // Read the row.
      gchar *str_data;
      gtk_tree_model_get (model, &iter, 0, &str_data, -1);
      // See if this is the book we wish to reorder.
      if (book == str_data) {
        // Move this one to the end of the store.
        gtk_list_store_move_before (GTK_LIST_STORE (model), &iter, NULL);
      }
      // Free some data.
      gtk_tree_path_free (path);
      g_free (str_data);
      // Next row.
      valid = gtk_tree_model_iter_next (model, &iter);
      index++;
    }
  }
}


void PrintOrderPortionDialog::include_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data)
{
  GtkTreeModel *model = (GtkTreeModel *)data;
  GtkTreeIter iter;
  GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
  gboolean include;
  // Get include iter
  gtk_tree_model_get_iter (model, &iter, path);
  gtk_tree_model_get (model, &iter, COLUMN_INCLUDE, &include, -1);
  // Toggle include 
  include = !include;
  // Set new value
  gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_INCLUDE, include, -1);
  // Clean up
  gtk_tree_path_free (path);
}


void PrintOrderPortionDialog::on_button_portion_clicked (GtkButton *button, gpointer user_data)
{
  ((PrintOrderPortionDialog *) user_data)->on_button_portion ();
}


void PrintOrderPortionDialog::on_button_portion ()
{
  // Get the selected portion.
  ustring book, portion;
  bool include;
  if (!selection_get (book, include, portion))
    return;
  // Run the dialog to select a portion.
  SelectChaptersDialog dialog (genconfig.project(), book, portion);
  if (dialog.run() == GTK_RESPONSE_OK) {
    // Ok, we've new portion: store it.
    // Some variables needed.
    GtkTreeModel * model;
    model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview1));
    GtkTreeIter iter;
    // Get the selected iterator.
    if (gtk_tree_selection_get_selected (select, &model, &iter)) {
      gtk_list_store_set (store, &iter, COLUMN_PORTION, dialog.new_selection.c_str(), -1);
    }
  }
}


void PrintOrderPortionDialog::on_treeview1_cursor_changed (GtkTreeView *treeview, gpointer user_data)
{
  g_timeout_add (1, GSourceFunc (on_timeout), user_data);
}


bool PrintOrderPortionDialog::on_timeout (gpointer data)
{
  ((PrintOrderPortionDialog *) data)->on_treeview1_cursor ();
  return false;
}


void PrintOrderPortionDialog::on_treeview1_cursor ()
{
  ustring book, portion;
  bool include;
  bool sensitive = false;
  if (selection_get (book, include, portion)) {
    if (include)
      sensitive = true;
  }
  gtk_widget_set_sensitive (button_portion, sensitive);
}


bool PrintOrderPortionDialog::selection_get (ustring& book, bool& include, ustring& portion)
{
  // Whether there was a selection.
  bool selected = false;
  // Get the model
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview1));
  // Some variables needed.
  GtkTreeIter iter;
  // Get the selected iterator.
  if (gtk_tree_selection_get_selected (select, &model, &iter)) {
    gchar *str_book;
    gboolean include_data;
    gchar *str_portion;
    gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COLUMN_BOOK, &str_book, COLUMN_INCLUDE, &include_data, COLUMN_PORTION, &str_portion, -1);
    book = str_book;
    g_free (str_book);
    include = include_data;
    portion = str_portion;
    g_free (str_portion);
    selected = true;
  }
  // Return result.
  return selected;  
}


void PrintOrderPortionDialog::books_include (set<ustring>& books)
{
  // Get the model
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview1));
  // Get the selection.
  GtkTreeSelection * selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1));
  // Some variables needed.
  GtkTreeIter iter;
  gboolean valid;
  gint index = 0;
  bool focused = false;
  // Get the first iter in the store.
  valid = gtk_tree_model_get_iter_first (model, &iter);
  while (valid) {
    // Produce path.
    GtkTreePath * path = NULL;
    path = gtk_tree_path_new_from_indices (index, -1);
    // Walk through the list, reading each row
    gchar *str_data;
    // Make sure you terminate calls to gtk_tree_model_get() with a '-1' value.
    gtk_tree_model_get (model, &iter, 0, &str_data, -1);
    // See if this is the book we wish to include.
    bool include = books.find (str_data) != books.end();
    // Put cursor on first one selected and select it.
    if (include) {
      if (path) {
        if (!focused) {
          gtk_tree_selection_select_iter (selection, &iter);
          gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview1), path, NULL, false);
          gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (treeview1), path, NULL, true, 0.5, 0.5);
          focused = true;
        }
      }
      gtk_widget_grab_focus (treeview1);
    }
    // Set whether to include this book.
    gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_INCLUDE, include, -1);
    // Free some data.
    gtk_tree_path_free (path);
    g_free (str_data);
    // Next row.
    valid = gtk_tree_model_iter_next (model, &iter);
    index++;
  }
}

Generated by  Doxygen 1.6.0   Back to index