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 @@ + @@ -56,11 +57,11 @@ - + - + @@ -122,7 +123,7 @@ - + @@ -132,7 +133,7 @@ - + @@ -165,7 +166,7 @@ - + @@ -178,12 +179,12 @@ - + - + @@ -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')