add keybinding editor
[ardour.git] / gtk2_ardour / processor_box.cc
index 756067e1e22660486c336b97712c3d43119e1f05..12e30e59c0b4668d16cab982a6648375a0e86e9c 100644 (file)
@@ -153,6 +153,10 @@ ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, boost::shared_ptr<Ro
        /* now force an update of all the various elements */
 
        redisplay_processors ();
+       processor_eventbox.show();
+       processor_scroller.show();
+       processor_display.show();
+       show();
 }
 
 ProcessorBox::~ProcessorBox ()
@@ -334,7 +338,7 @@ ProcessorBox::processor_button_release_event (GdkEventButton *ev)
                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;
@@ -390,13 +394,13 @@ ProcessorBox::processor_plugin_chosen (boost::shared_ptr<Plugin> plugin)
 
                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)));
                }
        }
 }
@@ -478,36 +482,39 @@ ProcessorBox::choose_send ()
        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
@@ -735,39 +742,38 @@ 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 ();
 }
@@ -776,7 +782,7 @@ void
 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);
 
@@ -787,12 +793,11 @@ ProcessorBox::copy_processors ()
        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
@@ -865,57 +870,64 @@ ProcessorBox::rename_processor (boost::shared_ptr<Processor> processor)
 }
 
 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)) {
@@ -1050,7 +1062,7 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
                }
        }
        
-       if ((send = boost::dynamic_pointer_cast<Send> (send)) != 0) {
+       if ((send = boost::dynamic_pointer_cast<Send> (processor)) != 0) {
                
                if (!_session.engine().connected()) {
                        return;