diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus
index d03449ff4f..effd9abc09 100644
--- a/gtk2_ardour/ardour-sae.menus
+++ b/gtk2_ardour/ardour-sae.menus
@@ -10,6 +10,7 @@
+
-
+
@@ -198,7 +199,7 @@
-
+
@@ -212,17 +213,17 @@
-
-
+
+
-
+
-
+
@@ -271,7 +272,7 @@
-
+
@@ -401,6 +402,6 @@
-
+
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index 898d9fb8a9..e216c22d20 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -14,6 +14,7 @@
#endif
+
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 9c1777acdb..4a4b385957 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -177,6 +177,7 @@ typedef uint64_t microseconds_t;
#include "speaker_dialog.h"
#include "splash.h"
#include "startup.h"
+#include "template_dialog.h"
#include "time_axis_view_item.h"
#include "time_info_box.h"
#include "timers.h"
@@ -3172,6 +3173,12 @@ ARDOUR_UI::save_template ()
}
}
+void ARDOUR_UI::manage_templates ()
+{
+ TemplateDialog td;
+ td.run();
+}
+
void
ARDOUR_UI::edit_metadata ()
{
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index be47e0941b..b22c2f7ad9 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -656,6 +656,7 @@ private:
void open_recent_session ();
bool process_save_template_prompter (ArdourPrompter& prompter);
void save_template ();
+ void manage_templates ();
void edit_metadata ();
void import_metadata ();
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index e2e791f93c..ffe39844bf 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -222,6 +222,9 @@ ARDOUR_UI::install_actions ()
act = global_actions.register_action (main_actions, X_("SaveTemplate"), _("Save Template..."), sigc::mem_fun(*this, &ARDOUR_UI::save_template));
ActionManager::session_sensitive_actions.push_back (act);
+ act = global_actions.register_action (main_actions, X_("ManageTemplates"), _("Manage Templates..."), sigc::mem_fun(*this, &ARDOUR_UI::manage_templates));
+ ActionManager::session_sensitive_actions.push_back (act);
+
act = global_actions.register_action (main_actions, X_("Metadata"), _("Metadata"));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/template_dialog.cc b/gtk2_ardour/template_dialog.cc
new file mode 100644
index 0000000000..4a73f91137
--- /dev/null
+++ b/gtk2_ardour/template_dialog.cc
@@ -0,0 +1,234 @@
+/*
+ Copyright (C) 2010 Paul Davis
+ Author: Johannes Mueller
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include
+
+#include
+#include
+
+#include "pbd/error.h"
+#include "pbd/i18n.h"
+
+#include "ardour/template_utils.h"
+
+#include "template_dialog.h"
+
+using namespace std;
+using namespace Gtk;
+using namespace PBD;
+using namespace ARDOUR;
+
+TemplateDialog::TemplateDialog ()
+ : ArdourDialog (_("Manage Templates"))
+ , _remove_button (_("Remove"))
+ , _rename_button (_("Rename"))
+{
+ _session_template_model = ListStore::create (_session_template_columns);
+ setup_session_templates ();
+ _session_template_treeview.set_model (_session_template_model);
+
+ _validated_column.set_title (_("Template Name"));
+ _validated_column.pack_start (_validating_cellrenderer);
+ _session_template_treeview.append_column (_validated_column);
+ _validating_cellrenderer.property_editable() = true;
+
+ _validated_column.set_cell_data_func (_validating_cellrenderer, sigc::mem_fun (*this, &TemplateDialog::render_template_names));
+ _validating_cellrenderer.signal_edited().connect (sigc::mem_fun (*this, &TemplateDialog::validate_edit));
+ _session_template_treeview.signal_cursor_changed().connect (sigc::mem_fun (*this, &TemplateDialog::row_selection_changed));
+ _session_template_treeview.signal_key_press_event().connect (sigc::mem_fun (*this, &TemplateDialog::key_event));
+
+ ScrolledWindow* sw = manage (new ScrolledWindow);
+ sw->add (_session_template_treeview);
+ sw->set_size_request (300, 200);
+
+
+ VBox* vb = manage (new VBox);
+ vb->pack_start (_rename_button, false, false);
+ vb->pack_start (_remove_button, false, false);
+
+ _rename_button.set_sensitive (false);
+ _rename_button.signal_clicked().connect (sigc::mem_fun (*this, &TemplateDialog::start_edit));
+ _remove_button.set_sensitive (false);
+ _remove_button.signal_clicked().connect (sigc::mem_fun (*this, &TemplateDialog::delete_selected_template));
+
+ HBox* hb = manage (new HBox);
+ hb->pack_start (*sw);
+ hb->pack_start (*vb);
+
+ get_vbox()->pack_start (*hb);
+
+ show_all_children ();
+
+ add_button (_("Ok"), Gtk::RESPONSE_OK);
+}
+
+void
+TemplateDialog::setup_session_templates ()
+{
+ vector templates;
+ find_session_templates (templates);
+
+ _session_template_model->clear ();
+
+ for (vector::iterator it = templates.begin(); it != templates.end(); ++it) {
+ TreeModel::Row row;
+ row = *(_session_template_model->append ());
+
+ row[_session_template_columns.name] = it->name;
+ row[_session_template_columns.path] = it->path;
+ }
+}
+
+void
+TemplateDialog::row_selection_changed ()
+{
+ bool has_selection = false;
+ if (_session_template_treeview.get_selection()->count_selected_rows () != 0) {
+ Gtk::TreeModel::const_iterator it = _session_template_treeview.get_selection()->get_selected ();
+ if (it) {
+ has_selection = true;
+ }
+ }
+
+ _rename_button.set_sensitive (has_selection);
+ _remove_button.set_sensitive (has_selection);
+}
+
+void
+TemplateDialog::render_template_names (Gtk::CellRenderer*, const Gtk::TreeModel::iterator& it)
+{
+ if (it) {
+ _validating_cellrenderer.property_text () = it->get_value (_session_template_columns.name);
+ }
+}
+
+void
+TemplateDialog::validate_edit (const Glib::ustring& path_string, const Glib::ustring& new_name)
+{
+ const TreePath path (path_string);
+ TreeModel::iterator current = _session_template_model->get_iter (path);
+
+ if (current->get_value (_session_template_columns.name) == new_name) {
+ return;
+ }
+
+ TreeModel::Children rows = _session_template_model->children ();
+
+ bool found = false;
+ for (TreeModel::Children::const_iterator it = rows.begin(); it != rows.end(); ++it) {
+ if (it->get_value (_session_template_columns.name) == new_name) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ error << string_compose (_("Template of name \"%1\" already exists"), new_name) << endmsg;
+ return;
+ }
+
+
+ rename_template (current, new_name);
+}
+
+void
+TemplateDialog::start_edit ()
+{
+ TreeModel::Path path;
+ TreeViewColumn* col;
+ _session_template_treeview.get_cursor (path, col);
+ _session_template_treeview.set_cursor (path, *col, /*set_editing =*/ true);
+}
+
+void
+TemplateDialog::delete_selected_template ()
+{
+ if (_session_template_treeview.get_selection()->count_selected_rows() == 0) {
+ return;
+ }
+
+ Gtk::TreeModel::const_iterator it = _session_template_treeview.get_selection()->get_selected();
+
+ if (!it) {
+ return;
+ }
+
+ const string path = it->get_value (_session_template_columns.path);
+ const string name = it->get_value (_session_template_columns.name);
+ const string file_path = Glib::build_filename (path, name+".template");
+
+ if (g_unlink (file_path.c_str()) != 0) {
+ error << string_compose(_("Could not delete template file \"%1\": %2"), file_path, strerror (errno)) << endmsg;
+ return;
+ }
+
+ if (g_rmdir (path.c_str()) != 0) {
+ error << string_compose(_("Could not delete template directory \"%1\": %2"), path, strerror (errno)) << endmsg;
+ }
+
+ _session_template_model->erase (it);
+ row_selection_changed ();
+}
+
+bool
+TemplateDialog::key_event (GdkEventKey* ev)
+{
+ if (ev->keyval == GDK_KEY_F2) {
+ start_edit ();
+ return true;
+ }
+ if (ev->keyval == GDK_KEY_Delete) {
+ delete_selected_template ();
+ return true;
+ }
+
+ return false;
+}
+
+void
+TemplateDialog::rename_template (TreeModel::iterator& item, const Glib::ustring& new_name)
+{
+ const string path = item->get_value (_session_template_columns.path);
+ const string name = item->get_value (_session_template_columns.name);
+
+ const string old_filepath = Glib::build_filename (path, name+".template");
+ const string new_filepath = Glib::build_filename (path, new_name+".template");
+ const string new_path = Glib::build_filename (user_template_directory(), new_name);
+
+ cout << old_filepath << " " << new_filepath << endl;
+ cout << path << " " << new_path << endl;
+
+ if (g_rename (old_filepath.c_str(), new_filepath.c_str()) != 0) {
+ error << string_compose (_("Renaming of the template file failed: %1"), strerror (errno)) << endmsg;
+ return;
+ }
+
+ if (g_rename (path.c_str(), new_path.c_str()) != 0) {
+ error << string_compose (_("Renaming of the template directory failed: %1"), strerror (errno)) << endmsg;
+ if (g_rename (new_filepath.c_str(), old_filepath.c_str()) != 0) {
+ error << string_compose (_("Couldn't even undo renaming of template file: %1. Please examine the situation using filemanager or terminal."),
+ strerror (errno)) << endmsg;
+ }
+ return;
+ }
+
+ item->set_value (_session_template_columns.name, string(new_name));
+ item->set_value (_session_template_columns.path, new_path);
+}
diff --git a/gtk2_ardour/template_dialog.h b/gtk2_ardour/template_dialog.h
new file mode 100644
index 0000000000..7523213a58
--- /dev/null
+++ b/gtk2_ardour/template_dialog.h
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2010 Paul Davis
+ Author: Johannes Mueller
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __gtk2_ardour_template_dialog_h__
+#define __gtk2_ardour_template_dialog_h__
+
+#include
+
+#include
+#include
+
+#include "ardour_dialog.h"
+
+class TemplateDialog : public ArdourDialog
+{
+public:
+ TemplateDialog ();
+ ~TemplateDialog () {}
+
+private:
+ void setup_session_templates ();
+
+ void row_selection_changed ();
+ void render_template_names (Gtk::CellRenderer* rnd, const Gtk::TreeModel::iterator& it);
+ void validate_edit (const Glib::ustring& path_string, const Glib::ustring& new_name);
+ void start_edit ();
+
+ bool key_event (GdkEventKey* ev);
+
+ void rename_template (Gtk::TreeModel::iterator& item, const Glib::ustring& new_name);
+ void delete_selected_template ();
+
+ struct SessionTemplateColumns : public Gtk::TreeModel::ColumnRecord {
+ SessionTemplateColumns () {
+ add (name);
+ add (path);
+ }
+
+ Gtk::TreeModelColumn name;
+ Gtk::TreeModelColumn path;
+ };
+
+ SessionTemplateColumns _session_template_columns;
+ Glib::RefPtr _session_template_model;
+
+ Gtk::TreeView _session_template_treeview;
+ Gtk::CellRendererText _validating_cellrenderer;
+ Gtk::TreeView::Column _validated_column;
+
+ Gtk::Button _remove_button;
+ Gtk::Button _rename_button;
+};
+
+#endif /* __gtk2_ardour_template_dialog_h__ */
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index a9d3205de1..92cb059379 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -250,6 +250,7 @@ gtk2_ardour_sources = [
'stripable_time_axis.cc',
'sys_ex.cc',
'tape_region_view.cc',
+ 'template_dialog.cc',
'tempo_curve.cc',
'tempo_dialog.cc',
'tempo_lines.cc',
@@ -859,7 +860,7 @@ def build(bld):
# NATIVE ARDOUR BINDING FILES
# explicitly state the use of perl here so that it works on windows too
- #
+ #
a_rule = 'perl ../tools/fmt-bindings --platform="%s" --winkey="%s" --accelmap ${SRC[0].abspath()} >${TGT}' % (sys.platform, bld.env['WINDOWS_KEY'] )
for b in [ 'ardour' ] :
obj = bld(
@@ -868,7 +869,7 @@ def build(bld):
rule = a_rule
)
obj.install_path = bld.env['CONFDIR']
-
+
# Icons/Images
bld.install_files(os.path.join (bld.env['DATADIR'], 'icons'), bld.path.ant_glob('icons/*.png'))
bld.install_files(bld.env['DATADIR'], 'ArdourMono.ttf')