// -*- C++ -*-
/*
* GChemPaint templates plugin
* templatetree.cc
*
* Copyright (C) 2004-2007 Jean Bréfort <jean.brefort@normalesup.org>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "gchempaint-config.h"
#include "templatetree.h"
#include "templatetool.h"
#include "gtkcombotoolitem.h"
#include <lib/document.h>
#include <glib/gi18n-lib.h>
map<string, gcpTemplate*> Templates, TempbyName;
set<xmlDocPtr> docs;
xmlDocPtr user_templates = NULL;
gcpTemplate::gcpTemplate ():
node (NULL),
doc (NULL),
bond_length (0.)
{
}
gcpTemplate::~gcpTemplate()
{
if (doc)
delete (doc);
}
enum {
NAME_COLUMN,
NUM_COLUMNS
};
typedef struct
{
char* name;
} TreeItem;
gcpTemplateTree::gcpTemplateTree(gcpApplication* App): gcpTool (App, "TemplateTree")
{
model = gtk_tree_store_new (NUM_COLUMNS, G_TYPE_STRING);
GtkTreeIter iter, child_iter;
map<string, gcpTemplate*>::iterator i, end = Templates.end();
string category;
for (i = Templates.begin(); i!= end; i++) {
if (category != (*i).second->category) {
category = (*i).second->category;
gtk_tree_store_append (model, &iter, NULL);
gtk_tree_store_set (model, &iter,
NAME_COLUMN, category.c_str(),
-1);
}
gtk_tree_store_append (model, &child_iter, &iter);
gtk_tree_store_set (model, &child_iter,
NAME_COLUMN, (*i).second->name.c_str(),
-1);
GtkTreePath *path = gtk_tree_model_get_path ((GtkTreeModel*)model, &child_iter);
char* s = gtk_tree_path_to_string (path);
m_Templates[s] = (*i).second;
m_Paths[(*i).second] = s;
g_free (s);
gtk_tree_path_free (path);
}
}
gcpTemplateTree::~gcpTemplateTree()
{
}
void gcpTemplateTree::SetTemplate (gcpTemplate *t)
{
GtkTreePath* path = (t)? gtk_tree_path_new_from_string (m_Paths[t].c_str()): NULL;
GtkTreeIter iter;
if (path) {
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
gtk_combo_box_set_active_iter (combo, &iter);
gtk_tree_path_free (path);
} else
gtk_combo_box_set_active (combo, 0);
}
gcpTemplate* gcpTemplateTree::GetTemplate (string path)
{
return m_Templates[path];
}
const char* gcpTemplateTree::GetPath (gcpTemplate *t)
{
return m_Paths[t].c_str();
}
void gcpTemplateTree::AddTemplate (string& key)
{
map<string, gcpTemplate*>::iterator i = Templates.find (key), end = Templates.end ();
GtkTreeIter iter, parent;
GtkTreePath *path;
gcpTemplate *t, *new_temp = (*i).second;
if (i == Templates.begin()) {
i++;
if (i == end || ((*i).second->category != new_temp->category)) {
gtk_tree_store_prepend (model, &parent, NULL);
gtk_tree_store_set (model, &parent,
NAME_COLUMN, new_temp->category.c_str(),
-1);
} else {
path = gtk_tree_path_new_from_string (GetPath ((*i).second));
gtk_tree_path_up (path);
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, path);
gtk_tree_path_free (path);
}
gtk_tree_store_prepend (model, &iter, &parent);
gtk_tree_store_set (model, &iter,
NAME_COLUMN, new_temp->name.c_str(),
-1);
} else {
i--;
t = (*i).second;
if (t->category == new_temp->category) {
path = gtk_tree_path_new_from_string (GetPath (t));
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
gtk_tree_path_up (path);
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, path);
gtk_tree_path_free (path);
gtk_tree_store_insert_after (model, &iter, &parent, &iter);
gtk_tree_store_set (model, &iter,
NAME_COLUMN, new_temp->name.c_str(),
-1);
} else {
i++;
i++;
t = (*i).second;
if (i != Templates.end() && (t->category == new_temp->category)) {
path = gtk_tree_path_new_from_string (GetPath (t));
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
gtk_tree_path_up (path);
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, path);
gtk_tree_path_free (path);
gtk_tree_store_insert_before (model, &iter, &parent, &iter);
gtk_tree_store_set (model, &iter,
NAME_COLUMN, new_temp->name.c_str(),
-1);
} else {
//new category, must go backwards
i--;
i--;
path = gtk_tree_path_new_from_string (GetPath ((*i).second));
gtk_tree_path_up (path);
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
gtk_tree_store_insert_after (model, &parent, NULL, &iter);
gtk_tree_store_set (model, &parent,
NAME_COLUMN, new_temp->category.c_str(),
-1);
gtk_tree_store_append (model, &iter, &parent);
gtk_tree_store_set (model, &iter,
NAME_COLUMN, new_temp->name.c_str(),
-1);
}
}
}
UpdateMaps ();
}
void gcpTemplateTree::DeleteTemplate (string& key)
{
gcpTemplate *t = Templates[key];
GtkTreeIter iter, parent;
GtkTreePath *path, *path1;
const char *s = m_Paths[t].c_str();
path = gtk_tree_path_new_from_string (s);
path1 = gtk_tree_path_copy (path);
gtk_tree_path_up (path1);
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, path1);
gtk_tree_store_remove (model, &iter);
if (!gtk_tree_model_iter_has_child (GTK_TREE_MODEL (model), &parent)) {
gtk_tree_store_remove (model, &parent);
categories.erase (t->category);
}
gtk_tree_path_next (path);
gtk_tree_path_next (path1);
xmlNodePtr node = t->node->parent;
xmlDocPtr doc = t->node->doc;
xmlUnlinkNode (node);
xmlIndentTreeOutput = true;
xmlKeepBlanksDefault (0);
xmlSaveFormatFile((char*) doc->URL, doc, true);
xmlFreeNode (node);
Templates.erase (key);
delete t;
UpdateMaps ();
}
void gcpTemplateTree::UpdateMaps ()
{
map<string, gcpTemplate*>::iterator i, end = Templates.end ();
GtkTreePath *path;
char* s;
string category;
path = gtk_tree_path_new_first ();
gtk_tree_path_down (path);
//rebuild the maps
m_Paths.clear ();
m_Templates.clear ();
i = Templates.begin ();
category = (*i).second->category;
while (i != end) {
if ((*i).second->category != category) {
category = (*i).second->category;
gtk_tree_path_up (path);
gtk_tree_path_next (path);
gtk_tree_path_down (path);
}
s = gtk_tree_path_to_string (path);
m_Templates[s] = (*i).second;
m_Paths[(*i).second] = s;
g_free (s);
gtk_tree_path_next (path);
i++;
}
gtk_tree_path_free (path);
}
syntax highlighted by Code2HTML, v. 0.9.1