13
0

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.
This commit is contained in:
Johannes Mueller 2017-07-03 12:27:25 +02:00 committed by Robin Gareus
parent eb79ae7d41
commit 610d9fd3b9
8 changed files with 335 additions and 16 deletions

View File

@ -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>

View File

@ -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'/>

View File

@ -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 ()
{

View File

@ -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 ();

View File

@ -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);

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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')