summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct8
-rw-r--r--gtk2_ardour/SConscript1
-rw-r--r--gtk2_ardour/actions.cc34
-rw-r--r--gtk2_ardour/actions.h4
-rw-r--r--gtk2_ardour/ardour.menus1
-rw-r--r--gtk2_ardour/ardour_ui.cc1
-rw-r--r--gtk2_ardour/ardour_ui.h6
-rw-r--r--gtk2_ardour/ardour_ui_dialogs.cc22
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc3
-rw-r--r--gtk2_ardour/editor_mouse.cc3
-rw-r--r--gtk2_ardour/editor_ops.cc2
-rw-r--r--gtk2_ardour/keyboard.h1
-rw-r--r--gtk2_ardour/keyeditor.cc159
-rw-r--r--gtk2_ardour/keyeditor.h44
-rw-r--r--libs/ardour/audio_diskstream.cc6
-rw-r--r--libs/pbd/strsplit.cc4
16 files changed, 274 insertions, 25 deletions
diff --git a/SConstruct b/SConstruct
index 159c064ac2..c84d0aa754 100644
--- a/SConstruct
+++ b/SConstruct
@@ -715,8 +715,8 @@ def prep_libcheck(topenv, libinfo):
# rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
# All libraries needed should be built against this location
if topenv['GTKOSX']:
- libinfo.Append(CCFLAGS="-I/opt/gtk/include", LINKFLAGS="-L/opt/gtk/lib")
- libinfo.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
+ libinfo.Append(CPPPATH="/opt/gtk/include", LIBPATH="/opt/gtk/lib")
+ libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
prep_libcheck(env, env)
@@ -745,7 +745,7 @@ libraries['usb'] = conf.Finish ()
libraries['flac'] = LibraryInfo ()
prep_libcheck(env, libraries['flac'])
-libraries['flac'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib")
+libraries['flac'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
#
# june 1st 2007: look for a function that is in FLAC 1.1.2 and not in later versions
@@ -769,7 +769,7 @@ libraries['flac'] = conf.Finish ()
libraries['boost'] = LibraryInfo ()
prep_libcheck(env, libraries['boost'])
-libraries['boost'].Append(CCFLAGS="-I/usr/local/include", LINKFLAGS="-L/usr/local/lib")
+libraries['boost'].Append(CPPPATH="/usr/local/include", LIBPATH="/usr/local/lib")
conf = Configure (libraries['boost'])
if conf.CheckHeader ('boost/shared_ptr.hpp', language='CXX') == False:
print "Boost header files do not appear to be installed."
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index 82fc200ba4..b1c6a6b75c 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -168,6 +168,7 @@ imageframe_time_axis_view.cc
imageframe_view.cc
io_selector.cc
keyboard.cc
+keyeditor.cc
ladspa_pluginui.cc
location_ui.cc
main.cc
diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc
index c70a07d64d..1a072c1321 100644
--- a/gtk2_ardour/actions.cc
+++ b/gtk2_ardour/actions.cc
@@ -148,19 +148,28 @@ ActionManager::lookup_entry (const ustring accel_path, Gtk::AccelKey& key)
void
ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, vector<string>& keys, vector<AccelKey>& bindings)
{
- ListHandle<RefPtr<ActionGroup> > uim_groups = ui_manager->get_action_groups ();
-
- for (ListHandle<RefPtr<ActionGroup> >::iterator g = uim_groups.begin(); g != uim_groups.end(); ++g) {
-
- ListHandle<RefPtr<Action> > group_actions = (*g)->get_actions();
-
- for (ListHandle<RefPtr<Action> >::iterator a = group_actions.begin(); a != group_actions.end(); ++a) {
-
- ustring accel_path;
-
- accel_path = (*a)->get_accel_path();
+ /* the C++ API for functions used here appears to be broken in
+ gtkmm2.6, so we fall back to the C level.
+ */
+
+ GList* list = gtk_ui_manager_get_action_groups (ui_manager->gobj());
+ GList* node;
+ GList* acts;
+
+ for (node = list; node; node = g_list_next (node)) {
+
+ GtkActionGroup* group = (GtkActionGroup*) node->data;
+
+ for (acts = gtk_action_group_list_actions (group); acts; acts = g_list_next (acts)) {
+
+ GtkAction* action = (GtkAction*) acts->data;
+
+ Glib::RefPtr<Action> act = Glib::wrap (action, true);
+
+ string accel_path = act->get_accel_path ();
+ ustring label = act->property_label();
- names.push_back ((*a)->get_name());
+ names.push_back (label);
paths.push_back (accel_path);
AccelKey key;
@@ -177,6 +186,7 @@ ActionManager::get_all_actions (vector<string>& names, vector<string>& paths, ve
}
}
+
void
ActionManager::add_action_group (RefPtr<ActionGroup> grp)
{
diff --git a/gtk2_ardour/actions.h b/gtk2_ardour/actions.h
index 5816325265..be994a3396 100644
--- a/gtk2_ardour/actions.h
+++ b/gtk2_ardour/actions.h
@@ -27,6 +27,8 @@
#include <gtkmm/actiongroup.h>
#include <gtkmm/accelkey.h>
+#include <ardour/configuration.h>
+
namespace Gtk {
class UIManager;
}
@@ -92,7 +94,7 @@ class ActionManager
static bool lookup_entry (const Glib::ustring accel_path, Gtk::AccelKey& key);
- static void get_all_actions (std::vector<std::string>& names,
+ static void get_all_actions (std::vector<std::string>& labels,
std::vector<std::string>& paths,
std::vector<std::string>& keys,
std::vector<Gtk::AccelKey>& bindings);
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index 128ca81c27..4c8c3d6df9 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -233,6 +233,7 @@
<menuitem action='ToggleOptionsEditor'/>
<menuitem action='ToggleInspector'/>
<menuitem action='ToggleLocations'/>
+ <menuitem action='ToggleKeyEditor'/>
<menuitem action='ToggleThemeManager'/>
<menuitem action='ToggleBigClock'/>
<separator/>
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index bc1369d9ee..2eed08ab6f 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -187,6 +187,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
route_params = 0;
option_editor = 0;
location_ui = 0;
+ key_editor = 0;
open_session_selector = 0;
have_configure_timeout = false;
have_disk_speed_dialog_displayed = false;
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 6f7ec37ee1..a60c7876ce 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -68,6 +68,7 @@ class AudioClock;
class PublicEditor;
class Keyboard;
class OptionEditor;
+class KeyEditor;
class Mixer_UI;
class ConnectionEditor;
class RouteParams_UI;
@@ -149,6 +150,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
PublicEditor& the_editor(){return *editor;}
Mixer_UI* the_mixer() { return mixer; }
+ void toggle_key_editor ();
void toggle_location_window ();
void toggle_theme_manager ();
void toggle_big_clock_window ();
@@ -610,6 +612,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI
static UIConfiguration *ui_config;
ThemeManager *theme_manager;
+ /* Key bindings editor */
+
+ KeyEditor *key_editor;
+
/* Options window */
OptionEditor *option_editor;
diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc
index b5fa7e2396..aa3455b7da 100644
--- a/gtk2_ardour/ardour_ui_dialogs.cc
+++ b/gtk2_ardour/ardour_ui_dialogs.cc
@@ -35,6 +35,7 @@
#include "route_params_ui.h"
#include "sfdb_ui.h"
#include "theme_manager.h"
+#include "keyeditor.h"
#include "i18n.h"
@@ -329,6 +330,27 @@ ARDOUR_UI::toggle_location_window ()
}
void
+ARDOUR_UI::toggle_key_editor ()
+{
+ if (key_editor == 0) {
+ key_editor = new KeyEditor;
+ key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
+ }
+
+ RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
+ if (act) {
+ RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
+
+ if (tact->get_active()) {
+ key_editor->show_all ();
+ key_editor->present ();
+ } else {
+ key_editor->hide ();
+ }
+ }
+}
+
+void
ARDOUR_UI::toggle_theme_manager ()
{
RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index cc835c81b6..4ee6ccc2fc 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -211,7 +211,8 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_toggle_action (common_actions, X_("ToggleBigClock"), _("Big Clock"), mem_fun(*this, &ARDOUR_UI::toggle_big_clock_window));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_action (common_actions, X_("About"), _("About"), mem_fun(*this, &ARDOUR_UI::show_splash));
- act = ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
+ ActionManager::register_toggle_action (common_actions, X_("ToggleThemeManager"), _("Theme Manager"), mem_fun(*this, &ARDOUR_UI::toggle_theme_manager));
+ ActionManager::register_toggle_action (common_actions, X_("ToggleKeyEditor"), _("Keybindings"), mem_fun(*this, &ARDOUR_UI::toggle_key_editor));
act = ActionManager::register_action (common_actions, X_("AddAudioTrack"), _("Add Audio Track"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_track), 1, 1, ARDOUR::Normal, 1));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index e7f6e7b67b..b39bfec403 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -5034,7 +5034,6 @@ Editor::compute_mouse_speed ()
total += mouse_speed[n];
}
-
return mouse_direction * total/mouse_speed_size;
}
@@ -5063,6 +5062,8 @@ Editor::update_mouse_speed ()
if (fabs (speed) < 0.1) {
/* don't asymptotically approach zero */
memset (mouse_speed, 0, sizeof (double) * mouse_speed_size);
+ have_full_mouse_speed = 0;
+ mouse_speed_entries = 0;
speed = 0.0;
} else if (fabs (speed) < 0.25) {
add_mouse_speed (fabs (speed * 0.2), mouse_direction);
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 872535aba9..34b3f06cf6 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -3039,7 +3039,7 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
playlist = (*i)->region()->playlist();
XMLNode &before = playlist->get_state();
- playlist->duplicate (r, r->last_frame(), times);
+ playlist->duplicate (r, r->last_frame() + 1, times);
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
c.disconnect ();
diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h
index a4904f770b..076bb73e43 100644
--- a/gtk2_ardour/keyboard.h
+++ b/gtk2_ardour/keyboard.h
@@ -25,6 +25,7 @@
#include <sigc++/signal.h>
#include <gtk/gtk.h>
+#include <gtkmm/window.h>
#include <ardour/types.h>
#include <pbd/stateful.h>
diff --git a/gtk2_ardour/keyeditor.cc b/gtk2_ardour/keyeditor.cc
new file mode 100644
index 0000000000..07aad652af
--- /dev/null
+++ b/gtk2_ardour/keyeditor.cc
@@ -0,0 +1,159 @@
+#include <map>
+
+#include <gtkmm/stock.h>
+#include <gtkmm/accelkey.h>
+#include <gtkmm/accelmap.h>
+#include <gtkmm/uimanager.h>
+
+#include <pbd/strsplit.h>
+
+#include "actions.h"
+#include "keyboard.h"
+#include "keyeditor.h"
+
+#include "i18n.h"
+
+using namespace std;
+using namespace Gtk;
+using namespace Gdk;
+
+KeyEditor::KeyEditor ()
+ : ArdourDialog (_("Keybinding Editor"), false)
+{
+ model = TreeStore::create(columns);
+
+ view.set_model (model);
+ view.append_column (_("Action"), columns.action);
+ view.append_column (_("Binding"), columns.binding);
+ view.set_headers_visible (true);
+ view.get_selection()->set_mode (SELECTION_SINGLE);
+ view.set_reorderable (false);
+ view.set_size_request (300,200);
+ view.set_enable_search (false);
+ view.set_rules_hint (true);
+ view.set_name (X_("KeyEditorTree"));
+
+ view.get_selection()->signal_changed().connect (mem_fun (*this, &KeyEditor::action_selected));
+
+ scroller.add (view);
+ scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ get_vbox()->pack_start (scroller);
+
+ scroller.show ();
+ view.show ();
+}
+
+void
+KeyEditor::on_show ()
+{
+ populate ();
+ view.get_selection()->unselect_all ();
+ ArdourDialog::on_show ();
+}
+
+void
+KeyEditor::on_unmap ()
+{
+ ArdourDialog::on_unmap ();
+}
+
+void
+KeyEditor::action_selected ()
+{
+}
+
+bool
+KeyEditor::on_key_release_event (GdkEventKey* ev)
+{
+ TreeModel::iterator i = view.get_selection()->get_selected();
+
+ if (i != model->children().end()) {
+ string path = (*i)[columns.path];
+
+ bool result = AccelMap::change_entry (path,
+ ev->keyval,
+ (ModifierType) ev->state,
+ true);
+
+ if (result) {
+ bool known;
+ AccelKey key;
+
+ known = ActionManager::lookup_entry (path, key);
+
+ if (known) {
+ (*i)[columns.binding] = ActionManager::ui_manager->get_accel_group()->name (key.get_key(), Gdk::ModifierType (key.get_mod()));
+ } else {
+ (*i)[columns.binding] = string();
+ }
+ }
+
+
+ }
+
+ return true;
+}
+
+void
+KeyEditor::populate ()
+{
+ vector<string> paths;
+ vector<string> labels;
+ vector<string> keys;
+ vector<AccelKey> bindings;
+ typedef std::map<string,TreeIter> NodeMap;
+ NodeMap nodes;
+ NodeMap::iterator r;
+
+ ActionManager::get_all_actions (labels, paths, keys, bindings);
+
+ vector<string>::iterator k;
+ vector<string>::iterator p;
+ vector<string>::iterator l;
+
+ model->clear ();
+
+ for (l = labels.begin(), k = keys.begin(), p = paths.begin(); l != labels.end(); ++k, ++p, ++l) {
+
+ TreeModel::Row row;
+ vector<string> parts;
+
+ parts.clear ();
+
+ split (*p, parts, '/');
+
+ if (parts.empty()) {
+ continue;
+ }
+
+ if ((r = nodes.find (parts[1])) == nodes.end()) {
+
+ /* top level is missing */
+
+ TreeIter rowp;
+ TreeModel::Row parent;
+ rowp = model->append();
+ nodes[parts[1]] = rowp;
+ parent = *(rowp);
+ parent[columns.action] = parts[1];
+
+ row = *(model->append (parent.children()));
+
+ } else {
+
+ row = *(model->append ((*r->second)->children()));
+
+ }
+
+ /* add this action */
+
+ row[columns.action] = (*l);
+ row[columns.path] = (*p);
+
+ if (*k == ActionManager::unbound_string) {
+ row[columns.binding] = string();
+ } else {
+ row[columns.binding] = (*k);
+ }
+ }
+}
diff --git a/gtk2_ardour/keyeditor.h b/gtk2_ardour/keyeditor.h
new file mode 100644
index 0000000000..b200adabf4
--- /dev/null
+++ b/gtk2_ardour/keyeditor.h
@@ -0,0 +1,44 @@
+#ifndef __ardour_gtk_key_editor_h__
+#define __ardour_gtk_key_editor_h__
+
+#include <string>
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/scrolledwindow.h>
+#include <glibmm/ustring.h>
+
+#include "ardour_dialog.h"
+
+class KeyEditor : public ArdourDialog
+{
+ public:
+ KeyEditor ();
+
+ protected:
+ void on_show ();
+ void on_unmap ();
+ bool on_key_release_event (GdkEventKey*);
+
+ private:
+ struct KeyEditorColumns : public Gtk::TreeModel::ColumnRecord {
+ KeyEditorColumns () {
+ add (action);
+ add (binding);
+ add (path);
+ }
+ Gtk::TreeModelColumn<Glib::ustring> action;
+ Gtk::TreeModelColumn<std::string> binding;
+ Gtk::TreeModelColumn<std::string> path;
+ };
+
+ Gtk::ScrolledWindow scroller;
+ Gtk::TreeView view;
+ Glib::RefPtr<Gtk::TreeStore> model;
+ KeyEditorColumns columns;
+
+ void action_selected ();
+ void populate ();
+};
+
+#endif /* __ardour_gtk_key_editor_h__ */
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 184ea8d998..f7e982b502 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -760,14 +760,14 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
uint64_t phase = last_phase;
- uint64_t phi_delta;
+ int64_t phi_delta;
nframes_t i = 0;
// Linearly interpolate into the alt buffer
// using 40.24 fixp maths (swh)
if (phi != target_phi) {
- phi_delta = (target_phi - phi) / nframes;
+ phi_delta = ((int64_t)(target_phi - phi)) / nframes;
} else {
phi_delta = 0;
}
@@ -792,7 +792,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
chaninfo->current_playback_buffer = chaninfo->speed_buffer;
}
- playback_distance = i + 1;
+ playback_distance = i;
last_phase = (phase & 0xFFFFFF);
} else {
diff --git a/libs/pbd/strsplit.cc b/libs/pbd/strsplit.cc
index b7a7109af4..342daadaa2 100644
--- a/libs/pbd/strsplit.cc
+++ b/libs/pbd/strsplit.cc
@@ -49,7 +49,7 @@ split (string str, vector<string>& result, char splitchar)
remaining = str;
- while ((pos = remaining.find_first_of (':')) != string::npos) {
+ while ((pos = remaining.find_first_of (splitchar)) != string::npos) {
result.push_back (remaining.substr (0, pos));
remaining = remaining.substr (pos+1);
}
@@ -87,7 +87,7 @@ split (ustring str, vector<ustring>& result, char splitchar)
remaining = str;
- while ((pos = remaining.find_first_of (':')) != ustring::npos) {
+ while ((pos = remaining.find_first_of (splitchar)) != ustring::npos) {
result.push_back (remaining.substr (0, pos));
remaining = remaining.substr (pos+1);
}