diff --git a/gtk2_ardour/ardour3_ui_default.conf b/gtk2_ardour/ardour3_ui_default.conf
index b578556b12..0cdf195798 100644
--- a/gtk2_ardour/ardour3_ui_default.conf
+++ b/gtk2_ardour/ardour3_ui_default.conf
@@ -139,6 +139,7 @@
+
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index c210926b55..0a4a4782d2 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -1050,16 +1050,21 @@ ARDOUR_UI::update_disk_space()
return;
}
- framecnt_t frames = _session->available_capture_duration();
+ boost::optional opt_frames = _session->available_capture_duration();
char buf[64];
framecnt_t fr = _session->frame_rate();
- if (frames == max_framecnt) {
+ if (!opt_frames) {
+ /* Available space is unknown */
+ snprintf (buf, sizeof (buf), "%s", _("Disk: Unknown"));
+ } else if (opt_frames.get_value_or (0) == max_framecnt) {
snprintf (buf, sizeof (buf), "%s", _("Disk: 24hrs+"));
} else {
rec_enabled_streams = 0;
_session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
+ framecnt_t frames = opt_frames.get_value_or (0);
+
if (rec_enabled_streams) {
frames /= rec_enabled_streams;
}
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 6e867292dc..7b4ffb9f0e 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -243,6 +243,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void maximise_editing_space ();
void restore_editing_space ();
+ void update_tearoff_visibility ();
+
void setup_profile ();
void setup_tooltips ();
@@ -254,6 +256,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void get_process_buffers ();
void drop_process_buffers ();
+ void goto_editor_window ();
+
protected:
friend class PublicEditor;
@@ -279,7 +283,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
ARDOUR::AudioEngine *engine;
Gtk::Tooltips _tooltips;
- void goto_editor_window ();
void goto_mixer_window ();
void toggle_mixer_window ();
void toggle_mixer_on_top ();
diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc
index b9deb1289e..97a9103c4e 100644
--- a/gtk2_ardour/ardour_ui2.cc
+++ b/gtk2_ardour/ardour_ui2.cc
@@ -604,6 +604,14 @@ ARDOUR_UI::editor_realized ()
reset_dpi ();
}
+void
+ARDOUR_UI::update_tearoff_visibility ()
+{
+ if (editor) {
+ editor->update_tearoff_visibility ();
+ }
+}
+
void
ARDOUR_UI::maximise_editing_space ()
{
diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc
index c55942b4bd..2b0e0df215 100644
--- a/gtk2_ardour/ardour_ui_dependents.cc
+++ b/gtk2_ardour/ardour_ui_dependents.cc
@@ -133,29 +133,25 @@ ARDOUR_UI::toggle_mixer_window ()
void
ARDOUR_UI::toggle_mixer_on_top ()
{
- Glib::RefPtr act = ActionManager::get_action (X_("Common"), X_("toggle-mixer-on-top"));
- if (!act) {
- return;
- }
+ /* Only called if the editor window received the shortcut key or if selected
+ from the editor window menu, so the mixer is definitely not on top, and
+ we can unconditionally make it so here.
+
+ XXX this might not work so well where there is a global menu bar, e.g.
+ on OS X.
+ */
- Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act);
+ /* Toggle the mixer to `visible' if required */
+ Glib::RefPtr act = ActionManager::get_action (X_("Common"), X_("toggle-mixer"));
+ if (act) {
+ Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act);
- if (tact->get_active()) {
-
- /* Toggle the mixer to `visible' if required */
- act = ActionManager::get_action (X_("Common"), X_("toggle-mixer"));
- if (act) {
- tact = Glib::RefPtr::cast_dynamic (act);
-
- if (!tact->get_active()) {
- tact->set_active ();
- }
+ if (!tact->get_active()) {
+ tact->set_active (true);
}
-
- goto_mixer_window ();
- } else {
- goto_editor_window ();
}
+
+ goto_mixer_window ();
}
/** The main editor window has been closed */
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index 394b1c5470..9519143af2 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -225,11 +225,11 @@ ARDOUR_UI::install_actions ()
/* windows visibility actions */
ActionManager::register_toggle_action (common_actions, X_("ToggleMaximalEditor"), _("Maximise Editor Space"), sigc::mem_fun (*this, &ARDOUR_UI::toggle_editing_space));
- act = ActionManager::register_toggle_action (common_actions, X_("KeepTearoffs"), _("Toolbars when Maximised"), mem_fun (*this, &ARDOUR_UI::toggle_keep_tearoffs));
+ act = ActionManager::register_toggle_action (common_actions, X_("KeepTearoffs"), _("Show Toolbars"), mem_fun (*this, &ARDOUR_UI::toggle_keep_tearoffs));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_toggle_action (common_actions, X_("toggle-mixer"), S_("Window|Mixer"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_mixer_window));
- ActionManager::register_toggle_action (common_actions, X_("toggle-mixer-on-top"), _("Mixer on Top"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_mixer_on_top));
+ ActionManager::register_action (common_actions, X_("toggle-mixer-on-top"), _("Mixer on Top"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_mixer_on_top));
ActionManager::register_toggle_action (common_actions, X_("ToggleRCOptionsEditor"), _("Preferences"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_rc_options_window));
ActionManager::register_toggle_action (common_actions, X_("ToggleSessionOptionsEditor"), _("Properties"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_session_options_window));
act = ActionManager::register_toggle_action (common_actions, X_("ToggleInspector"), _("Tracks and Busses"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_route_params_window));
diff --git a/gtk2_ardour/ardour_ui_mixer.cc b/gtk2_ardour/ardour_ui_mixer.cc
index e3250d2a1f..aacffa9d20 100644
--- a/gtk2_ardour/ardour_ui_mixer.cc
+++ b/gtk2_ardour/ardour_ui_mixer.cc
@@ -44,7 +44,6 @@ ARDOUR_UI::create_mixer ()
mixer->signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), false));
mixer->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("/Common/toggle-mixer")));
- mixer->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("/Common/toggle-mixer-on-top")));
return 0;
}
diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc
index f2f7d397df..232c41b0c7 100644
--- a/gtk2_ardour/ardour_ui_options.cc
+++ b/gtk2_ardour/ardour_ui_options.cc
@@ -52,7 +52,7 @@ ARDOUR_UI::toggle_keep_tearoffs ()
{
ActionManager::toggle_config_state ("Common", "KeepTearoffs", &RCConfiguration::set_keep_tearoffs, &RCConfiguration::get_keep_tearoffs);
- ARDOUR_UI::toggle_editing_space ();
+ ARDOUR_UI::update_tearoff_visibility();
}
void
diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc
index bb51b94fc4..a80a474232 100644
--- a/gtk2_ardour/automation_controller.cc
+++ b/gtk2_ardour/automation_controller.cc
@@ -137,23 +137,6 @@ AutomationController::end_touch ()
}
}
-void
-AutomationController::automation_state_changed ()
-{
- ENSURE_GUI_THREAD (*this, &AutomationController::automation_state_changed)
-
- bool x = (_controllable->automation_state() != Off);
-
- /* start watching automation so that things move */
-
- _screen_update_connection.disconnect();
-
- if (x) {
- _screen_update_connection = ARDOUR_UI::RapidScreenUpdate.connect (
- sigc::mem_fun (*this, &AutomationController::display_effective_value));
- }
-}
-
void
AutomationController::value_changed ()
{
diff --git a/gtk2_ardour/automation_controller.h b/gtk2_ardour/automation_controller.h
index 0392d8c9a4..88e6d87e01 100644
--- a/gtk2_ardour/automation_controller.h
+++ b/gtk2_ardour/automation_controller.h
@@ -62,7 +62,6 @@ private:
void end_touch();
void value_changed();
- void automation_state_changed();
bool _ignore_change;
boost::shared_ptr _printer;
diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc
index 744ec806d4..f5d2669d0a 100644
--- a/gtk2_ardour/automation_line.cc
+++ b/gtk2_ardour/automation_line.cc
@@ -136,7 +136,11 @@ void
AutomationLine::show ()
{
if (_visible & Line) {
- if (alist->interpolation() != AutomationList::Discrete) {
+ /* Only show the line there are some points, otherwise we may show an out-of-date line
+ when automation points have been removed (the line will still follow the shape of the
+ old points).
+ */
+ if (alist->interpolation() != AutomationList::Discrete && control_points.size() >= 2) {
line->show();
} else {
line->hide ();
diff --git a/gtk2_ardour/canvas-flag.cc b/gtk2_ardour/canvas-flag.cc
index 30299641ed..d77de07359 100644
--- a/gtk2_ardour/canvas-flag.cc
+++ b/gtk2_ardour/canvas-flag.cc
@@ -1,6 +1,12 @@
-#include "canvas-flag.h"
#include
+
+#include "gtkmm2ext/utils.h"
+#include "gtkmm2ext/rgb_macros.h"
+
#include "ardour_ui.h"
+#include "canvas-flag.h"
+#include "time_axis_view_item.h"
+#include "utils.h"
using namespace Gnome::Canvas;
using namespace std;
@@ -13,23 +19,23 @@ CanvasFlag::CanvasFlag (MidiRegionView& region,
double x,
double y)
: Group(parent, x, y)
- , _text(0)
+ , _name_pixbuf(0)
, _height(height)
, _outline_color_rgba(outline_color_rgba)
, _fill_color_rgba(fill_color_rgba)
, _region(region)
+ , name_pixbuf_width (0)
, _line(0)
, _rect(0)
{
- /* XXX this connection is needed if ::on_event() is changed to actually do anything */
signal_event().connect (sigc::mem_fun (*this, &CanvasFlag::on_event));
}
void
CanvasFlag::delete_allocated_objects()
{
- delete _text;
- _text = 0;
+ delete _name_pixbuf;
+ _name_pixbuf = 0;
delete _line;
_line = 0;
@@ -39,28 +45,29 @@ CanvasFlag::delete_allocated_objects()
}
void
-CanvasFlag::set_text(const string& a_text)
+CanvasFlag::set_text (const string& text)
{
delete_allocated_objects();
- _text = new Text (*this, 0.0, 0.0, a_text);
- _text->property_justification() = Gtk::JUSTIFY_CENTER;
- _text->property_fill_color_rgba() = _outline_color_rgba;
- double flagwidth = _text->property_text_width() + 10.0;
- double flagheight = _text->property_text_height() + 3.0;
- _text->property_x() = flagwidth / 2.0;
- _text->property_y() = flagheight / 2.0;
- _text->show();
+ _name_pixbuf = new ArdourCanvas::Pixbuf (*this);
+ name_pixbuf_width = Gtkmm2ext::pixel_width (text, TimeAxisViewItem::NAME_FONT) + 2;
+ Gdk::Color c;
+ set_color (c, _outline_color_rgba);
+ _name_pixbuf->property_pixbuf() = Gtkmm2ext::pixbuf_from_string (text, TimeAxisViewItem::NAME_FONT, name_pixbuf_width,
+ TimeAxisViewItem::NAME_HEIGHT, c);
+ _name_pixbuf->property_x() = 10.0;
+ _name_pixbuf->property_y() = 2.0;
+ _name_pixbuf->show();
+
+ double flagwidth = name_pixbuf_width + 8.0;
+ double flagheight = TimeAxisViewItem::NAME_HEIGHT + 3.0;
_line = new SimpleLine(*this, 0.0, 0.0, 0.0, _height);
_line->property_color_rgba() = _outline_color_rgba;
_rect = new SimpleRect(*this, 0.0, 0.0, flagwidth, flagheight);
_rect->property_outline_color_rgba() = _outline_color_rgba;
_rect->property_fill_color_rgba() = _fill_color_rgba;
- _text->raise_to_top();
- /* XXX these two connections are needed if ::on_event() is changed to actually do anything */
- //_rect->signal_event().connect (sigc::mem_fun (*this, &CanvasFlag::on_event));
- //_text->signal_event().connect (sigc::mem_fun (*this, &CanvasFlag::on_event));
+ _name_pixbuf->raise_to_top();
}
CanvasFlag::~CanvasFlag()
diff --git a/gtk2_ardour/canvas-flag.h b/gtk2_ardour/canvas-flag.h
index c8b32c72a5..17edc19880 100644
--- a/gtk2_ardour/canvas-flag.h
+++ b/gtk2_ardour/canvas-flag.h
@@ -2,12 +2,13 @@
#define CANVASFLAG_H_
#include
+#include
#include
#include
-#include
#include "simplerect.h"
#include "simpleline.h"
+#include "canvas.h"
class MidiRegionView;
@@ -17,13 +18,13 @@ namespace Canvas {
class CanvasFlag : public Group
{
public:
- CanvasFlag(MidiRegionView& region,
- Group& parent,
- double height,
- guint outline_color_rgba = 0xc0c0c0ff,
- guint fill_color_rgba = 0x07070707,
- double x = 0.0,
- double y = 0.0);
+ CanvasFlag (MidiRegionView& region,
+ Group& parent,
+ double height,
+ guint outline_color_rgba = 0xc0c0c0ff,
+ guint fill_color_rgba = 0x07070707,
+ double x = 0.0,
+ double y = 0.0);
virtual ~CanvasFlag();
@@ -32,12 +33,15 @@ public:
virtual void set_text(const std::string& a_text);
virtual void set_height (double);
+ int width () const { return name_pixbuf_width + 10.0; }
+
protected:
- Text* _text;
+ ArdourCanvas::Pixbuf* _name_pixbuf;
double _height;
guint _outline_color_rgba;
guint _fill_color_rgba;
MidiRegionView& _region;
+ int name_pixbuf_width;
private:
void delete_allocated_objects();
diff --git a/gtk2_ardour/canvas_patch_change.cc b/gtk2_ardour/canvas_patch_change.cc
index 44389ae96c..ff28295c6e 100644
--- a/gtk2_ardour/canvas_patch_change.cc
+++ b/gtk2_ardour/canvas_patch_change.cc
@@ -19,10 +19,10 @@
#include
-#include
+#include
#include "gtkmm2ext/keyboard.h"
-#include "ardour/midi_patch_manager.h"
+#include "ardour/instrument_info.h"
#include "ardour_ui.h"
#include "midi_region_view.h"
@@ -44,8 +44,7 @@ CanvasPatchChange::CanvasPatchChange(
double height,
double x,
double y,
- string& model_name,
- string& custom_device_mode,
+ ARDOUR::InstrumentInfo& info,
ARDOUR::MidiModel::PatchChangePtr patch,
bool active_channel)
: CanvasFlag(
@@ -60,12 +59,11 @@ CanvasPatchChange::CanvasPatchChange(
ARDOUR_UI::config()->canvasvar_MidiPatchChangeInactiveChannelFill.get(),
x,
y)
- , _model_name(model_name)
- , _custom_device_mode(custom_device_mode)
+ , _info (info)
, _patch (patch)
, _popup_initialized(false)
{
- set_text(text);
+ set_text (text);
}
CanvasPatchChange::~CanvasPatchChange()
@@ -75,9 +73,7 @@ CanvasPatchChange::~CanvasPatchChange()
void
CanvasPatchChange::initialize_popup_menus()
{
- boost::shared_ptr channel_name_set =
- MidiPatchManager::instance()
- .find_channel_name_set(_model_name, _custom_device_mode, _patch->channel());
+ boost::shared_ptr channel_name_set = _info.get_patches (_patch->channel());
if (!channel_name_set) {
return;
@@ -91,9 +87,6 @@ CanvasPatchChange::initialize_popup_menus()
for (ChannelNameSet::PatchBanks::const_iterator bank = patch_banks.begin();
bank != patch_banks.end();
++bank) {
- Glib::RefPtr underscores = Glib::Regex::create("_");
- std::string replacement(" ");
-
Gtk::Menu& patch_bank_menu = *manage(new Gtk::Menu());
const PatchBank::PatchNameList& patches = (*bank)->patch_name_list();
@@ -102,7 +95,8 @@ CanvasPatchChange::initialize_popup_menus()
for (PatchBank::PatchNameList::const_iterator patch = patches.begin();
patch != patches.end();
++patch) {
- std::string name = underscores->replace((*patch)->name().c_str(), -1, 0, replacement);
+ std::string name = (*patch)->name();
+ boost::replace_all (name, "_", " ");
patch_menus.push_back(
Gtk::Menu_Helpers::MenuElem(
@@ -112,8 +106,8 @@ CanvasPatchChange::initialize_popup_menus()
(*patch)->patch_primary_key())) );
}
-
- std::string name = underscores->replace((*bank)->name().c_str(), -1, 0, replacement);
+ std::string name = (*bank)->name();
+ boost::replace_all (name, "_", " ");
patch_bank_menus.push_back(
Gtk::Menu_Helpers::MenuElem(
@@ -193,22 +187,28 @@ CanvasPatchChange::on_event (GdkEvent* ev)
break;
case GDK_SCROLL:
- if (ev->scroll.direction == GDK_SCROLL_UP) {
- if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
- _region.previous_bank (*this);
- } else {
- _region.previous_patch (*this);
+ {
+ /* XXX: icky dcast */
+ Editor* e = dynamic_cast (&_region.get_time_axis_view().editor());
+ if (e->current_mouse_mode() == Editing::MouseObject && e->internal_editing()) {
+ if (ev->scroll.direction == GDK_SCROLL_UP) {
+ if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
+ _region.previous_bank (*this);
+ } else {
+ _region.previous_patch (*this);
+ }
+ return true;
+ } else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
+ if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
+ _region.next_bank (*this);
+ } else {
+ _region.next_patch (*this);
+ }
+ return true;
}
- return true;
- } else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
- if (Keyboard::modifier_state_contains (ev->scroll.state, Keyboard::PrimaryModifier)) {
- _region.next_bank (*this);
- } else {
- _region.next_patch (*this);
- }
- return true;
+ break;
}
- break;
+ }
case GDK_ENTER_NOTIFY:
_region.patch_entered (this);
@@ -218,9 +218,6 @@ CanvasPatchChange::on_event (GdkEvent* ev)
_region.patch_left (this);
break;
- case GDK_BUTTON_RELEASE:
- return true;
-
default:
break;
}
diff --git a/gtk2_ardour/canvas_patch_change.h b/gtk2_ardour/canvas_patch_change.h
index 2a219fdbb6..20c0067ae7 100644
--- a/gtk2_ardour/canvas_patch_change.h
+++ b/gtk2_ardour/canvas_patch_change.h
@@ -30,6 +30,10 @@ namespace MIDI {
}
}
+namespace ARDOUR {
+ class InstrumentInfo;
+}
+
namespace Gnome {
namespace Canvas {
@@ -43,8 +47,7 @@ public:
double height,
double x,
double y,
- string& model_name,
- string& custom_device_mode,
+ ARDOUR::InstrumentInfo& info,
ARDOUR::MidiModel::PatchChangePtr patch,
bool
);
@@ -53,8 +56,6 @@ public:
virtual bool on_event(GdkEvent* ev);
- string model_name () const { return _model_name; }
- string custom_device_mode () const { return _custom_device_mode; }
ARDOUR::MidiModel::PatchChangePtr patch () const { return _patch; }
void initialize_popup_menus();
@@ -62,8 +63,7 @@ public:
void on_patch_menu_selected(const MIDI::Name::PatchPrimaryKey& key);
private:
- string _model_name;
- string _custom_device_mode;
+ ARDOUR::InstrumentInfo& _info;
ARDOUR::MidiModel::PatchChangePtr _patch;
Gtk::Menu _popup;
bool _popup_initialized;
diff --git a/gtk2_ardour/canvas_vars.h b/gtk2_ardour/canvas_vars.h
index 975f5eb2af..672d4e1256 100644
--- a/gtk2_ardour/canvas_vars.h
+++ b/gtk2_ardour/canvas_vars.h
@@ -133,6 +133,7 @@ CANVAS_VARIABLE(canvasvar_TrimHandle, "trim handle")
CANVAS_VARIABLE(canvasvar_VerboseCanvasCursor, "verbose canvas cursor")
CANVAS_VARIABLE(canvasvar_VestigialFrame, "vestigial frame")
CANVAS_VARIABLE(canvasvar_FrameBase, "region base")
+CANVAS_VARIABLE(canvasvar_CoveredRegion, "region area covered by another region")
CANVAS_VARIABLE(canvasvar_WaveForm, "waveform outline")
CANVAS_VARIABLE(canvasvar_WaveFormClip, "clipped waveform")
CANVAS_VARIABLE(canvasvar_WaveFormFill, "waveform fill")
diff --git a/gtk2_ardour/edit_note_dialog.cc b/gtk2_ardour/edit_note_dialog.cc
index 3c866cfe6f..17827693e7 100644
--- a/gtk2_ardour/edit_note_dialog.cc
+++ b/gtk2_ardour/edit_note_dialog.cc
@@ -28,21 +28,27 @@
#include "i18n.h"
+using namespace std;
using namespace Gtk;
using namespace Gtkmm2ext;
/**
* EditNoteDialog constructor.
*
- * @param n Note to edit.
+ * @param n Notes to edit.
*/
-EditNoteDialog::EditNoteDialog (MidiRegionView* rv, Gnome::Canvas::CanvasNoteEvent* ev)
+EditNoteDialog::EditNoteDialog (MidiRegionView* rv, set n)
: ArdourDialog (_("Note"))
, _region_view (rv)
- , _event (ev)
+ , _events (n)
+ , _channel_all (_("Set selected notes to this channel"))
+ , _pitch_all (_("Set selected notes to this pitch"))
+ , _velocity_all (_("Set selected notes to this velocity"))
, _time_clock (X_("notetime"), true, "", true, false)
+ , _time_all (_("Set selected notes to this time"))
, _length_clock (X_("notelength"), true, "", true, false, true)
+ , _length_all (_("Set selected notes to this length"))
{
Table* table = manage (new Table (4, 2));
table->set_spacings (6);
@@ -52,48 +58,89 @@ EditNoteDialog::EditNoteDialog (MidiRegionView* rv, Gnome::Canvas::CanvasNoteEve
Label* l = manage (left_aligned_label (_("Channel")));
table->attach (*l, 0, 1, r, r + 1);
table->attach (_channel, 1, 2, r, r + 1);
+ table->attach (_channel_all, 2, 3, r, r + 1);
++r;
_channel.set_range (1, 16);
_channel.set_increments (1, 2);
- _channel.set_value (ev->note()->channel () + 1);
+ _channel.set_value ((*_events.begin())->note()->channel () + 1);
l = manage (left_aligned_label (_("Pitch")));
table->attach (*l, 0, 1, r, r + 1);
table->attach (_pitch, 1, 2, r, r + 1);
+ table->attach (_pitch_all, 2, 3, r, r + 1);
++r;
_pitch.set_range (0, 127);
_pitch.set_increments (1, 10);
- _pitch.set_value (ev->note()->note ());
+ _pitch.set_value ((*_events.begin())->note()->note());
l = manage (left_aligned_label (_("Velocity")));
table->attach (*l, 0, 1, r, r + 1);
table->attach (_velocity, 1, 2, r, r + 1);
+ table->attach (_velocity_all, 2, 3, r, r + 1);
++r;
_velocity.set_range (0, 127);
_velocity.set_increments (1, 10);
- _velocity.set_value (ev->note()->velocity ());
+ _velocity.set_value ((*_events.begin())->note()->velocity ());
l = manage (left_aligned_label (_("Time")));
table->attach (*l, 0, 1, r, r + 1);
table->attach (_time_clock, 1, 2, r, r + 1);
+ table->attach (_time_all, 2, 3, r, r + 1);
++r;
_time_clock.set_session (_region_view->get_time_axis_view().session ());
_time_clock.set_mode (AudioClock::BBT);
- _time_clock.set (_region_view->source_relative_time_converter().to (ev->note()->time ()), true);
+ _time_clock.set (_region_view->source_relative_time_converter().to ((*_events.begin())->note()->time ()), true);
l = manage (left_aligned_label (_("Length")));
table->attach (*l, 0, 1, r, r + 1);
table->attach (_length_clock, 1, 2, r, r + 1);
+ table->attach (_length_all, 2, 3, r, r + 1);
++r;
_length_clock.set_session (_region_view->get_time_axis_view().session ());
_length_clock.set_mode (AudioClock::BBT);
- _length_clock.set (_region_view->region_relative_time_converter().to (ev->note()->length ()), true);
+ _length_clock.set (_region_view->region_relative_time_converter().to ((*_events.begin())->note()->length ()), true);
+ /* Set up `set all notes...' buttons' sensitivity */
+
+ _channel_all.set_sensitive (false);
+ _pitch_all.set_sensitive (false);
+ _velocity_all.set_sensitive (false);
+ _time_all.set_sensitive (false);
+ _length_all.set_sensitive (false);
+
+ int test_channel = (*_events.begin())->note()->channel ();
+ int test_pitch = (*_events.begin())->note()->note ();
+ int test_velocity = (*_events.begin())->note()->velocity ();
+ double test_time = (*_events.begin())->note()->time ();
+ double test_length = (*_events.begin())->note()->length ();
+
+ for (set::iterator i = _events.begin(); i != _events.end(); ++i) {
+ if ((*i)->note()->channel() != test_channel) {
+ _channel_all.set_sensitive (true);
+ }
+
+ if ((*i)->note()->note() != test_pitch) {
+ _pitch_all.set_sensitive (true);
+ }
+
+ if ((*i)->note()->velocity() != test_velocity) {
+ _velocity_all.set_sensitive (true);
+ }
+
+ if ((*i)->note()->time () != test_time) {
+ _time_all.set_sensitive (true);
+ }
+
+ if ((*i)->note()->length () != test_length) {
+ _length_all.set_sensitive (true);
+ }
+ }
+
get_vbox()->pack_start (*table);
add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
@@ -122,33 +169,53 @@ EditNoteDialog::run ()
bool had_change = false;
- if (_channel.get_value_as_int() - 1 != _event->note()->channel()) {
- _region_view->change_note_channel (_event, _channel.get_value_as_int () - 1);
- had_change = true;
+ if (!_channel_all.get_sensitive() || _channel_all.get_active ()) {
+ for (set::iterator i = _events.begin(); i != _events.end(); ++i) {
+ if (_channel.get_value_as_int() - 1 != (*i)->note()->channel()) {
+ _region_view->change_note_channel (*i, _channel.get_value_as_int () - 1);
+ had_change = true;
+ }
+ }
}
- if (_pitch.get_value_as_int() != _event->note()->note()) {
- _region_view->change_note_note (_event, _pitch.get_value_as_int (), false);
- had_change = true;
+ if (!_pitch_all.get_sensitive() || _pitch_all.get_active ()) {
+ for (set::iterator i = _events.begin(); i != _events.end(); ++i) {
+ if (_pitch.get_value_as_int() != (*i)->note()->note()) {
+ _region_view->change_note_note (*i, _pitch.get_value_as_int ());
+ had_change = true;
+ }
+ }
}
- if (_velocity.get_value_as_int() != _event->note()->velocity()) {
- _region_view->change_note_velocity (_event, _velocity.get_value_as_int (), false);
- had_change = true;
+ if (!_velocity_all.get_sensitive() || _velocity_all.get_active ()) {
+ for (set::iterator i = _events.begin(); i != _events.end(); ++i) {
+ if (_velocity.get_value_as_int() != (*i)->note()->velocity()) {
+ _region_view->change_note_velocity (*i, _velocity.get_value_as_int ());
+ had_change = true;
+ }
+ }
}
double const t = _region_view->source_relative_time_converter().from (_time_clock.current_time ());
- if (t != _event->note()->time()) {
- _region_view->change_note_time (_event, t);
- had_change = true;
+ if (!_time_all.get_sensitive() || _time_all.get_active ()) {
+ for (set::iterator i = _events.begin(); i != _events.end(); ++i) {
+ if (t != (*i)->note()->time()) {
+ _region_view->change_note_time (*i, t);
+ had_change = true;
+ }
+ }
}
double const d = _region_view->region_relative_time_converter().from (_length_clock.current_duration ());
- if (d != _event->note()->length()) {
- _region_view->change_note_length (_event, d);
- had_change = true;
+ if (!_length_all.get_sensitive() || _length_all.get_active ()) {
+ for (set::iterator i = _events.begin(); i != _events.end(); ++i) {
+ if (d != (*i)->note()->length()) {
+ _region_view->change_note_length (*i, d);
+ had_change = true;
+ }
+ }
}
if (!had_change) {
@@ -157,7 +224,9 @@ EditNoteDialog::run ()
_region_view->apply_diff ();
- _event->set_selected (_event->selected()); // change color
+ for (set::iterator i = _events.begin(); i != _events.end(); ++i) {
+ (*i)->set_selected ((*i)->selected()); // change color
+ }
return r;
}
diff --git a/gtk2_ardour/edit_note_dialog.h b/gtk2_ardour/edit_note_dialog.h
index 8dfd434440..cc92f290c3 100644
--- a/gtk2_ardour/edit_note_dialog.h
+++ b/gtk2_ardour/edit_note_dialog.h
@@ -33,16 +33,21 @@ namespace Gnome {
class EditNoteDialog : public ArdourDialog
{
public:
- EditNoteDialog (MidiRegionView *, Gnome::Canvas::CanvasNoteEvent *);
+ EditNoteDialog (MidiRegionView *, std::set);
int run ();
private:
MidiRegionView* _region_view;
- Gnome::Canvas::CanvasNoteEvent* _event;
+ std::set _events;
Gtk::SpinButton _channel;
+ Gtk::CheckButton _channel_all;
Gtk::SpinButton _pitch;
+ Gtk::CheckButton _pitch_all;
Gtk::SpinButton _velocity;
+ Gtk::CheckButton _velocity_all;
AudioClock _time_clock;
+ Gtk::CheckButton _time_all;
AudioClock _length_clock;
+ Gtk::CheckButton _length_all;
};
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index e17c8046c4..939c05b1e8 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -3928,6 +3928,15 @@ Editor::session_state_saved (string)
_snapshots->redisplay ();
}
+void
+Editor::update_tearoff_visibility()
+{
+ bool visible = Config->get_keep_tearoffs();
+ _mouse_mode_tearoff->set_visible (visible);
+ _tools_tearoff->set_visible (visible);
+ _zoom_tearoff->set_visible (visible);
+}
+
void
Editor::maximise_editing_space ()
{
@@ -3937,15 +3946,6 @@ Editor::maximise_editing_space ()
fullscreen ();
- if (!Config->get_keep_tearoffs()) {
- /* these calls will leave each tearoff visible *if* it is torn off,
- but invisible otherwise.
- */
- _mouse_mode_tearoff->set_visible (false);
- _tools_tearoff->set_visible (false);
- _zoom_tearoff->set_visible (false);
- }
-
_maximised = true;
}
@@ -3958,12 +3958,6 @@ Editor::restore_editing_space ()
unfullscreen();
- if (!Config->get_keep_tearoffs()) {
- _mouse_mode_tearoff->set_visible (true);
- _tools_tearoff->set_visible (true);
- _zoom_tearoff->set_visible (true);
- }
-
_maximised = false;
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index eaf682b9b8..5134b6a7a1 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -63,9 +63,12 @@
#include "canvas.h"
#include "window_proxy.h"
-namespace Gnome { namespace Canvas {
- class NoEventText;
-} }
+namespace Gnome {
+ namespace Canvas {
+ class NoEventText;
+ class CanvasNoteEvent;
+ }
+}
namespace Gtkmm2ext {
class TearOff;
@@ -397,6 +400,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void maximise_editing_space();
void restore_editing_space();
+ void update_tearoff_visibility();
+
void reset_x_origin (framepos_t);
void reset_x_origin_to_follow_playhead ();
void reset_y_origin (double);
@@ -1489,7 +1494,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void edit_tempo_marker (ArdourCanvas::Item*);
void edit_meter_marker (ArdourCanvas::Item*);
void edit_control_point (ArdourCanvas::Item*);
- void edit_note (ArdourCanvas::Item *);
+ void edit_notes (std::set const &);
void marker_menu_edit ();
void marker_menu_remove ();
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index aaf587a464..8a7e09df2c 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -209,7 +209,7 @@ Editor::session_import_dialog ()
typedef std::map > SourceMap;
/**
- * Updating is still disabled, see note in libs/ardour/import.cc Session::import_audiofiles()
+ * Updating is still disabled, see note in libs/ardour/import.cc Session::import_files()
*
* all_or_nothing:
* true = show "Update", "Import" and "Skip"
@@ -546,7 +546,7 @@ Editor::import_sndfiles (vector paths, ImportMode mode, SrcQuality quali
set_canvas_cursor (_cursors->wait);
gdk_flush ();
- /* start import thread for this spec. this will ultimately call Session::import_audiofiles()
+ /* start import thread for this spec. this will ultimately call Session::import_files()
which, if successful, will add the files as regions to the region list. its up to us
(the GUI) to direct additional steps after that.
*/
@@ -788,7 +788,7 @@ Editor::add_sources (vector paths, SourceList& sources, framepos_t& pos,
*/
framecnt_t len = (*x)->length (pos);
if (len == 0) {
- len = (60 / 120) * _session->frame_rate ();
+ len = (60.0 / 120.0) * _session->frame_rate ();
}
plist.add (ARDOUR::Properties::start, 0);
@@ -827,6 +827,8 @@ Editor::add_sources (vector paths, SourceList& sources, framepos_t& pos,
int n = 0;
framepos_t rlen = 0;
+ begin_reversible_command (Operations::insert_file);
+
for (vector >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
boost::shared_ptr ar = boost::dynamic_pointer_cast (*r);
@@ -874,6 +876,8 @@ Editor::add_sources (vector paths, SourceList& sources, framepos_t& pos,
}
}
+ commit_reversible_command ();
+
/* setup peak file building in another thread */
for (SourceList::iterator x = sources.begin(); x != sources.end(); ++x) {
@@ -885,7 +889,7 @@ Editor::add_sources (vector paths, SourceList& sources, framepos_t& pos,
int
Editor::finish_bringing_in_material (boost::shared_ptr region, uint32_t in_chans, uint32_t out_chans, framepos_t& pos,
- ImportMode mode, boost::shared_ptr