/* now force an update of all the various elements */
redisplay_processors ();
+ processor_eventbox.show();
+ processor_scroller.show();
+ processor_display.show();
+ show();
}
ProcessorBox::~ProcessorBox ()
show_processor_menu(ev->time);
ret = true;
- } else if (processor && (ev->button == 2) && (ev->state == Gdk::BUTTON2_MASK)) {
+ } else if (processor && (ev->button == 2) && (Keyboard::no_modifier_keys_pressed (ev) && ((ev->state & Gdk::BUTTON2_MASK) == Gdk::BUTTON2_MASK))) {
processor->set_active (!processor->active());
ret = true;
boost::shared_ptr<Processor> processor (new PluginInsert (_session, plugin, _placement));
- processor->ActiveChanged.connect (bind (mem_fun (*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
-
Route::ProcessorStreams err;
if (_route->add_processor (processor, &err)) {
weird_plugin_dialog (*plugin, err, _route);
// XXX SHAREDPTR delete plugin here .. do we even need to care?
+ } else {
+ processor->ActiveChanged.connect (bind (mem_fun (*this, &ProcessorBox::show_processor_active), boost::weak_ptr<Processor>(processor)));
}
}
}
boost::shared_ptr<Send> send (new Send (_session, _placement));
//send->set_default_type(_route->default_type());
- /* XXX need redirect lock on route */
+ ChanCount outs;
+
+ /* make an educated guess at the initial number of outputs for the send */
+
+ if (_session.master_out()) {
+ outs = _session.master_out()->n_outputs();
+ } else {
+ outs = _route->n_outputs();
+ }
- // This will be set properly in route->add_processor
- send->configure_io (_route->max_processor_outs(), _route->max_processor_outs());
+ send->io()->ensure_io (ChanCount::ZERO, outs, false, this);
+
+ SendUIWindow* gui = new SendUIWindow (send, _session);
- IOSelectorWindow *ios = new IOSelectorWindow (_session, send->io(), false, true);
+ /* let the user adjust the output setup (number and connections) before passing
+ it along to the Route
+ */
- ios->show_all ();
+ gui->show_all ();
+ gui->present ();
+
+ /* pass shared_ptr, it will go out of scope when the GUI is deleted */
+ /* also, connect it *before* existing handlers so that its definitely executed */
- ios->selector().Finished.connect (bind (mem_fun(*this, &ProcessorBox::send_io_finished), send, ios));
+ gui->signal_delete_event().connect (bind (mem_fun(*this, &ProcessorBox::send_io_finished), send, gui), false);
}
-void
-ProcessorBox::send_io_finished (IOSelector::Result r, boost::shared_ptr<Send> send, IOSelectorWindow* ios)
+bool
+ProcessorBox::send_io_finished (GdkEventAny* ev, boost::shared_ptr<Send> send, SendUIWindow* sui)
{
- if (!send) {
- return;
- }
-
- switch (r) {
- case IOSelector::Cancelled:
- // send will go away when all shared_ptrs to it vanish
- break;
-
- case IOSelector::Accepted:
- _route->add_processor (send);
- break;
- }
-
- delete_when_idle (ios);
+ _route->add_processor (send);
+ delete sui;
+ return false;
}
void
ProcessorBox::cut_processors ()
{
vector<boost::shared_ptr<Processor> > to_be_removed;
-
+ XMLNode* node = new XMLNode (X_("cut"));
+
get_selected_processors (to_be_removed);
if (to_be_removed.empty()) {
return;
}
- /* this essentially transfers ownership of the processor
- of the processor from the route to the mixer
- selection.
- */
-
- _rr_selection.set (to_be_removed);
-
no_processor_redisplay = true;
for (vector<boost::shared_ptr<Processor> >::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) {
- // Do not cut processors or sends
+ // Do not cut inserts or sends
+
if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0) {
void* gui = (*i)->get_gui ();
if (gui) {
static_cast<Gtk::Widget*>(gui)->hide ();
}
-
- if (_route->remove_processor (*i)) {
- /* removal failed */
- _rr_selection.remove (*i);
- }
- } else {
- _rr_selection.remove (*i);
- }
+
+ XMLNode& child ((*i)->get_state());
+ if (_route->remove_processor (*i) == 0) {
+ /* success */
+ node->add_child_nocopy (child);
+ } else {
+ delete &child;
+ }
+ }
}
+
+ _rr_selection.set (node);
+
no_processor_redisplay = false;
redisplay_processors ();
}
ProcessorBox::copy_processors ()
{
vector<boost::shared_ptr<Processor> > to_be_copied;
- vector<boost::shared_ptr<Processor> > copies;
+ XMLNode* node = new XMLNode (X_("copy"));
get_selected_processors (to_be_copied);
for (vector<boost::shared_ptr<Processor> >::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) {
// Do not copy processors or sends
if (boost::dynamic_pointer_cast<PluginInsert>((*i)) != 0) {
- copies.push_back (Processor::clone (*i));
+ node->add_child_nocopy ((*i)->get_state());
}
}
- _rr_selection.set (copies);
-
+ _rr_selection.set (node);
}
void
}
void
-ProcessorBox::cut_processor (boost::shared_ptr<Processor> processor)
+ProcessorBox::paste_processors ()
{
- /* this essentially transfers ownership of the processor
- of the processor from the route to the mixer
- selection.
- */
+ if (_rr_selection.processors.empty()) {
+ return;
+ }
- _rr_selection.add (processor);
-
- void* gui = processor->get_gui ();
+ cerr << "paste from node called " << _rr_selection.processors.get_node().name() << endl;
- if (gui) {
- static_cast<Gtk::Widget*>(gui)->hide ();
- }
-
- no_processor_redisplay = true;
- if (_route->remove_processor (processor)) {
- _rr_selection.remove (processor);
- }
- no_processor_redisplay = false;
- redisplay_processors ();
+ paste_processor_state (_rr_selection.processors.get_node());
}
void
-ProcessorBox::copy_processor (boost::shared_ptr<Processor> processor)
+ProcessorBox::paste_processor_list (list<boost::shared_ptr<Processor> >& processors)
{
- boost::shared_ptr<Processor> copy = Processor::clone (processor);
- _rr_selection.add (copy);
-}
+ list<boost::shared_ptr<Processor> > copies;
+
+ for (list<boost::shared_ptr<Processor> >::iterator i = processors.begin(); i != processors.end(); ++i) {
+
+ boost::shared_ptr<Processor> copy = Processor::clone (*i);
+
+ copy->set_placement (_placement);
+ copies.push_back (copy);
+ }
-void
-ProcessorBox::paste_processors ()
-{
- if (_rr_selection.processors.empty()) {
- return;
- }
+ if (_route->add_processors (copies)) {
- paste_processor_list (_rr_selection.processors);
+ string msg = _(
+ "Copying the set of processors on the clipboard failed,\n\
+probably because the I/O configuration of the plugins\n\
+could not match the configuration of this track.");
+ MessageDialog am (msg);
+ am.run ();
+ }
}
void
-ProcessorBox::paste_processor_list (list<boost::shared_ptr<Processor> >& processors)
+ProcessorBox::paste_processor_state (const XMLNode& node)
{
+ XMLNodeList nlist;
+ XMLNodeConstIterator niter;
list<boost::shared_ptr<Processor> > copies;
- for (list<boost::shared_ptr<Processor> >::iterator i = processors.begin(); i != processors.end(); ++i) {
+ nlist = node.children();
- boost::shared_ptr<Processor> copy = Processor::clone (*i);
+ cerr << "Pasting processor selection containing " << nlist.size() << endl;
- copy->set_placement (_placement);
- copies.push_back (copy);
+ if (nlist.empty()) {
+ return;
+ }
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+ cerr << "try using " << (*niter)->name() << endl;
+ try {
+ copies.push_back (boost::shared_ptr<Processor> (new PluginInsert (_session, **niter)));
+ }
+ catch (...) {
+ cerr << "plugin insert constructor failed\n";
+ }
}
if (_route->add_processors (copies)) {
}
}
- if ((send = boost::dynamic_pointer_cast<Send> (send)) != 0) {
+ if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
if (!_session.engine().connected()) {
return;