summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/file.cpp114
-rw-r--r--src/file.h7
-rw-r--r--src/menus-skeleton.h1
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/dialog/save-template-dialog.cpp91
-rw-r--r--src/ui/dialog/save-template-dialog.h51
-rw-r--r--src/verbs.cpp28
-rw-r--r--src/verbs.h3
8 files changed, 276 insertions, 21 deletions
diff --git a/src/file.cpp b/src/file.cpp
index b9d896de0..549ed7d6e 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -69,6 +69,7 @@
using Inkscape::DocumentUndo;
using Inkscape::IO::Resource::TEMPLATES;
+using Inkscape::IO::Resource::USER;
#ifdef WITH_GNOME_VFS
# include <libgnomevfs/gnome-vfs.h>
@@ -122,7 +123,7 @@ SPDesktop *sp_file_new(const std::string &templ)
{
SPDocument *doc = SPDocument::createNewDoc( !templ.empty() ? templ.c_str() : 0 , TRUE, true );
g_return_val_if_fail(doc != NULL, NULL);
-
+
// Remove all the template info from xml tree
Inkscape::XML::Node *myRoot = doc->getReprRoot();
Inkscape::XML::Node *nodeToRemove = sp_repr_lookup_name(myRoot, "inkscape:_templateinfo");
@@ -132,11 +133,11 @@ SPDesktop *sp_file_new(const std::string &templ)
delete nodeToRemove;
DocumentUndo::setUndoSensitive(doc, true);
}
-
+
SPDesktop *olddesktop = SP_ACTIVE_DESKTOP;
if (olddesktop)
olddesktop->setWaitingCursor();
-
+
SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc.
g_return_val_if_fail(dtw != NULL, NULL);
sp_create_window(dtw, TRUE);
@@ -145,12 +146,12 @@ SPDesktop *sp_file_new(const std::string &templ)
doc->doUnref();
sp_namedview_window_from_document(desktop);
- sp_namedview_update_layers_from_document(desktop);
+ sp_namedview_update_layers_from_document(desktop);
#ifdef WITH_DBUS
Inkscape::Extension::Dbus::dbus_init_desktop_interface(desktop);
#endif
-
+
if (olddesktop)
olddesktop->clearWaitingCursor();
if (desktop)
@@ -1006,6 +1007,101 @@ sp_file_save_a_copy(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
return sp_file_save_dialog(parentWindow, SP_ACTIVE_DOCUMENT, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY);
}
+/**
+ * Save a copy of a document as template.
+ */
+void
+sp_file_save_template(Gtk::Window &parentWindow, Glib::ustring name,
+ Glib::ustring author, Glib::ustring description, Glib::ustring keywords,
+ bool isDefault)
+{
+
+ if (!SP_ACTIVE_DOCUMENT || name.length() == 0)
+ return;
+
+ auto document = SP_ACTIVE_DOCUMENT;
+
+ DocumentUndo::setUndoSensitive(document, false);
+
+ auto root = document->getReprRoot();
+ auto xml_doc = document->getReprDoc();
+
+ auto templateinfo_node = xml_doc->createElement("inkscape:_templateinfo");
+ Inkscape::GC::release(templateinfo_node);
+
+ auto element_node = xml_doc->createElement("inkscape:_name");
+ Inkscape::GC::release(element_node);
+
+ element_node->appendChild(xml_doc->createTextNode(name.c_str()));
+ templateinfo_node->appendChild(element_node);
+
+ if (author.length() != 0) {
+
+ element_node = xml_doc->createElement("inkscape:author");
+ Inkscape::GC::release(element_node);
+
+ element_node->appendChild(xml_doc->createTextNode(author.c_str()));
+ templateinfo_node->appendChild(element_node);
+ }
+
+ if (description.length() != 0) {
+
+ element_node = xml_doc->createElement("inkscape:_shortdesc");
+ Inkscape::GC::release(element_node);
+
+ element_node->appendChild(xml_doc->createTextNode(description.c_str()));
+ templateinfo_node->appendChild(element_node);
+
+ }
+
+ element_node = xml_doc->createElement("inkscape:date");
+ Inkscape::GC::release(element_node);
+
+ element_node->appendChild(xml_doc->createTextNode(
+ Glib::DateTime::create_now_local().format("%F").c_str()));
+ templateinfo_node->appendChild(element_node);
+
+ if (keywords.length() != 0) {
+
+ element_node = xml_doc->createElement("inkscape:_keywords");
+ Inkscape::GC::release(element_node);
+
+ element_node->appendChild(xml_doc->createTextNode(keywords.c_str()));
+ templateinfo_node->appendChild(element_node);
+
+ }
+
+ root->appendChild(templateinfo_node);
+
+ if (isDefault) {
+
+ auto filename = Inkscape::IO::Resource::get_path_ustring(USER,
+ TEMPLATES, "default.svg");
+ file_save(parentWindow, document, filename,
+ Inkscape::Extension::db.get(".svg"), false, false,
+ Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
+ }
+
+ name.append(".svg");
+
+ auto filename = Inkscape::IO::Resource::get_path_ustring(USER, TEMPLATES,
+ name.c_str());
+ file_save(parentWindow, document, filename,
+ Inkscape::Extension::db.get(".svg"), false, false,
+ Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
+
+ auto nodeToRemove = sp_repr_lookup_name(root, "inkscape:_templateinfo");
+
+ if (nodeToRemove != NULL){
+
+ sp_repr_unparent(nodeToRemove);
+ delete nodeToRemove;
+ }
+
+ DocumentUndo::setUndoSensitive(document, true);
+}
+
+
/*######################
## I M P O R T
@@ -1069,7 +1165,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place)
SPLPEItem * pasted_lpe_item = dynamic_cast<SPLPEItem *>(pasted);
if (pasted_lpe_item){
pasted_lpe_item->forkPathEffectsIfNecessary(1);
- }
+ }
pasted_objects_not.push_back(obj_copy);
}
Inkscape::Selection *selection = desktop->getSelection();
@@ -1127,7 +1223,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
bool cancelled = false;
-
+
//DEBUG_MESSAGE( fileImport, "file_import( in_doc:%p uri:[%s], key:%p", in_doc, uri, key );
SPDocument *doc;
try {
@@ -1660,7 +1756,7 @@ Inkscape::UI::Dialog::OCAL::ImportDialog* import_ocal_dialog = NULL;
void on_import_from_ocal_response(Glib::ustring filename)
{
SPDocument *doc = SP_ACTIVE_DOCUMENT;
-
+
if (!filename.empty()) {
Inkscape::Extension::Extension *selection = import_ocal_dialog->get_selection_type();
file_import(doc, filename, selection);
@@ -1686,7 +1782,7 @@ sp_file_import_from_ocal(Gtk::Window &parent_window)
import_ocal_dialog->signal_response().connect(
sigc::ptr_fun(&on_import_from_ocal_response));
}
-
+
import_ocal_dialog->show_all();
}
diff --git a/src/file.h b/src/file.h
index c6ff61c25..9cd22d744 100644
--- a/src/file.h
+++ b/src/file.h
@@ -110,6 +110,13 @@ bool sp_file_save_as (Gtk::Window &parentWindow, void* object, void* data);
*/
bool sp_file_save_a_copy (Gtk::Window &parentWindow, void* object, void* data);
+/**
+ * Save a copy of a document as template.
+ */
+void
+sp_file_save_template(Gtk::Window &parentWindow, Glib::ustring name,
+ Glib::ustring author, Glib::ustring description, Glib::ustring keywords,
+ bool isDefault);
/**
* Saves the given document. Displays a file select dialog
diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h
index 65c497da4..e5991aa1d 100644
--- a/src/menus-skeleton.h
+++ b/src/menus-skeleton.h
@@ -24,6 +24,7 @@ static char const menus_skeleton[] =
" <verb verb-id=\"FileSave\" />\n"
" <verb verb-id=\"FileSaveAs\" />\n"
" <verb verb-id=\"FileSaveACopy\" />\n"
+" <verb verb-id=\"FileSaveTemplate\" />\n"
" <separator/>\n"
" <verb verb-id=\"FileImport\" />\n"
" <verb verb-id=\"DialogExport\" />\n"
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index b6b88e50b..789378e0c 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -115,6 +115,7 @@ set(ui_SRC
dialog/transformation.cpp
dialog/undo-history.cpp
dialog/xml-tree.cpp
+ dialog/save-template-dialog.cpp
widget/addtoicon.cpp
widget/anchor-selector.cpp
@@ -262,6 +263,7 @@ set(ui_SRC
dialog/transformation.h
dialog/undo-history.h
dialog/xml-tree.h
+ dialog/save-template-dialog.h
tool/commit-events.h
tool/control-point-selection.h
diff --git a/src/ui/dialog/save-template-dialog.cpp b/src/ui/dialog/save-template-dialog.cpp
new file mode 100644
index 000000000..5b7540039
--- /dev/null
+++ b/src/ui/dialog/save-template-dialog.cpp
@@ -0,0 +1,91 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "save-template-dialog.h"
+#include "file.h"
+
+#include <glibmm/i18n.h>
+
+#include <iostream>
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+SaveTemplate::SaveTemplate() :
+ Gtk::Dialog(_("Save Document as Template")),
+ name_label(_("Name: "), Gtk::ALIGN_START),
+ author_label(_("Author: "), Gtk::ALIGN_START),
+ description_label(_("Description: "), Gtk::ALIGN_START),
+ keywords_label(_("Keywords: "), Gtk::ALIGN_START),
+ is_default_template("Set as default template")
+{
+ resize(400, 200);
+
+ name_text.set_hexpand(true);
+
+ grid.attach(name_label, 0, 0, 1, 1);
+ grid.attach(name_text, 1, 0, 1, 1);
+
+ grid.attach(author_label, 0, 1, 1, 1);
+ grid.attach(author_text, 1, 1, 1, 1);
+
+ grid.attach(description_label, 0, 2, 1, 1);
+ grid.attach(description_text, 1, 2, 1, 1);
+
+ grid.attach(keywords_label, 0, 3, 1, 1);
+ grid.attach(keywords_text, 1, 3, 1, 1);
+
+ auto content_area = get_content_area();
+
+ content_area->set_spacing(5);
+
+ content_area->add(grid);
+ content_area->add(is_default_template);
+
+ name_text.signal_changed().connect( sigc::mem_fun(*this,
+ &SaveTemplate::on_name_changed) );
+
+ add_button("Cancel", Gtk::RESPONSE_CANCEL);
+ add_button("Save", Gtk::RESPONSE_OK);
+
+ set_response_sensitive(Gtk::RESPONSE_OK, false);
+ set_default_response(Gtk::RESPONSE_CANCEL);
+
+ show_all();
+}
+
+void SaveTemplate::on_name_changed() {
+
+ if (name_text.get_text_length() == 0) {
+
+ set_response_sensitive(Gtk::RESPONSE_OK, false);
+ } else {
+
+ set_response_sensitive(Gtk::RESPONSE_OK, true);
+ }
+}
+
+void SaveTemplate::save_template(Gtk::Window &parentWindow) {
+
+ sp_file_save_template(parentWindow, name_text.get_text(),
+ author_text.get_text(), description_text.get_text(),
+ keywords_text.get_text(), is_default_template.get_active());
+}
+
+void SaveTemplate::save_document_as_template(Gtk::Window &parentWindow) {
+
+ SaveTemplate dialog;
+
+ auto result = dialog.run();
+
+ if (result == Gtk::RESPONSE_OK){
+
+ dialog.save_template(parentWindow);
+ }
+}
+
+}
+}
+}
diff --git a/src/ui/dialog/save-template-dialog.h b/src/ui/dialog/save-template-dialog.h
new file mode 100644
index 000000000..9f38c499d
--- /dev/null
+++ b/src/ui/dialog/save-template-dialog.h
@@ -0,0 +1,51 @@
+#ifndef INKSCAPE_SEEN_UI_DIALOG_SAVE_TEMPLATE_H
+#define INKSCAPE_SEEN_UI_DIALOG_SAVE_TEMPLATE_H
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/box.h>
+#include <gtkmm/grid.h>
+#include <gtkmm/label.h>
+#include <gtkmm/checkbutton.h>
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+class SaveTemplate : public Gtk::Dialog
+{
+
+public:
+
+ static void save_document_as_template(Gtk::Window &parentWindow);
+
+protected:
+
+ void on_name_changed();
+
+private:
+
+ Gtk::Grid grid;
+
+ Gtk::Label name_label;
+ Gtk::Entry name_text;
+
+ Gtk::Label author_label;
+ Gtk::Entry author_text;
+
+ Gtk::Label description_label;
+ Gtk::Entry description_text;
+
+ Gtk::Label keywords_label;
+ Gtk::Entry keywords_text;
+
+ Gtk::CheckButton is_default_template;
+
+ SaveTemplate();
+ void save_template(Gtk::Window &parentWindow);
+
+};
+}
+}
+}
+#endif
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 22ded60b3..4827ba631 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -84,6 +84,7 @@
#include "ui/dialog/spellcheck.h"
#include "ui/icon-names.h"
#include "ui/tools/node-tool.h"
+#include "ui/dialog/save-template-dialog.h"
using Inkscape::DocumentUndo;
using Inkscape::UI::Dialog::ActionAlign;
@@ -587,7 +588,7 @@ SPAction *Verb::make_action_helper(Inkscape::ActionContext const & context, void
_(_tip), _image, this);
if (action == NULL) return NULL;
-
+
action->signal_perform.connect(
sigc::bind(
sigc::bind(
@@ -849,7 +850,7 @@ void FileVerb::perform(SPAction *action, void *data)
// Convert verb impls to use this where possible, to reduce static cling
// to macros like SP_ACTIVE_DOCUMENT, which end up enforcing GUI-mode operation
SPDocument *doc = sp_action_get_document(action);
-
+
// We can vacuum defs, or exit, without needing a desktop!
bool handled = true;
switch (reinterpret_cast<std::size_t>(data)) {
@@ -866,7 +867,7 @@ void FileVerb::perform(SPAction *action, void *data)
if (handled) {
return;
}
-
+
g_return_if_fail(ensure_desktop_valid(action));
SPDesktop *desktop = sp_action_get_desktop(action);
@@ -892,6 +893,9 @@ void FileVerb::perform(SPAction *action, void *data)
case SP_VERB_FILE_SAVE_A_COPY:
sp_file_save_a_copy(*parent, NULL, NULL);
break;
+ case SP_VERB_FILE_SAVE_TEMPLATE:
+ Inkscape::UI::Dialog::SaveTemplate::save_document_as_template(*parent);
+ break;
case SP_VERB_FILE_PRINT:
sp_file_print(*parent);
break;
@@ -944,7 +948,7 @@ void EditVerb::perform(SPAction *action, void *data)
if (handled) {
return;
}
-
+
g_return_if_fail(ensure_desktop_valid(action));
SPDesktop *dt = sp_action_get_desktop(action);
@@ -1297,7 +1301,7 @@ void LayerVerb::perform(SPAction *action, void *data)
g_return_if_fail(ensure_desktop_valid(action));
SPDesktop *dt = sp_action_get_desktop(action);
size_t verb = reinterpret_cast<std::size_t>(data);
-
+
if ( !dt->currentLayer() ) {
return;
}
@@ -1633,12 +1637,12 @@ void TagVerb::perform( SPAction *action, void *data)
g_free(id);
id = g_strdup_printf(_("Set %d"), tag_suffix++);
} while (dt->doc()->getObjectById(id));
-
+
doc = dt->doc()->getReprDoc();
repr = doc->createElement("inkscape:tag");
repr->setAttribute("id", id);
g_free(id);
-
+
dt->doc()->getDefs()->addChild(repr, NULL);
Inkscape::DocumentUndo::done(dt->doc(), SP_VERB_DIALOG_TAGS, _("Create new selection set"));
break;
@@ -1657,7 +1661,7 @@ void ContextVerb::perform(SPAction *action, void *data)
SPDesktop *dt;
sp_verb_t verb;
int vidx;
-
+
g_return_if_fail(ensure_desktop_valid(action));
dt = sp_action_get_desktop(action);
@@ -2134,7 +2138,7 @@ void DialogVerb::perform(SPAction *action, void *data)
// unhide all when opening a new dialog
INKSCAPE.dialogs_unhide();
}
-
+
g_return_if_fail(ensure_desktop_valid(action));
SPDesktop *dt = sp_action_get_desktop(action);
g_assert(dt->_dlg_mgr != NULL);
@@ -2564,6 +2568,8 @@ Verb *Verb::_base_verbs[] = {
N_("Save document under a new name"), INKSCAPE_ICON("document-save-as")),
new FileVerb(SP_VERB_FILE_SAVE_A_COPY, "FileSaveACopy", N_("Save a Cop_y..."),
N_("Save a copy of the document under a new name"), NULL ),
+ new FileVerb(SP_VERB_FILE_SAVE_TEMPLATE, "FileSaveTemplate", N_("Save template ..."),
+ N_("Save a copy of the document as template"), NULL ),
new FileVerb(SP_VERB_FILE_PRINT, "FilePrint", N_("_Print..."), N_("Print document"),
INKSCAPE_ICON("document-print")),
// TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions)
@@ -2572,7 +2578,7 @@ Verb *Verb::_base_verbs[] = {
new FileVerb(SP_VERB_FILE_IMPORT, "FileImport", N_("_Import..."),
N_("Import a bitmap or SVG image into this document"), INKSCAPE_ICON("document-import")),
// new FileVerb(SP_VERB_FILE_EXPORT, "FileExport", N_("_Export Bitmap..."), N_("Export this document or a selection as a bitmap image"), INKSCAPE_ICON("document-export")),
- new FileVerb(SP_VERB_FILE_IMPORT_FROM_OCAL, "FileImportFromOCAL", N_("Import Clip Art..."),
+ new FileVerb(SP_VERB_FILE_IMPORT_FROM_OCAL, "FileImportFromOCAL", N_("Import Clip Art..."),
N_("Import clipart from Open Clip Art Library"), INKSCAPE_ICON("document-import-ocal")),
// new FileVerb(SP_VERB_FILE_EXPORT_TO_OCAL, "FileExportToOCAL", N_("Export To Open Clip Art Library"), N_("Export this document to Open Clip Art Library"), INKSCAPE_ICON_DOCUMENT_EXPORT_OCAL),
new FileVerb(SP_VERB_FILE_NEXT_DESKTOP, "NextWindow", N_("N_ext Window"),
@@ -3199,7 +3205,7 @@ Verb *Verb::_base_verbs[] = {
N_("Remove a linked ICC color profile"), NULL),
// Scripting
new ContextVerb(SP_VERB_EDIT_ADD_EXTERNAL_SCRIPT, "AddExternalScript",
- N_("Add External Script"), N_("Add an external script"), NULL),
+ N_("Add External Script"), N_("Add an external script"), NULL),
new ContextVerb(SP_VERB_EDIT_ADD_EMBEDDED_SCRIPT, "AddEmbeddedScript",
N_("Add Embedded Script"), N_("Add an embedded script"), NULL),
new ContextVerb(SP_VERB_EDIT_EMBEDDED_SCRIPT, "EditEmbeddedScript",
diff --git a/src/verbs.h b/src/verbs.h
index a383bc365..7df2d1399 100644
--- a/src/verbs.h
+++ b/src/verbs.h
@@ -51,6 +51,7 @@ enum {
SP_VERB_FILE_SAVE, /**< Save the current file with its saved filename */
SP_VERB_FILE_SAVE_AS, /**< Save the current file with a new filename */
SP_VERB_FILE_SAVE_A_COPY, /**< Save a copy of the current file */
+ SP_VERB_FILE_SAVE_TEMPLATE, /**< Save the ciurrent document as template */
SP_VERB_FILE_PRINT,
SP_VERB_FILE_VACUUM,
SP_VERB_FILE_IMPORT,
@@ -604,7 +605,7 @@ public:
}
}
static Verb * getbyid (gchar const * id, bool verbose = true);
-
+
/**
* Print a message to stderr indicating that this verb needs a GUI to run
*/