From 9f41acc07a7ca7b06ac0903af487a9a745748ac6 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Tue, 4 May 2004 21:46:28 +0000 Subject: [PATCH] Implemented drag&drop onto the input, attachment and chapter editor tabs. --- ChangeLog | 7 + src/mmg/mux_dialog.cpp | 12 +- src/mmg/tab_attachments.cpp | 86 +++++---- src/mmg/tab_attachments.h | 1 + src/mmg/tab_chapters.cpp | 18 +- src/mmg/tab_input.cpp | 343 +++++++++++++++++++----------------- src/mmg/tab_input.h | 1 + 7 files changed, 272 insertions(+), 196 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7d86fd727..c12ac48ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-05-04 Moritz Bunkus + + * mmg: new feature: Implement drag'n'drop of files onto the input, + attachment and chapter tabs. For the input and attachment tabs it + works like pressing the 'add' button. On the chapters tab it works + like calling 'Chapter Editor -> Open'. + 2004-05-02 Moritz Bunkus * mkvinfo/mmg: Enabled compilation with wxWidgets 2.5 and Unicode diff --git a/src/mmg/mux_dialog.cpp b/src/mmg/mux_dialog.cpp index 88ef365a0..3873e91b9 100644 --- a/src/mmg/mux_dialog.cpp +++ b/src/mmg/mux_dialog.cpp @@ -55,7 +55,7 @@ mux_dialog::mux_dialog(wxWindow *parent): wxSize(500, 520), #endif wxCAPTION) { - wxChar c; + char c; string arg_utf8; long value; wxString line, tmp; @@ -151,7 +151,7 @@ mux_dialog::mux_dialog(wxWindow *parent): while (app->Pending()) app->Dispatch(); - if ((c == wxT('\n')) || (c == wxT('\r')) || out->Eof()) { + if ((c == '\n') || (c == '\r') || out->Eof()) { if (line.Find(wxT("Warning:")) == 0) tc_warnings->AppendText(line + wxT("\n")); else if (line.Find(wxT("Error:")) == 0) @@ -167,8 +167,12 @@ mux_dialog::mux_dialog(wxWindow *parent): } else if (line.Length() > 0) tc_output->AppendText(line + wxT("\n")); line = wxT(""); - } else if ((unsigned char)c != 0xff) - line.Append(c); + } else if ((unsigned char)c != 0xff) { + char s[2]; + s[0] = c; + s[1] = 0; + line.Append(wxU(s)); + } if (out->Eof()) break; diff --git a/src/mmg/tab_attachments.cpp b/src/mmg/tab_attachments.cpp index b6bf3d45e..b78889331 100644 --- a/src/mmg/tab_attachments.cpp +++ b/src/mmg/tab_attachments.cpp @@ -22,8 +22,9 @@ #include "wx/wxprec.h" #include "wx/wx.h" -#include "wx/notebook.h" +#include "wx/dnd.h" #include "wx/listctrl.h" +#include "wx/notebook.h" #include "wx/statline.h" #include "common.h" @@ -33,6 +34,22 @@ vector attachments; +class attachments_drop_target_c: public wxFileDropTarget { +private: + tab_attachments *owner; +public: + attachments_drop_target_c(tab_attachments *n_owner): + owner(n_owner) {}; + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &files) { + int i; + + for (i = 0; i < files.Count(); i++) + owner->add_attachment(files[i]); + + return true; + } +}; + tab_attachments::tab_attachments(wxWindow *parent): wxPanel(parent, -1, wxDefaultPosition, wxSize(100, 400), wxTAB_TRAVERSAL) { @@ -90,6 +107,8 @@ tab_attachments::tab_attachments(wxWindow *parent): t_get_entries.SetOwner(this, ID_T_ATTACHMENTVALUES); t_get_entries.Start(333); + + SetDropTarget(new attachments_drop_target_c(this)); } void @@ -101,44 +120,49 @@ tab_attachments::enable(bool e) { void tab_attachments::on_add_attachment(wxCommandEvent &evt) { - mmg_attachment_t attch; - wxString name, ext; - uint32_t i, j; - vector extensions; - wxFileDialog dlg(NULL, wxT("Choose an attachment file"), last_open_dir, wxT(""), wxT(ALLFILES), wxOPEN); if(dlg.ShowModal() == wxID_OK) { last_open_dir = dlg.GetDirectory(); - attch.file_name = new wxString(dlg.GetPath()); - name = dlg.GetFilename(); - ext = name.AfterLast(wxT('.')); - name += wxString(wxT(" (")) + last_open_dir + wxT(")"); - lb_attachments->Append(name); - attch.mime_type = NULL; - if (ext.Length() > 0) { - for (i = 0; (mime_types[i].name != NULL) && (attch.mime_type == NULL); - i++) { - if (mime_types[i].extensions[0] == 0) - continue; - extensions = split(wxU(mime_types[i].extensions), wxU(" ")); - for (j = 0; j < extensions.size(); j++) - if (!wxStricmp(extensions[j], ext)) { - attch.mime_type = new wxString(wxU(mime_types[i].name)); - break; - } - } - } - if (attch.mime_type == NULL) - attch.mime_type = new wxString(wxT("")); - attch.description = new wxString(wxT("")); - attch.style = 0; - - attachments.push_back(attch); + add_attachment(dlg.GetPath()); } } +void +tab_attachments::add_attachment(const wxString &file_name) { + mmg_attachment_t attch; + wxString name, ext; + uint32_t i, j; + vector extensions; + + attch.file_name = new wxString(file_name); + name = file_name.AfterLast(wxT(PSEP)); + ext = name.AfterLast(wxT('.')); + name += wxString(wxT(" (")) + file_name.BeforeLast(wxT(PSEP)) + wxT(")"); + lb_attachments->Append(name); + attch.mime_type = NULL; + if (ext.Length() > 0) { + for (i = 0; (mime_types[i].name != NULL) && (attch.mime_type == NULL); + i++) { + if (mime_types[i].extensions[0] == 0) + continue; + extensions = split(wxU(mime_types[i].extensions), wxU(" ")); + for (j = 0; j < extensions.size(); j++) + if (!wxStricmp(extensions[j], ext)) { + attch.mime_type = new wxString(wxU(mime_types[i].name)); + break; + } + } + } + if (attch.mime_type == NULL) + attch.mime_type = new wxString(wxT("")); + attch.description = new wxString(wxT("")); + attch.style = 0; + + attachments.push_back(attch); +} + void tab_attachments::on_remove_attachment(wxCommandEvent &evt) { mmg_attachment_t *a; diff --git a/src/mmg/tab_attachments.h b/src/mmg/tab_attachments.h index d4cef7422..6e07e1606 100644 --- a/src/mmg/tab_attachments.h +++ b/src/mmg/tab_attachments.h @@ -51,6 +51,7 @@ public: tab_attachments(wxWindow *parent); void on_add_attachment(wxCommandEvent &evt); + void add_attachment(const wxString &file_name); void on_remove_attachment(wxCommandEvent &evt); void on_attachment_selected(wxCommandEvent &evt); void on_description_changed(wxCommandEvent &evt); diff --git a/src/mmg/tab_chapters.cpp b/src/mmg/tab_chapters.cpp index dc197b0c0..d0a1262f3 100644 --- a/src/mmg/tab_chapters.cpp +++ b/src/mmg/tab_chapters.cpp @@ -23,8 +23,9 @@ #include #include "wx/wx.h" -#include "wx/notebook.h" +#include "wx/dnd.h" #include "wx/listctrl.h" +#include "wx/notebook.h" #include "wx/statline.h" #include @@ -44,6 +45,19 @@ using namespace std; using namespace libebml; using namespace libmatroska; +class chapters_drop_target_c: public wxFileDropTarget { +private: + tab_chapters *owner; +public: + chapters_drop_target_c(tab_chapters *n_owner): + owner(n_owner) {}; + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &files) { + owner->load(files[0]); + + return true; + } +}; + #define FINDFIRST(p, c) (static_cast \ (((EbmlMaster *)p)->FindFirstElt(c::ClassInfos, false))) #define FINDNEXT(p, c, e) (static_cast \ @@ -318,6 +332,8 @@ tab_chapters::tab_chapters(wxWindow *parent, source_is_simple_format = false; no_update = false; + + SetDropTarget(new chapters_drop_target_c(this)); } tab_chapters::~tab_chapters() { diff --git a/src/mmg/tab_input.cpp b/src/mmg/tab_input.cpp index 50a4ca82d..5d07a8e49 100644 --- a/src/mmg/tab_input.cpp +++ b/src/mmg/tab_input.cpp @@ -25,8 +25,9 @@ #include "wx/wxprec.h" #include "wx/wx.h" -#include "wx/notebook.h" +#include "wx/dnd.h" #include "wx/listctrl.h" +#include "wx/notebook.h" #include "wx/statline.h" #include "common.h" @@ -42,6 +43,22 @@ wxArrayString sorted_iso_codes; wxArrayString sorted_charsets; bool title_was_present = false; +class input_drop_target_c: public wxFileDropTarget { +private: + tab_input *owner; +public: + input_drop_target_c(tab_input *n_owner): + owner(n_owner) {}; + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &files) { + int i; + + for (i = 0; i < files.Count(); i++) + owner->add_file(files[i]); + + return true; + } +}; + tab_input::tab_input(wxWindow *parent): wxPanel(parent, -1, wxDefaultPosition, wxSize(100, 400), wxTAB_TRAVERSAL) { @@ -347,6 +364,8 @@ tab_input::tab_input(wxWindow *parent): value_copy_timer.SetOwner(this, ID_T_INPUTVALUES); value_copy_timer.Start(333); + + SetDropTarget(new input_drop_target_c(this)); } void @@ -474,13 +493,7 @@ from_utf8(const wxString &src) { void tab_input::on_add_file(wxCommandEvent &evt) { - mmg_file_t file; - wxString file_name, name, command, id, type, exact, media_files; - wxString video_track_name; - wxArrayString output, errors; - vector args, pair; - int result, pos; - unsigned int i, k; + wxString media_files; media_files = wxT("Media files (*.aac;*.ac3;*.ass;*.avi;*.dts;"); if (capabilities[wxT("FLAC")] == wxT("true")) @@ -519,171 +532,181 @@ tab_input::on_add_file(wxCommandEvent &evt) { if(dlg.ShowModal() == wxID_OK) { last_open_dir = dlg.GetDirectory(); - file_name = dlg.GetPath(); + add_file(dlg.GetPath()); + } +} - command = wxT("\"") + mkvmerge_path + wxT("\" --identify-verbose \"") + - file_name + wxT("\""); - result = wxExecute(command, output, errors); - if ((result < 0) || (result > 1)) { - name.Printf(wxT("'mkvmerge -i' failed. Return code: %d\n\n"), result); - for (i = 0; i < output.Count(); i++) - name += break_line(output[i]) + wxT("\n"); - name += wxT("\n"); - for (i = 0; i < errors.Count(); i++) - name += break_line(errors[i]) + wxT("\n"); - wxMessageBox(name, wxT("'mkvmerge -i' failed"), wxOK | wxCENTER | - wxICON_ERROR); - return; - } else if (result > 0) { - name.Printf(wxT("'mkvmerge -i' failed. Return code: %d. Errno: %d " - "(%s).\nMake sure that you've selected a mkvmerge " - "executable on the 'settings' tab."), result, errno, - wxUCS(strerror(errno))); - wxMessageBox(name, wxT("'mkvmerge -i' failed"), wxOK | wxCENTER | - wxICON_ERROR); - return; - } +void +tab_input::add_file(const wxString &file_name) { + mmg_file_t file; + wxString name, command, id, type, exact, video_track_name; + wxArrayString output, errors; + vector args, pair; + int result, pos; + unsigned int i, k; - memset(&file, 0, sizeof(mmg_file_t)); - file.tracks = new vector; - file.title = new wxString; + command = wxT("\"") + mkvmerge_path + wxT("\" --identify-verbose \"") + + file_name + wxT("\""); + result = wxExecute(command, output, errors); + if ((result < 0) || (result > 1)) { + name.Printf(wxT("'mkvmerge -i' failed. Return code: %d\n\n"), result); + for (i = 0; i < output.Count(); i++) + name += break_line(output[i]) + wxT("\n"); + name += wxT("\n"); + for (i = 0; i < errors.Count(); i++) + name += break_line(errors[i]) + wxT("\n"); + wxMessageBox(name, wxT("'mkvmerge -i' failed"), wxOK | wxCENTER | + wxICON_ERROR); + return; + } else if (result > 0) { + name.Printf(wxT("'mkvmerge -i' failed. Return code: %d. Errno: %d " + "(%s).\nMake sure that you've selected a mkvmerge " + "executable on the 'settings' tab."), result, errno, + wxUCS(strerror(errno))); + wxMessageBox(name, wxT("'mkvmerge -i' failed"), wxOK | wxCENTER | + wxICON_ERROR); + return; + } - for (i = 0; i < output.Count(); i++) { - if (output[i].Find(wxT("Track")) == 0) { - wxString info; - mmg_track_t track; + memset(&file, 0, sizeof(mmg_file_t)); + file.tracks = new vector; + file.title = new wxString; - memset(&track, 0, sizeof(mmg_track_t)); - id = output[i].AfterFirst(wxT(' ')).AfterFirst(wxT(' ')). - BeforeFirst(wxT(':')); - type = output[i].AfterFirst(wxT(':')).BeforeFirst(wxT('(')).Mid(1). - RemoveLast(); - exact = output[i].AfterFirst(wxT('(')).BeforeFirst(wxT(')')); - info = output[i].AfterFirst(wxT('[')).BeforeLast(wxT(']')); - if (type == wxT("audio")) - track.type = 'a'; - else if (type == wxT("video")) - track.type = 'v'; - else if (type == wxT("subtitles")) - track.type = 's'; - else - track.type = '?'; - parse_int(wxMB(id), track.id); - track.ctype = new wxString(exact); - track.enabled = true; - track.language = new wxString(wxT("none")); - track.sub_charset = new wxString(wxT("default")); - track.cues = new wxString(wxT("default")); - track.track_name = new wxString(wxT("")); - track.delay = new wxString(wxT("")); - track.stretch = new wxString(wxT("")); - track.tags = new wxString(wxT("")); - track.aspect_ratio = new wxString(wxT("")); - track.dwidth = new wxString(wxT("")); - track.dheight = new wxString(wxT("")); - track.fourcc = new wxString(wxT("")); - track.compression = new wxString(wxT("")); - track.timecodes = new wxString(wxT("")); + for (i = 0; i < output.Count(); i++) { + if (output[i].Find(wxT("Track")) == 0) { + wxString info; + mmg_track_t track; - if (info.length() > 0) { - args = split(info, wxU(" ")); - for (k = 0; k < args.size(); k++) { - pair = split(args[k], wxU(":"), 2); - if (pair.size() != 2) - continue; - if (pair[0] == wxT("track_name")) { - *track.track_name = from_utf8(unescape(pair[1])); - track.track_name_was_present = true; - } else if (pair[0] == wxT("language")) - *track.language = unescape(pair[1]); - else if (pair[0] == wxT("display_dimensions")) { - vector dims; - int64_t width, height; + memset(&track, 0, sizeof(mmg_track_t)); + id = output[i].AfterFirst(wxT(' ')).AfterFirst(wxT(' ')). + BeforeFirst(wxT(':')); + type = output[i].AfterFirst(wxT(':')).BeforeFirst(wxT('(')).Mid(1). + RemoveLast(); + exact = output[i].AfterFirst(wxT('(')).BeforeFirst(wxT(')')); + info = output[i].AfterFirst(wxT('[')).BeforeLast(wxT(']')); + if (type == wxT("audio")) + track.type = 'a'; + else if (type == wxT("video")) + track.type = 'v'; + else if (type == wxT("subtitles")) + track.type = 's'; + else + track.type = '?'; + parse_int(wxMB(id), track.id); + track.ctype = new wxString(exact); + track.enabled = true; + track.language = new wxString(wxT("none")); + track.sub_charset = new wxString(wxT("default")); + track.cues = new wxString(wxT("default")); + track.track_name = new wxString(wxT("")); + track.delay = new wxString(wxT("")); + track.stretch = new wxString(wxT("")); + track.tags = new wxString(wxT("")); + track.aspect_ratio = new wxString(wxT("")); + track.dwidth = new wxString(wxT("")); + track.dheight = new wxString(wxT("")); + track.fourcc = new wxString(wxT("")); + track.compression = new wxString(wxT("")); + track.timecodes = new wxString(wxT("")); - dims = split(pair[1], wxU("x")); - if ((dims.size() == 2) && parse_int(wxMB(dims[0]), width) && - parse_int(wxMB(dims[1]), height)) { - track.dwidth->Printf(wxT("%d"), (int)width); - track.dheight->Printf(wxT("%d"), (int)height); - track.display_dimensions_selected = true; - } - } - } - } + if (info.length() > 0) { + args = split(info, wxU(" ")); + for (k = 0; k < args.size(); k++) { + pair = split(args[k], wxU(":"), 2); + if (pair.size() != 2) + continue; + if (pair[0] == wxT("track_name")) { + *track.track_name = from_utf8(unescape(pair[1])); + track.track_name_was_present = true; + } else if (pair[0] == wxT("language")) + *track.language = unescape(pair[1]); + else if (pair[0] == wxT("display_dimensions")) { + vector dims; + int64_t width, height; - if ((track.type == 'v') && (track.track_name->length() > 0)) - video_track_name = *track.track_name; - - file.tracks->push_back(track); - - } else if ((pos = output[i].Find(wxT("container:"))) > 0) { - wxString container, info; - - container = output[i].Mid(pos + 11).BeforeFirst(wxT(' ')); - info = output[i].Mid(pos + 11).AfterFirst(wxT('[')). - BeforeLast(wxT(']')); - if (container == wxT("AAC")) - file.container = TYPEAAC; - else if (container == wxT("AC3")) - file.container = TYPEAC3; - else if (container == wxT("AVI")) - file.container = TYPEAVI; - else if (container == wxT("DTS")) - file.container = TYPEDTS; - else if (container == wxT("Matroska")) - file.container = TYPEMATROSKA; - else if (container == wxT("MP2/MP3")) - file.container = TYPEMP3; - else if (container == wxT("Ogg/OGM")) - file.container = TYPEOGM; - else if (container == wxT("Quicktime/MP4")) - file.container = TYPEQTMP4; - else if (container == wxT("RealMedia")) - file.container = TYPEREAL; - else if (container == wxT("SRT")) - file.container = TYPESRT; - else if (container == wxT("SSA/ASS")) - file.container = TYPESSA; - else if (container == wxT("VobSub")) - file.container = TYPEVOBSUB; - else if (container == wxT("WAV")) - file.container = TYPEWAV; - else - file.container = TYPEUNKNOWN; - - if (info.length() > 0) { - args = split(info, wxU(" ")); - for (k = 0; k < args.size(); k++) { - pair = split(args[k], wxU(":"), 2); - if ((pair.size() == 2) && (pair[0] == wxT("title"))) { - *file.title = from_utf8(unescape(pair[1])); - title_was_present = true; + dims = split(pair[1], wxU("x")); + if ((dims.size() == 2) && parse_int(wxMB(dims[0]), width) && + parse_int(wxMB(dims[1]), height)) { + track.dwidth->Printf(wxT("%d"), (int)width); + track.dheight->Printf(wxT("%d"), (int)height); + track.display_dimensions_selected = true; } } } } + + if ((track.type == 'v') && (track.track_name->length() > 0)) + video_track_name = *track.track_name; + + file.tracks->push_back(track); + + } else if ((pos = output[i].Find(wxT("container:"))) > 0) { + wxString container, info; + + container = output[i].Mid(pos + 11).BeforeFirst(wxT(' ')); + info = output[i].Mid(pos + 11).AfterFirst(wxT('[')). + BeforeLast(wxT(']')); + if (container == wxT("AAC")) + file.container = TYPEAAC; + else if (container == wxT("AC3")) + file.container = TYPEAC3; + else if (container == wxT("AVI")) + file.container = TYPEAVI; + else if (container == wxT("DTS")) + file.container = TYPEDTS; + else if (container == wxT("Matroska")) + file.container = TYPEMATROSKA; + else if (container == wxT("MP2/MP3")) + file.container = TYPEMP3; + else if (container == wxT("Ogg/OGM")) + file.container = TYPEOGM; + else if (container == wxT("Quicktime/MP4")) + file.container = TYPEQTMP4; + else if (container == wxT("RealMedia")) + file.container = TYPEREAL; + else if (container == wxT("SRT")) + file.container = TYPESRT; + else if (container == wxT("SSA/ASS")) + file.container = TYPESSA; + else if (container == wxT("VobSub")) + file.container = TYPEVOBSUB; + else if (container == wxT("WAV")) + file.container = TYPEWAV; + else + file.container = TYPEUNKNOWN; + + if (info.length() > 0) { + args = split(info, wxU(" ")); + for (k = 0; k < args.size(); k++) { + pair = split(args[k], wxU(":"), 2); + if ((pair.size() == 2) && (pair[0] == wxT("title"))) { + *file.title = from_utf8(unescape(pair[1])); + title_was_present = true; + } + } + } } - - if (file.tracks->size() == 0) { - delete file.tracks; - wxMessageBox(wxT("The input file '") + dlg.GetPath() + - wxT("' does not contain any tracks."), - wxT("No tracks found")); - return; - } - - name = dlg.GetFilename(); - name += wxT(" (") + last_open_dir + wxT(")"); - lb_input_files->Append(name); - - file.file_name = new wxString(dlg.GetPath()); - mdlg->set_title_maybe(*file.title); - if ((file.container == TYPEOGM) && - (video_track_name.length() > 0)) - mdlg->set_title_maybe(video_track_name); - mdlg->set_output_maybe(*file.file_name); - files.push_back(file); } + + if (file.tracks->size() == 0) { + delete file.tracks; + wxMessageBox(wxT("The input file '") + file_name + + wxT("' does not contain any tracks."), + wxT("No tracks found")); + return; + } + + name = file_name.AfterLast(wxT(PSEP)); + name += wxT(" (") + file_name.BeforeLast(wxT(PSEP)) + wxT(")"); + lb_input_files->Append(name); + + file.file_name = new wxString(file_name); + mdlg->set_title_maybe(*file.title); + if ((file.container == TYPEOGM) && + (video_track_name.length() > 0)) + mdlg->set_title_maybe(video_track_name); + mdlg->set_output_maybe(*file.file_name); + files.push_back(file); } void diff --git a/src/mmg/tab_input.h b/src/mmg/tab_input.h index 644e26ab8..025837ad6 100644 --- a/src/mmg/tab_input.h +++ b/src/mmg/tab_input.h @@ -83,6 +83,7 @@ public: tab_input(wxWindow *parent); void on_add_file(wxCommandEvent &evt); + void add_file(const wxString &file_name); void on_remove_file(wxCommandEvent &evt); void on_move_file_up(wxCommandEvent &evt); void on_move_file_down(wxCommandEvent &evt);