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

styletree.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 "stylesheetutils.h"
#include "gwrappers.h"
#include "gtkwrappers.h"
#include "styletree.h"
#include "usfmtools.h"
#include <map>
#include "dialogentry.h"
#include "projectutils.h"
#include "directories.h"
#include "utilities.h"
#include "shell.h"
#include "generalconfig.h"
#include "projectconfig.h"


void styletree_load_stylesheet (GtkTreeStore * store, const ustring& stylesheet, GtkTreeView * treeview)
// Load a whole stylesheet.
{
  vector<ustring> markers;
  vector<ustring> names0;
  markers = stylesheet_get_markers (stylesheet, &names0);
  map <ustring, ustring> names;
  for (unsigned int i = 0; i < markers.size(); i++) {
    names[markers[i]] = names0[i];
  }
  vector<UsfmCategory> categories;
  usfm_categorize_markers (markers, categories);
  UsfmCategory category = ucIdentificationInformation;
  bool insert_category = true;
  GtkTreeIter iter;
  for (unsigned int i = 0; i < markers.size(); i++) {
    if (categories[i] != category) {
      insert_category = true;
      category = categories[i];
    }
    ustring ucategory;
    if (insert_category) {
      ucategory = usfm_get_category_name (categories[i]);
      gtk_tree_store_append (store, &iter, NULL);
      gtk_tree_store_set (store, &iter, 0, ucategory.c_str(), -1);
    }
    GtkTreeIter child_iter;
    gtk_tree_store_append (store, &child_iter, &iter);
    ustring row;
    row = markers[i] + " " + names[markers[i]];
    gtk_tree_store_set (store, &child_iter, 0, row.c_str(), -1);
    if (insert_category) {
      bool state = styletree_get_state (ucategory);
      if (state) {
        GtkTreePath * path;
        path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
        gtk_tree_view_expand_row (treeview, path, false);
        gtk_tree_path_free (path);
      } 
    }
    insert_category = false;
  }
  while (gtk_events_pending ()) gtk_main_iteration ();
}


#define RECENTLY_USED "Recently Used"


void styletree_load_recently_used_styles (GtkTreeStore * store, GtkTreeView * treeview)
// Sets the recently used styles in the treeview.
{
  // Configuration
  GeneralConfiguration genconfig (0);
  // Get the often used styles, if there are any.
  vector<ustring> styles = stylesheet_get_recently_used (genconfig.stylesheet());
  {
    // Make it a complete style.
    for (unsigned int i = 0; i < styles.size(); i++) {
      Style styleobject (genconfig.stylesheet(), styles[i], false);
      styles[i] = styles[i] + " " + styleobject.name;
    }
  }
  // Proceed if there are still any styles left.
  if (!styles.empty()) {
    // Insert the category.
    GtkTreeIter iter;
    gtk_tree_store_append (store, &iter, NULL);
    gtk_tree_store_set (store, &iter, 0, RECENTLY_USED, -1);
    // Insert the styles themselves.
    GtkTreeIter child_iter;
    for (unsigned int i = 0; i < styles.size(); i++) {
      gtk_tree_store_append (store, &child_iter, &iter);
      gtk_tree_store_set (store, &child_iter, 0, styles[i].c_str(), -1);
    }
    // Expand if needed.
    bool state = styletree_get_state (RECENTLY_USED);
    if (state) {
      GtkTreePath * path;
      path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
      gtk_tree_view_expand_row (treeview, path, false);
      gtk_tree_path_free (path);
    } 
    // Focus the category.
    styletree_focus_string (GTK_WIDGET (treeview), RECENTLY_USED);
  }
  while (gtk_events_pending ()) gtk_main_iteration ();
}


void styletree_clear_recently_used_style (const ustring& style)
{
  // Configuration
  GeneralConfiguration genconfig (0);
  // Get the styles we now have.
  vector<ustring> styles1 = stylesheet_get_recently_used (genconfig.stylesheet());
  // Remove the style.
  vector<ustring> styles2;
  for (unsigned int i = 0; i < styles1.size(); i++) {
    if (styles1[i] != style)
      styles2.push_back(styles1[i]);
  }
  // Store the styles again.
  stylesheet_set_recently_used (genconfig.stylesheet(), styles2);
}


void styletree_clear_recently_used_styles ()
{
  GeneralConfiguration genconfig (0);
  vector<ustring> styles;
  stylesheet_set_recently_used (genconfig.stylesheet(), styles);
}


void styletree_use_style (GtkTreeStore * store, GtkWidget * treeview, const ustring& style)
// "Uses" a style, and so ranks it at the top of the recently used styles,
// and updates both the store and the configuration.
{
  // Configuration
  GeneralConfiguration genconfig (0);
  // Make a "complete" style, that is, style and name.
  ustring complete_style;
  {
    Style styleobject (genconfig.stylesheet(), style, false);
    complete_style = style + " " + styleobject.name;
  }
  // Get the styles we have often used.
  vector<ustring> old_styles = stylesheet_get_recently_used (genconfig.stylesheet());
  // Make them complete styles.
  for (unsigned int i = 0; i < old_styles.size(); i++) {
    Style styleobject (genconfig.stylesheet(), old_styles[i], false);
    old_styles[i] = old_styles[i] + " " + styleobject.name;
  }
  // Obtain a pointer to the style we have often used.
  unsigned int pointer = 1000;
  for (unsigned int i = 0; i < old_styles.size(); i++)
    if (complete_style == old_styles[i])
      pointer = i;
  // Container for rearranged styles.
  vector<ustring> new_styles;
  // Put the new one first.
  new_styles.push_back (complete_style);
  // Rearrange any other styles.
  for (unsigned int i = 0; i < old_styles.size(); i++) {
    if (i != pointer) {
      new_styles.push_back (old_styles[i]);
    }
  }
  // Display no more than a maximum number of styles.
  while (new_styles.size() > 30)
    new_styles.erase (new_styles.end());
  // Display information.
  GtkTreeModel * model;
  model = GTK_TREE_MODEL (store);
  // Some variables needed.
  GtkTreeIter iter;
  // Take out the frequently used category, if it is in.
  gtk_tree_model_get_iter_first (model, &iter);
  gchar *str_data;
  gtk_tree_model_get (model, &iter, 0, &str_data, -1);
  if (strcmp (str_data, RECENTLY_USED) == 0) {
    gtk_tree_store_remove (store, &iter);
  }
  g_free (str_data);
  // Add the category at the very start.
  gtk_tree_store_prepend (store, &iter, NULL);
  gtk_tree_store_set (store, &iter, 0, RECENTLY_USED, -1);
  // The iter now points to the frequently used row. Add any children here.
  GtkTreeIter child_iter;
  for (unsigned int i = 0; i < new_styles.size(); i++) {
    gtk_tree_store_append (store, &child_iter, &iter);
    gtk_tree_store_set (store, &child_iter, 0, new_styles[i].c_str(), -1);
  }
  // Expand if needed.
  bool state = styletree_get_state (RECENTLY_USED);
  if (state) {
    GtkTreePath * path;
    path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
    gtk_tree_view_expand_row (GTK_TREE_VIEW (treeview), path, false);
    gtk_tree_path_free (path);
  } 
  // Store recently used styles. Store marker only.
  for (unsigned int i = 0; i < new_styles.size(); i++) {
    Parse parse (new_styles[i]);
    new_styles[i] = parse.words[0];
  }
  stylesheet_set_recently_used (genconfig.stylesheet(), new_styles);
}


size_t styletree_get_state_offset (const ustring& row) 
{
  size_t offset = 0; // Default: recently used.
  if (row == usfm_get_category_name (ucIdentificationInformation))
    offset = 1;
  if (row == usfm_get_category_name (ucIntroductionTitlesHeadings))
    offset = 2;
  if (row == usfm_get_category_name (ucIntroductionParagraphsPoetry))
    offset = 3;
  if (row == usfm_get_category_name (ucIntroductionOtherElements))
    offset = 4;
  if (row == usfm_get_category_name (ucTitles))
    offset = 5;
  if (row == usfm_get_category_name (ucHeadings))
    offset = 6;
  if (row == usfm_get_category_name (ucChaptersAndVerses))
    offset = 7;
  if (row == usfm_get_category_name (ucParagraphs))
    offset = 8;
  if (row == usfm_get_category_name (ucLists))
    offset = 9;
  if (row == usfm_get_category_name (ucPoetryElements))
    offset = 10;
  if (row == usfm_get_category_name (ucTableElements))
    offset = 11;
  if (row == usfm_get_category_name (ucFootnotes))
    offset = 12;
  if (row == usfm_get_category_name (ucCrossReferences))
    offset = 13;
  if (row == usfm_get_category_name (ucExtendedStudyNotes))
    offset = 14;
  if (row == usfm_get_category_name (ucSpecialText))
    offset = 15;
  if (row == usfm_get_category_name (ucCharacterStyles))
    offset = 16;
  if (row == usfm_get_category_name (ucSpacingsAndBreaks))
    offset = 17;
  if (row == usfm_get_category_name (ucSpecialFeatures))
    offset = 18;
  if (row == usfm_get_category_name (ucPeripheralMaterials))
    offset = 19;
  if (row == usfm_get_category_name (ucNonstandardStyles))
    offset = 20;
  return offset;
}


void styletree_store_state (GtkTreeStore * store, GtkTreeIter *iter, bool expand)
{
  // Get the name of the row that has been affected.
  gchar *str_data;
  gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &str_data, -1);
  ustring row = str_data;
  g_free (str_data);
  // Store it in the configuration. Cater for 20 states.
  GeneralConfiguration genconfig (0);
  vector<bool> states = genconfig.styles_category_expanded ();
  if (states.size() < 20) {
    unsigned int add = 20 - states.size();
    for (unsigned int i = 0; i < add; i++)
      states.push_back (false);
  }
  size_t offset = styletree_get_state_offset (row);
  try {
    states[offset] = expand;
    genconfig.styles_category_expanded_set (states);
  }
  catch (exception & ex)
  {
    gw_critical (ex.what ());
  }
}


bool styletree_get_state (const ustring& row)
// Taking the string in "row", this returns the state as in configuration.
{
  // Look for the categorised rows, and if found return the state.
  bool state = false;
  GeneralConfiguration genconfig (0);
  vector<bool> states = genconfig.styles_category_expanded();
  size_t offset = styletree_get_state_offset (row);
  if (offset < states.size())
    state = states[offset];
  return state;
}


void internal_focus_iter (GtkWidget * treeview, GtkTreeModel * model, GtkTreeSelection * selection, GtkTreeIter * iter, bool expand)
{
  gtk_tree_selection_select_iter (selection, iter);
  GtkTreePath * path;
  path = gtk_tree_model_get_path (model, iter);
  if (expand) {
    gtk_tree_view_expand_to_path (GTK_TREE_VIEW (treeview), path);
  }
  gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, NULL, false);
  gtk_tree_path_free (path);
  while (gtk_events_pending ()) gtk_main_iteration ();
}


void styletree_focus_string (GtkWidget * treeview, const ustring& string)
// Focuses "string" in the treeview.
{
  // Get the model
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
  // Get the selection.
  GtkTreeSelection * selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
  // Some variables needed.
  GtkTreeIter iter;
  gboolean valid;
  bool focused = false;
  // Get the first iter in the store.
  valid = gtk_tree_model_get_iter_first (model, &iter);
  while (valid) {
    // 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);
    // If this is the string we wish to focus, select it, put the cursor on it,
    // and focus on the treeview.
    if (str_data == string) {
      // Only focus the first occurrence.
      if (!focused) {
        internal_focus_iter (treeview, model, selection, &iter, false);
      }
      focused = true;
    }
    g_free (str_data);
    // Walk through the children.
    GtkTreeIter child_iter;
    bool valid_child;
    valid_child = gtk_tree_model_iter_children (model, &child_iter, &iter);
    while (valid_child) {
      gchar *str_data;
      gtk_tree_model_get (model, &child_iter, 0, &str_data, -1);
      if (str_data == string) {
        if (!focused)
          internal_focus_iter (treeview, model, selection, &child_iter, true);
        focused = true;
      }
      g_free (str_data);
      valid_child = gtk_tree_model_iter_next (model, &child_iter);      
    }
    valid = gtk_tree_model_iter_next (model, &iter);
  }
  while (gtk_events_pending ()) gtk_main_iteration ();
}


void styletree_get_focused_strings (GtkWidget * treeview, vector<ustring>& focused_strings, 
                                    vector<bool>& recently_used, vector<bool>& categories)
{
  // Get the model
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
  // Get the selection.
  GtkTreeSelection * selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
  // Get the selected paths.
  GList *sellist = NULL;
  sellist = gtk_tree_selection_get_selected_rows (selection, &model);
  // Walk through all selected ones.
  while (sellist) {
    // Get the path.
    GtkTreePath * path = (GtkTreePath *) sellist->data;
    // Get iterator to the style.
    GtkTreeIter iter;
    gtk_tree_model_get_iter (model, &iter, path);
    // Get the data.
    gchar *str_data;
    gtk_tree_model_get (model, &iter, 0, &str_data, -1);
    ustring data = str_data;
    // Store the style.
    focused_strings.push_back (data);
    // Free memory.    
    g_free (str_data);
    // See whether we're in the recently used styles or elsewhere.
    bool recently_used_style = false;
    GtkTreeIter parent_iter;
    if (gtk_tree_model_iter_parent (model, &parent_iter, &iter)) {
      gchar *str_data;
      gtk_tree_model_get (model, &parent_iter, 0, &str_data, -1);
      recently_used_style = (strcmp (str_data, RECENTLY_USED) == 0);
      g_free (str_data);
    }
    recently_used.push_back (recently_used_style);
    // See whether we're in a category or elsewhere.
    // Depth 1: category; depth 2: style.
    int depth = gtk_tree_path_get_depth (path);
    categories.push_back (depth == 1);
    // Free memory.
    gtk_tree_path_free (path);
    // Next round.
    sellist = sellist->next;
  }
  // Free memory for list.
  g_list_free (sellist);
}


ustring styletree_get_focused_style (GtkWidget * treeview)
{
  // Containers.
  vector<ustring> focused_strings;
  vector<bool> recently_used;
  vector<bool> categories;
  // Get all focused strings.
  styletree_get_focused_strings (treeview, focused_strings, recently_used, categories);
  // Focused styles.
  vector<ustring> focused_styles;
  for (unsigned int i = 0; i < focused_strings.size(); i++) {
    if (!categories[i])
      focused_styles.push_back (focused_strings[i]);
  }
  // Focused style.
  ustring focused_style;
  if (focused_styles.size() > 0) {
    focused_style = focused_styles[0];
    size_t pos = focused_style.find (" ");
    focused_style = focused_style.substr (0, pos);
  }
  return focused_style; 
}


vector<ustring> styletree_get_focused_regular_styles (GtkWidget * treeview)
{
  // Containers.
  vector<ustring> focused_strings;
  vector<bool> recently_used;
  vector<bool> categories;
  // Get all focused strings.
  styletree_get_focused_strings (treeview, focused_strings, recently_used, categories);
  // Focused styles.
  vector<ustring> focused_styles;
  for (unsigned int i = 0; i < focused_strings.size(); i++) {
    if (!categories[i]) {
      if (!recently_used[i]) {
        size_t pos = focused_strings[i].find (" ");
        focused_styles.push_back (focused_strings[i].substr (0, pos));
      }
    }
  }
  return focused_styles;
}


vector<ustring> styletree_get_focused_recently_used_styles (GtkWidget * treeview)
{
  // Containers.
  vector<ustring> focused_strings;
  vector<bool> recently_used;
  vector<bool> categories;
  // Get all focused strings.
  styletree_get_focused_strings (treeview, focused_strings, recently_used, categories);
  // Focused styles.
  vector<ustring> focused_styles;
  for (unsigned int i = 0; i < focused_strings.size(); i++) {
    if (!categories[i]) {
      if (recently_used[i]) {
        size_t pos = focused_strings[i].find (" ");
        focused_styles.push_back (focused_strings[i].substr (0, pos));
      }
    }
  }
  return focused_styles;
}


vector<ustring> styletree_get_focused_categories (GtkWidget * treeview)
{
  // Containers.
  vector<ustring> focused_strings;
  vector<bool> recently_used;
  vector<bool> categories;
  // Get all focused strings.
  styletree_get_focused_strings (treeview, focused_strings, recently_used, categories);
  // Focused styles.
  vector<ustring> focused_categories;
  for (unsigned int i = 0; i < focused_strings.size(); i++) {
    if (categories[i]) {
      focused_categories.push_back (focused_strings[i]);
    }
  }
  return focused_categories;
}



ustring styletree_get_string_before_focus (GtkWidget * treeview)
// This returns the visible text just before the first focused item.
{
  // Variable.
  ustring returnvalue;
  // Get all focused strings. If none, do nothing.
  vector<ustring> focused_strings;
  vector<bool> dummy1, dummy2;
  styletree_get_focused_strings (treeview, focused_strings, dummy1, dummy2);
  if (!focused_strings.empty()) {
    // Get the model
    GtkTreeModel * model;
    model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
    // Some variables needed.
    GtkTreeIter iter;
    gboolean valid;
    ustring previousvalue;
    // Get the first iter in the store.
    valid = gtk_tree_model_get_iter_first (model, &iter);
    while (valid) {
      // Walk through the list, reading each row
      gchar *str_data;
      gtk_tree_model_get (model, &iter, 0, &str_data, -1);
      // If this is the first focused string, store the previous value.
      if (strcmp (str_data, focused_strings[0].c_str()) == 0)
        returnvalue = previousvalue;
      // Set previous value for next round.
      previousvalue = str_data;
      // Free memory.
      g_free (str_data);
      // See whether the row is expanded.
      GtkTreePath * path;
      path = gtk_tree_model_get_path (model, &iter);
      bool row_expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (treeview), path);
      gtk_tree_path_free (path);
      // If row expanded, walk through the children.
      if (row_expanded) {
        GtkTreeIter child_iter;
        bool valid_child;
        valid_child = gtk_tree_model_iter_children (model, &child_iter, &iter);
        while (valid_child) {
          gchar *str_data;
          gtk_tree_model_get (model, &child_iter, 0, &str_data, -1);
          if (strcmp (str_data, focused_strings[0].c_str()) == 0)
            returnvalue = previousvalue;
          previousvalue = str_data;
          g_free (str_data);
          valid_child = gtk_tree_model_iter_next (model, &child_iter);      
        }
      }
      valid = gtk_tree_model_iter_next (model, &iter);
    }
  }    
  // Return the result.
  return returnvalue;
}


void styletree_rename_stylesheet (GtkWidget * parent)
{
  // Get the current name of the stylesheet, and ask for a new name.
  GeneralConfiguration genconfig (0);
  ustring currentname = genconfig.stylesheet();
  EntryDialog dialog ("Rename stylesheet", "Give a new name for this stylesheet", currentname);
  if (dialog.run() == GTK_RESPONSE_OK) {
    // Check whether the new name does not already exist.
    if (!stylesheet_exists (dialog.entered_value)) {
      // Ok, new name is still free.
      // Check all projects and if they have this stylesheet, rename it.
      vector<ustring> affected_projects;
      ustring current_project = genconfig.project();
      vector <ustring> projects = projects_get_all ();
      for (unsigned int i = 0; i < projects.size(); i++) {
        genconfig.project_set (projects[i]);
        ProjectConfiguration projectconfig ("");
        if (projectconfig.stylesheet() == currentname) {
          projectconfig.stylesheet_set (dialog.entered_value);
          affected_projects.push_back (projects[i]);
        }
      }
      genconfig.project_set (current_project);
      // Rename the stylesheet itself.
      // Note: This should be done after checking on which projects have it, 
      // due to a feature in the project object that it only gives an existing
      // stylesheet.
      stylesheet_copy (currentname, dialog.entered_value);
      stylesheet_delete (currentname);
      // Store new name in configuration.
      genconfig.stylesheet_set (dialog.entered_value);
      // If projects were affected, mention that.
      if (affected_projects.size() > 0) {
        ustring message = "The stylesheets attached to the following projects were changed along:\n\n";
        for (unsigned int i = 0; i < affected_projects.size(); i++)
          message.append (affected_projects[i] + "\n");
        gtkw_dialog_info (parent, message.c_str());
      }
    } else {
      // No, it already exist - give message about that.
      gtkw_dialog_error (parent, "This name already exists.");
    }
  }
}


bool styletree_import_stylesheet (GtkWidget * parent)
{
  bool returnvalue = false;
  GtkWidget *dialog;
  dialog = gtk_file_chooser_dialog_new ("Open stylesheet", GTK_WINDOW (parent),
    GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
    GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
  int result = gtk_dialog_run (GTK_DIALOG (dialog));
  if (result == GTK_RESPONSE_ACCEPT) {
    GeneralConfiguration genconfig (0);
    ustring filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
    ustring name = stylesheet_import (filename);
    if (!name.empty()) {
      // Save the name of the stylesheet in two locations.
      genconfig.stylesheet_set (name);
      if (!genconfig.project().empty()) {
        ProjectConfiguration projectconfig ("");
        projectconfig.stylesheet_set (name);
      }
      // Open the sheet.
      returnvalue = true;
    }
  }
  gtk_widget_destroy (dialog);
  return returnvalue;
}


void styletree_export_stylesheet (GtkWidget * parent)
{
  GeneralConfiguration genconfig (0);
  ustring name = genconfig.stylesheet();
  GtkWidget *dialog;
  dialog = gtk_file_chooser_dialog_new ("Save to a file", GTK_WINDOW (parent),
    GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
    GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), name.c_str());
  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
    ustring filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
    ustring command;
    command = "bibledit --export-stylesheet ";
    command.append ("--stylesheet" + shell_quote_space (name));
    command.append ("--file" + shell_quote_space (filename));
    system (command.c_str());
  }
  gtk_widget_destroy (dialog);  
}


void styletree_delete_categories (vector<ustring> categories)
{
  // Configuration
  GeneralConfiguration genconfig (0);
  // Get a list of all the markers in our stylesheet.
  vector<ustring> markers;
  markers = stylesheet_get_markers (genconfig.stylesheet(), NULL);
  // Categorize them all.
  vector<UsfmCategory> usfmcategories;
  usfm_categorize_markers (markers, usfmcategories);
  // Get the human readable form of the category for them all.
  vector<ustring> ucategories;
  for (unsigned int i = 0; i < usfmcategories.size(); i++) {
    ucategories.push_back (usfm_get_category_name (usfmcategories[i]));
  }
  // Go through all categories we wish to delete.  
  for (unsigned int i = 0; i < categories.size(); i++) {
    if (categories[i] == RECENTLY_USED) {
      // If it's the recently used category, clear it.
      styletree_clear_recently_used_styles ();
    } else {
      // If it's a regular category, clear it completely.
      for (unsigned int i2 = 0; i2 < markers.size(); i2++) {
        if (categories[i] == ucategories[i2]) {
          stylesheet_delete_style (genconfig.stylesheet(), markers[i2]);          
        }
      }
    }
  }
}


bool styletree_expand_collapse (GtkWidget * treeview, bool expand)
// Expands (or collapses) the last selected item(s) in the treeview.
{
  // Indication whether we expanded or collapsed something.
  bool expanded_collapsed = false;
  // Get the model
  GtkTreeModel * model;
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
  // Get the selection.
  GtkTreeSelection * selection;
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
  // Some variables needed.
  GtkTreeIter iter;
  gboolean valid;
  // Get the first iter in the store.
  valid = gtk_tree_model_get_iter_first (model, &iter);
  while (valid) {
    // Walk through the list.
    if (gtk_tree_selection_iter_is_selected (selection, &iter)) {
      GtkTreePath * path;
      path = gtk_tree_model_get_path (model, &iter);
      if (expand)
        gtk_tree_view_expand_row (GTK_TREE_VIEW (treeview), path, false);
      else
        gtk_tree_view_collapse_row (GTK_TREE_VIEW (treeview), path);
      gtk_tree_path_free (path);
      expanded_collapsed = true;
    }
    // Next.
    valid = gtk_tree_model_iter_next (model, &iter);
  }
  // Return whether we did something.
  return expanded_collapsed;
}

Generated by  Doxygen 1.6.0   Back to index