// -*- C++ -*- /* * GChemPaint templates plugin * plugin.cc * * Copyright (C) 2004 Jean Bréfort * * 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 "plugin.h" #include "lib/application.h" #include "templatetool.h" #include "templatetree.h" #include "category.h" #include #include #include gcpTemplatesPlugin plugin; extern set docs; gcpTemplatesPlugin::gcpTemplatesPlugin(): gcpPlugin() { //Load templates, assuming that users templates are not readonly xmlDocPtr doc; xmlNodePtr node; const char *name; char *path; GDir* dir = g_dir_open (PKGDATADIR"/templates", 0, NULL); xmlIndentTreeOutput = true; xmlKeepBlanksDefault (0); if (dir) { while ((name = g_dir_read_name (dir))) { if (strcmp (name + strlen (name) - 4, ".xml")) continue; name = g_strconcat (PKGDATADIR"/templates/", name, NULL); doc = xmlParseFile (name); docs.insert (doc); node = doc->children; if (!strcmp ((char*)node->name, "templates")) ParseNodes (node->children, false); g_free ((void*) name); } g_dir_close (dir); } path = g_strconcat (getenv ("HOME"), "/.gchempaint/templates", NULL); dir = g_dir_open (path, 0, NULL); if (dir) { bool is_user_templates; while ((name = g_dir_read_name (dir))) { if (strcmp (name + strlen (name) - 4, ".xml")) continue; is_user_templates = !strcmp (name, "templates.xml"); name = g_strconcat (path, "/", name, NULL); doc = xmlParseFile (name); docs.insert (doc); if (is_user_templates) user_templates = doc; node = doc->children; if (!strcmp ((char*)node->name, "templates")) ParseNodes (node->children, true); g_free ((void*) name); } g_dir_close (dir); } else { char* gcppath = g_strconcat (getenv ("HOME"), "/.gchempaint", NULL); dir = g_dir_open (gcppath, 0, NULL); if (dir) g_dir_close (dir); else mkdir (gcppath, 0x1ed); g_free (gcppath) ; mkdir (path, 0x1ed); } g_free (path); } gcpTemplatesPlugin::~gcpTemplatesPlugin() { set::iterator i, iend = docs.end (); for (i = docs.begin (); i != iend; i++) xmlFreeDoc (*i); docs.clear (); map::iterator j, jend = Templates.end (); for (j = Templates.begin (); j != jend; j++) delete (*j).second; Templates.clear (); TempbyName.clear (); } static GtkRadioActionEntry entries[] = { { "Templates", GTK_STOCK_INDEX, N_("Templates"), NULL, N_("Use or manage templates"), 0 }, }; static const char *ui_description = "" " " " " " " " " " " " " " " " " ""; void gcpTemplatesPlugin::Populate (gcpApplication* App) { App->AddActions (entries, G_N_ELEMENTS (entries), ui_description, NULL); new gcpTemplateTool (App); new gcpTemplateTree (App); } void gcpTemplatesPlugin::ParseNodes (xmlNodePtr node, bool writeable) { xmlNodePtr next, child, next_child; gcpTemplate* t; gcpTemplateCategory *c; bool lang_matched, cat_matched; xmlChar *category, *name; string key; char *lang = getenv("LANG"), *node_lang; while (node) { next = node->next; if (!strcmp ((char*)node->name, "template")) { category = name = NULL; lang_matched = cat_matched = false; t = new gcpTemplate(); child = node->children; while (child) { if (!strcmp ((char*)child->name, "text")) { child = child->next; continue; } next_child = child->next; if (!strcmp ((char*)child->name, "name")) { node_lang = (char*) xmlNodeGetLang(child); if (node_lang) { if (lang) { if (!strcmp (lang, node_lang) || (!lang_matched && !strncmp(lang, node_lang, 2)) ){ if (name) xmlFree (name); name = xmlNodeGetContent(child); lang_matched = true; } } xmlFree (node_lang); } else if (!node_lang && !lang_matched) { if (name) xmlFree (name); name = xmlNodeGetContent(child); } } else if (!strcmp ((char*)child->name, "category")) { node_lang = (char*) xmlNodeGetLang(child); if (node_lang) { if (lang) { if (!strcmp (lang, node_lang) || (!cat_matched && !strncmp(lang, node_lang, 2))) { if (category) xmlFree (category); category = xmlNodeGetContent(child); cat_matched = true; } } xmlFree (node_lang); } else if (!node_lang && !cat_matched) { if (category) xmlFree (category); category = xmlNodeGetContent (child); } } else if (t->node == NULL) { t->node = child; } else { delete t; t = NULL; break; } child = next_child; } if (t) { if (t->node) { t->name = (char*) name; t->category = (char*) category; t->writeable = writeable; key = string((char*) category) + "/" + (char*) name; if (Templates[key]) { int i = 0; char* str = g_strdup_printf ("%d", i); while (Templates[key + str]) { g_free (str); str = g_strdup_printf ("%d", ++i); } key += str; g_free (str); } Templates[key] = t; key = t->name; if (TempbyName[key]) { int i = 0; char* str = g_strdup_printf ("%d", i); while (TempbyName[key + str]) { g_free (str); str = g_strdup_printf ("%d", ++i); } key += str; g_free (str); } TempbyName[key] = t; } else delete t; } if (name) xmlFree (name); if (category) { c = TemplateCategories[(char*) category]; if (c == NULL) c = new gcpTemplateCategory ((char*) category); xmlFree (category); } else { c = TemplateCategories[_("Miscellaneous")]; if (c == NULL) c = new gcpTemplateCategory (_("Miscellaneous")); } c->AddTemplate (t); } node = next; } }