summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Mueller <github@johannes-mueller.org>2017-07-03 12:27:25 +0200
committerRobin Gareus <robin@gareus.org>2017-07-12 16:15:03 +0200
commit610d9fd3b9e4a60a63c9a7523a992de31dfa80b8 (patch)
tree4dd0248a61c4d13c4e21522a062cfbd0ae4e066d
parenteb79ae7d415294789fa9056511ae27215449bfe3 (diff)
First draft of a template management dialog
Goal is to a simple dialog that can rename and remove templates. This is helpful in order to keep the template list tidy. So far it works for session templates. Track templates tbd.
-rw-r--r--gtk2_ardour/ardour-sae.menus29
-rw-r--r--gtk2_ardour/ardour.menus.in1
-rw-r--r--gtk2_ardour/ardour_ui.cc7
-rw-r--r--gtk2_ardour/ardour_ui.h1
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc3
-rw-r--r--gtk2_ardour/template_dialog.cc234
-rw-r--r--gtk2_ardour/template_dialog.h71
-rw-r--r--gtk2_ardour/wscript5
8 files changed, 335 insertions, 16 deletions
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 @@
<menuitem action='Save'/>
<menuitem action='Snapshot'/>
<menuitem action='SaveTemplate'/>
+ <menuitem action='ManageTemplates'/>
<separator/>
<menu name='Files' action='Files'>
@@ -56,11 +57,11 @@
<menuitem action='TransitionToRoll'/>
<menuitem action='TransitionToReverse'/>
<separator/>
-
+
<menuitem action='set-playhead'/>
<menu action="MovePlayHeadMenu">
-
+
<menuitem action='playhead-to-edit'/>
<menuitem action='center-playhead'/>
<separator/>
@@ -122,7 +123,7 @@
<menuitem action='editor-cut'/>
<menuitem action='editor-copy'/>
<menuitem action='editor-paste'/>
- <separator/>
+ <separator/>
<menuitem action='editor-delete'/>
<menuitem action='split-region'/>
<menu action="SeparateMenu">
@@ -132,7 +133,7 @@
<separator/>
<menuitem action='split-region-at-transients'/>
</menu>
- <separator/>
+ <separator/>
<menuitem action='duplicate-region'/>
<menuitem action='multi-duplicate-region'/>
<menuitem action='region-fill-track'/>
@@ -165,7 +166,7 @@
<menuitem action='toggle-selected-region-fades'/>
<menuitem action='toggle-region-fades'/>
</menu>
- <menu action="SelectMenu">
+ <menu action="SelectMenu">
<menuitem action='select-all'/>
<menuitem action='deselect-all'/>
<menuitem action='invert-selection'/>
@@ -178,12 +179,12 @@
<separator/>
<menuitem action='select-next-route'/>
<menuitem action='select-prev-route'/>
- </menu>
+ </menu>
</menu>
<menu action='TrackMenu'>
<menuitem action='remove-track'/>
- <menuitem action='AddTrackBus'/>
+ <menuitem action='AddTrackBus'/>
<menuitem action="move-selected-tracks-up"/>
<menuitem action="move-selected-tracks-down"/>
<menu action='TrackHeightMenu'>
@@ -198,7 +199,7 @@
<menuitem action='linear-waveforms'/>
<menuitem action='logarithmic-waveforms'/>
</menu>
- <menuitem action='toggle-track-active'/>
+ <menuitem action='toggle-track-active'/>
</menu>
<menu action='RegionMenu'>
@@ -212,17 +213,17 @@
<menuitem action='set-region-sync-position'/>
<menuitem action='remove-region-sync'/>
<menuitem action='toggle-region-mute'/>
- <separator/>
- <menuitem action='reverse-region'/>
+ <separator/>
+ <menuitem action='reverse-region'/>
<menuitem action='split-multichannel-region'/>
<menuitem action='normalize-region'/>
<menuitem action='boost-region-gain'/>
- <menuitem action='cut-region-gain'/>
+ <menuitem action='cut-region-gain'/>
<menuitem action='pitch-shift-region'/>
<separator/>
<menuitem action='toggle-selected-region-fades'/>
<menuitem action='toggle-region-fades'/>
- </menu>
+ </menu>
<menu name='View' action = 'View'>
<menuitem action='ToggleMaximalEditor'/>
@@ -271,7 +272,7 @@
</menu>
<menu action="WindowMenu">
-
+
<menuitem action='toggle-editor-mixer-on-top'/>
<menuitem action='ToggleLocations'/>
<menuitem action='ToggleKeyEditor'/>
@@ -401,6 +402,6 @@
<menuitem action='SortBySourceFilesystem'/>
</menu>
<separator/>
- <menuitem action='addExternalAudioToRegionList'/>
+ <menuitem action='addExternalAudioToRegionList'/>
</popup>
</ui>
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 @@
<menuitem action='SnapshotSwitch'/>
#endif
<menuitem action='SaveTemplate'/>
+ <menuitem action='ManageTemplates'/>
<menuitem action='Archive'/>
<menu name='Metadata' action='Metadata'>
<menuitem action='EditMetadata'/>
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 <glib/gstdio.h>
+
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/treeiter.h>
+
+#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<TemplateInfo> templates;
+ find_session_templates (templates);
+
+ _session_template_model->clear ();
+
+ for (vector<TemplateInfo>::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 <vector>
+
+#include <gtkmm/liststore.h>
+#include <gtkmm/treeview.h>
+
+#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<std::string> name;
+ Gtk::TreeModelColumn<std::string> path;
+ };
+
+ SessionTemplateColumns _session_template_columns;
+ Glib::RefPtr<Gtk::ListStore> _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')