Move more Gtkmm2ext widgets into libwidget
[ardour.git] / gtk2_ardour / editor_pt_import.cc
index 3639fcf877f5fc468b794b69184e11b9bbe8365e..55c3b0b43c9782009aa3e616ad7d2823dfe3dba2 100644 (file)
 #include "pbd/shortpath.h"
 #include "pbd/stateful_diff_command.h"
 
-#include <gtkmm2ext/choice.h>
-
 #include "ardour/audio_track.h"
 #include "ardour/audiofilesource.h"
 #include "ardour/audioregion.h"
 #include "ardour/midi_region.h"
 #include "ardour/midi_track.h"
+#include "ardour/midi_model.h"
 #include "ardour/operations.h"
 #include "ardour/region_factory.h"
 #include "ardour/smf_source.h"
@@ -60,7 +59,7 @@
 #include "mouse_cursors.h"
 #include "editor_cursors.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
@@ -179,11 +178,25 @@ Editor::do_ptimport (std::string ptpath,
                msg.run ();
        }
 
+       // Create a dummy midi track first to get a midi Source
+       list<boost::shared_ptr<MidiTrack> > mt (
+               _session->new_midi_track (ChanCount (DataType::MIDI, 1),
+                                         ChanCount (DataType::MIDI, 1),
+                                         true,
+                                         instrument, (Plugin::PresetRecord*) 0,
+                                         (RouteGroup*) 0,
+                                         1,
+                                         string(),
+                                         PresentationInfo::max_order));
+       if (mt.empty()) {
+               return;
+       }
+
        for (vector<PTFFormat::region_t>::iterator a = ptf.regions.begin();
                        a != ptf.regions.end(); ++a) {
                for (vector<ptflookup_t>::iterator p = ptfwavpair.begin();
                                p != ptfwavpair.end(); ++p) {
-                       if (p->index1 == a->wave.index) {
+                       if ((p->index1 == a->wave.index) && (strcmp(a->wave.filename.c_str(), "") != 0)) {
                                for (SourceList::iterator x = imported.begin();
                                                x != imported.end(); ++x) {
                                        if ((*x)->id() == p->id) {
@@ -212,6 +225,42 @@ Editor::do_ptimport (std::string ptpath,
                                }
                        }
                }
+               if (strcmp(a->wave.filename.c_str(), "") == 0) {
+                       /* Empty wave - assume MIDI region */
+                       boost::shared_ptr<MidiTrack> midi_track = mt.back();
+                       boost::shared_ptr<Playlist> playlist = midi_track->playlist();
+                       framepos_t f = (framepos_t)a->startpos;
+                       framecnt_t length = (framecnt_t)a->length;
+                       MusicFrame pos (f, 0);
+                       boost::shared_ptr<Source> src = _session->create_midi_source_by_stealing_name (midi_track);
+                       PropertyList plist;
+                       plist.add (ARDOUR::Properties::start, 0);
+                       plist.add (ARDOUR::Properties::length, length);
+                       plist.add (ARDOUR::Properties::name, PBD::basename_nosuffix(src->name()));
+                       boost::shared_ptr<Region> region = (RegionFactory::create (src, plist));
+                       /* sets beat position */
+                       region->set_position (pos.frame, pos.division);
+                       midi_track->playlist()->add_region (region, pos.frame, 1.0, false, pos.division);
+
+                       boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
+                       boost::shared_ptr<MidiModel> mm = mr->midi_source(0)->model();
+                       MidiModel::NoteDiffCommand *midicmd;
+                       midicmd = mm->new_note_diff_command ("Import ProTools MIDI");
+
+                       for (vector<PTFFormat::midi_ev_t>::iterator
+                                       j = a->midi.begin();
+                                       j != a->midi.end(); ++j) {
+                               Evoral::Beats start = (Evoral::Beats)(j->pos/960000.);
+                               Evoral::Beats len = (Evoral::Beats)(j->length/960000.);
+                               // PT C-2 = 0, Ardour C-1 = 0, subtract twelve to convert...
+                               midicmd->add(boost::shared_ptr<Evoral::Note<Evoral::Beats> >
+                                       (new Evoral::Note<Evoral::Beats>( (uint8_t)1, start, len, j->note - 12, j->velocity )));
+                       }
+                       mm->apply_command (_session, midicmd);
+                       boost::shared_ptr<Region> copy (RegionFactory::create (mr, true));
+                       playlist->clear_changes ();
+                       playlist->add_region (copy, a->startpos);
+               }
        }
 
        boost::shared_ptr<AudioTrack> existing_track;
@@ -244,12 +293,27 @@ Editor::do_ptimport (std::string ptpath,
                                } else {
                                        // Put on a new track
                                        DEBUG_TRACE (DEBUG::FileUtils, string_compose ("\twav(%1) reg(%2) new_tr(%3)\n", a->reg.wave.filename.c_str(), a->reg.index, nth));
-                                       list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (1, 2, Normal, 0, 1));
+                                       list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (1, 2, 0, 1, string(), PresentationInfo::max_order, Normal));
                                        if (at.empty()) {
                                                return;
                                        }
                                        existing_track = at.back();
-                                       existing_track->set_name (a->name);
+                                       std::string trackname;
+                                       try {
+                                               trackname = Glib::convert_with_fallback (a->name, "UTF-8", "UTF-8", "_");
+                                       } catch (Glib::ConvertError& err) {
+                                               trackname = string_compose ("Invalid %1", a->index);
+                                       }
+                                       // TODO legalize track name (no slashes, no colons)
+#if 0 // TODO --  "find_route_name" is currently private
+                                       /* generate a unique name by adding a number if needed */
+                                       uint32_t id = 0;
+                                       if (!_session->find_route_name (trackname.c_str (), id, trackname, false)) {
+                                               fatal << _("PTImport: UINT_MAX routes? impossible!") << endmsg;
+                                               abort(); /*NOTREACHED*/
+                                       }
+#endif
+                                       existing_track->set_name (trackname);
                                        boost::shared_ptr<Playlist> playlist = existing_track->playlist();
                                        boost::shared_ptr<Region> copy (RegionFactory::create (r, true));
                                        playlist->clear_changes ();