Example #1
0
bool
mmg_app::OnInit() {
#ifdef __WXMAC__
  ProcessSerialNumber PSN;
  GetCurrentProcess(&PSN);
  TransformProcessType(&PSN, kProcessTransformToForegroundApplication);
#endif

  wxImage::AddHandler(new wxPNGHandler);

  mtx_common_init("mmg");

  wxConfigBase *cfg;
  uint32_t i;
  wxString k, v;
  int index;

  prepare_mmg_data_folder();

#if defined(SYS_WINDOWS)
  cfg = new wxConfig(wxT("mkvmergeGUI"));
#else
  cfg = new wxFileConfig(wxT("mkvmergeGUI"), wxEmptyString, get_config_file_name());
#endif
  cfg->SetExpandEnvVars(false);
  wxConfigBase::Set(cfg);

  init_ui_locale();

  cfg->SetPath(wxT("/GUI"));
  cfg->Read(wxT("last_directory"), &last_open_dir, wxEmptyString);
  for (i = 0; i < 4; i++) {
    k.Printf(wxT("last_settings %u"), i);
    if (cfg->Read(k, &v) && wxFile::Exists(v))
      last_settings.push_back(v);
    k.Printf(wxT("last_chapters %u"), i);
    if (cfg->Read(k, &v) && wxFile::Exists(v))
      last_chapters.push_back(v);
  }
  cfg->SetPath(wxT("/chapter_editor"));
  cfg->Read(wxT("default_language"), &k, wxT("und"));
  g_default_chapter_language = wxMB(k);
  index = map_to_iso639_2_code(g_default_chapter_language.c_str());
  if (-1 == index)
    g_default_chapter_language = "und";
  else
    g_default_chapter_language = iso639_languages[index].iso639_2_code;
  if (cfg->Read(wxT("default_country"), &k) && (0 < k.length()))
    g_default_chapter_country = wxMB(k);
  if (!is_valid_cctld(g_default_chapter_country.c_str()))
    g_default_chapter_country = "";

  app = this;
  mdlg = new mmg_dialog();
  mdlg->Show(true);

  handle_command_line_arguments();

  return true;
}
Example #2
0
void
mmg_app::init_ui_locale() {
  std::string locale;

#if defined(HAVE_LIBINTL_H)
  static bool s_first_init = true;
  wxString w_locale;

  translation_c::initialize_available_translations();

  wxConfigBase *cfg = wxConfigBase::Get();
  cfg->SetPath(wxT("/GUI"));
  if (cfg->Read(wxT("ui_locale"), &w_locale)) {
    locale = wxMB(w_locale);
    if (-1 == translation_c::look_up_translation(locale))
      locale = "";
  }

  if (locale.empty()) {
    locale = translation_c::get_default_ui_locale();
    if (-1 == translation_c::look_up_translation(locale))
      locale = "";
  }

  m_ui_locale = locale;

  if (s_first_init) {
    std::string installation_path = get_installation_path();
    if (!installation_path.empty())
      wxLocale::AddCatalogLookupPathPrefix(wxU(installation_path + "/locale"));
  }

  const wxLanguageInfo *lang_info = wxLocale::FindLanguageInfo(wxU(m_ui_locale));
  if (s_first_init) {
    if (lang_info && m_locale.Init(lang_info->Language)) {
      m_locale.AddCatalog(wxU("wxstd"));
#ifdef SYS_WINDOWS
      m_locale.AddCatalog(wxU("wxmsw"));
#endif // SYS_WINDOWS
    }

    delete wxLog::SetActiveTarget(nullptr);
    s_first_init = false;
  }

#endif  // HAVE_LIBINTL_H

  init_locales(locale);
}
Example #3
0
void
tab_attachments::add_attachment(const wxString &file_name) {
  mmg_attachment_cptr attch = mmg_attachment_cptr(new mmg_attachment_t);

  attch->file_name  = file_name;
  wxString name     = file_name.AfterLast(wxT(PSEP));
  wxString ext      = name.AfterLast(wxT('.'));
  name             += wxString(wxT(" (")) + file_name.BeforeLast(wxT(PSEP)) + wxT(")");
  lb_attachments->Append(name);

  if (ext.Length() > 0)
    attch->mime_type = wxU(guess_mime_type(wxMB(file_name), true));
  attch->style       = 0;
  attch->stored_name = derive_stored_name_from_file_name(attch->file_name);

  attachments.push_back(attch);
}
Example #4
0
void
mmg_app::handle_command_line_arguments() {
  if (1 >= app->argc)
    return;

  std::vector<std::string> args;
  size_t i;
  for (i = 1; static_cast<size_t>(app->argc) > i; ++i)
    args.push_back(wxMB(wxString(app->argv[i])));

  handle_common_cli_args(args, "");

  if (args.empty())
    return;

  std::vector<wxString> wargs;
  for (i = 0; args.size() > i; ++i)
    wargs.push_back(wxU(args[i]));

  if (wargs[0] == wxT("--edit-headers")) {
    if (wargs.size() == 1)
      wxMessageBox(Z("Missing file name after for the option '--edit-headers'."), Z("Missing file name"), wxOK | wxCENTER | wxICON_ERROR);
    else
      mdlg->create_header_editor_window(wargs[1]);

    return;
  }

  for (auto &file : wargs)
    if (!wxFileExists(file) || wxDirExists(file))
      wxMessageBox(wxString::Format(Z("The file '%s' does not exist."), file.c_str()), Z("Error loading settings"), wxOK | wxCENTER | wxICON_ERROR);
    else {
#ifdef SYS_WINDOWS
      if ((file.Length() > 3) && (file.c_str()[1] != wxT(':')) && (file.c_str()[0] != wxT('\\')))
        file = wxGetCwd() + wxT("\\") + file;
#else
      if ((file.Length() > 0) && (file.c_str()[0] != wxT('/')))
        file = wxGetCwd() + wxT("/") + file;
#endif

      if (wxFileName(file).GetExt() == wxU("mmg"))
        mdlg->load(file);
      else
        mdlg->input_page->add_file(file, false);
    }
}
Example #5
0
void
mmg_app::prepare_mmg_data_folder() {
  // The 'jobs' folder is part of the application data
  // folder. Therefore both directories will be creatd.
  // 'prepare_path' treats the last part of the path as a file name;
  // therefore append a dummy file name so that all directory parts
  // will be created.
  mm_file_io_c::prepare_path(wxMB(get_jobs_folder() + wxT("/dummy")));

#if !defined(SYS_WINDOWS)
  // Migrate the config file from its old location ~/.mkvmergeGUI to
  // the new location ~/.mkvtoolnix/config
  wxString old_config_name;
  wxGetEnv(wxT("HOME"), &old_config_name);
  old_config_name += wxT("/.mkvmergeGUI");

  if (wxFileExists(old_config_name))
    wxRenameFile(old_config_name, get_config_file_name());
#endif
}
Example #6
0
void
mmg_options_t::init_popular_languages(const wxString &list) {
  size_t i;

  popular_languages.clear();

  if (!list.IsEmpty()) {
    std::vector<wxString> codes = split(list, wxU(" "));
    for (i = 0; codes.size() > i; ++i)
      if (is_valid_iso639_2_code(wxMB(codes[i])))
        popular_languages.Add(codes[i]);
  }

  if (popular_languages.IsEmpty()) {
    std::map<std::string, bool> codes_found;
    for (auto lang : g_iso639_languages)
      if (!codes_found[lang.iso639_2_code] && is_popular_language_code(lang.iso639_2_code)) {
        popular_languages.Add(wxU(lang.iso639_2_code));
        codes_found[lang.iso639_2_code] = true;
      }
  }

  popular_languages.Sort();
}
Example #7
0
bool
header_editor_frame_c::open_file(wxFileName file_name) {
    if (!kax_analyzer_c::probe(wxMB(file_name.GetFullPath()))) {
        wxMessageBox(Z("The file you tried to open is not a Matroska file."), Z("Wrong file selected"), wxOK | wxCENTER | wxICON_ERROR);
        return false;
    }

    m_e_segment_info.clear();
    m_e_tracks.clear();

    m_analyzer = wx_kax_analyzer_cptr(new wx_kax_analyzer_c(this, wxMB(file_name.GetFullPath())));

    if (!m_analyzer->process(kax_analyzer_c::parse_mode_fast)) {
        wxMessageBox(Z("This file could not be opened or parsed."), Z("File parsing failed"), wxOK | wxCENTER | wxICON_ERROR);
        m_analyzer.clear();

        return false;
    }

    m_file_name = file_name;
    m_file_name.GetTimes(NULL, &m_file_mtime, NULL);

    set_window_title();

    m_ignore_tree_selection_changes = true;

    enable_menu_entries();

    m_bs_main->Hide(m_tc_tree);

    size_t i;
    for (i = 0; m_pages.size() > i; ++i)
        if (m_pages[i]->IsShown())
            m_pages[i]->Hide();

    m_tc_tree->DeleteChildren(m_root_id);
    m_bs_page->Clear();
    m_pages.clear();
    m_top_level_pages.clear();

    for (i = 0; m_analyzer->m_data.size() > i; ++i) {
        kax_analyzer_data_c *data = m_analyzer->m_data[i].get_object();
        if (data->m_id == KaxInfo::ClassInfos.GlobalId) {
            handle_segment_info(data);
            break;
        }
    }

    for (i = 0; m_analyzer->m_data.size() > i; ++i) {
        kax_analyzer_data_c *data = m_analyzer->m_data[i].get_object();
        if (data->m_id == KaxTracks::ClassInfos.GlobalId) {
            handle_tracks(data);
            break;
        }
    }

    m_analyzer->close_file();

    m_bs_main->Show(m_tc_tree);
    m_bs_main->Layout();

    last_open_dir                   = file_name.GetPath();

    m_ignore_tree_selection_changes = false;

    return true;
}
Example #8
0
mux_dialog::mux_dialog(wxWindow *parent):
    wxDialog(parent, -1, Z("mkvmerge is running"), wxDefaultPosition,
#ifdef SYS_WINDOWS
             wxSize(700, 560),
#else
             wxSize(700, 520),
#endif
             wxDEFAULT_FRAME_STYLE)
#if defined(SYS_WINDOWS)
    , pid(0)
    , m_taskbar_progress(NULL)
    , m_abort_button_changed(false)
#endif  // SYS_WINDOWS
    , m_exit_code(0)
    , m_progress(0)
{
    char c;
    std::string arg_utf8, line;
    long value;
    wxString wx_line, tmp;
    wxInputStream *out;
    wxFile *opt_file;
    uint32_t i;
    wxArrayString *arg_list;
    wxBoxSizer *siz_all, *siz_buttons, *siz_line;
    wxStaticBoxSizer *siz_status, *siz_output;

    m_window_disabler = new wxWindowDisabler(this);

    c = 0;
    siz_status = new wxStaticBoxSizer(new wxStaticBox(this, -1, Z("Status and progress")), wxVERTICAL);
    st_label = new wxStaticText(this, -1, wxEmptyString);
    st_remaining_time_label = new wxStaticText(this, -1, Z("Remaining time:"));
    st_remaining_time       = new wxStaticText(this, -1, Z("is being estimated"));
    siz_line = new wxBoxSizer(wxHORIZONTAL);
    siz_line->Add(st_label);
    siz_line->AddSpacer(5);
    siz_line->Add(st_remaining_time_label);
    siz_line->AddSpacer(5);
    siz_line->Add(st_remaining_time);
    siz_status->Add(siz_line, 0, wxGROW | wxALIGN_LEFT | wxALL, 5);
    g_progress = new wxGauge(this, -1, 100, wxDefaultPosition, wxSize(250, 15));
    siz_status->Add(g_progress, 1, wxALL | wxGROW, 5);

    siz_output = new wxStaticBoxSizer(new wxStaticBox(this, -1, Z("Output")), wxVERTICAL);
    siz_output->Add(new wxStaticText(this, -1, Z("mkvmerge output:")), 0, wxALIGN_LEFT | wxALL, 5);
    tc_output = new wxTextCtrl(this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_BESTWRAP | wxTE_MULTILINE);
    siz_output->Add(tc_output, 2, wxGROW | wxALL, 5);
    siz_output->Add(new wxStaticText(this, -1, Z("Warnings:")), 0, wxALIGN_LEFT | wxALL, 5);
    tc_warnings = new wxTextCtrl(this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_BESTWRAP | wxTE_MULTILINE);
    siz_output->Add(tc_warnings, 1, wxGROW | wxALL, 5);
    siz_output->Add(new wxStaticText(this, -1, Z("Errors:")), 0, wxALIGN_LEFT | wxALL, 5);
    tc_errors = new wxTextCtrl(this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_BESTWRAP | wxTE_MULTILINE);
    siz_output->Add(tc_errors, 1, wxGROW | wxALL, 5);

    siz_buttons = new wxBoxSizer(wxHORIZONTAL);
    siz_buttons->AddStretchSpacer();
    b_ok = new wxButton(this, ID_B_MUX_OK, Z("Ok"));
    b_ok->Enable(false);
    siz_buttons->Add(b_ok, 0, wxGROW);
    siz_buttons->AddStretchSpacer();
    b_abort = new wxButton(this, ID_B_MUX_ABORT, Z("Abort"));
    siz_buttons->Add(b_abort, 0, wxGROW);
    siz_buttons->AddStretchSpacer();
    b_save_log = new wxButton(this, ID_B_MUX_SAVELOG, Z("Save log"));
    siz_buttons->Add(b_save_log, 0, wxGROW);
    siz_buttons->AddStretchSpacer();

    siz_all = new wxBoxSizer(wxVERTICAL);
    siz_all->Add(siz_status, 0, wxGROW | wxALL, 5);
    siz_all->Add(siz_output, 1, wxGROW | wxALL, 5);
    siz_all->Add(siz_buttons, 0, wxGROW | wxALL, 10);
    SetSizer(siz_all);

    update_window(Z("Muxing in progress."));
    Show(true);

    process = new mux_process(this);

    opt_file_name.Printf(wxT("%smmg-mkvmerge-options-%d-%d"), get_temp_dir().c_str(), (int)wxGetProcessId(), (int)wxGetUTCTime());
    try {
        const unsigned char utf8_bom[3] = {0xef, 0xbb, 0xbf};
        opt_file = new wxFile(opt_file_name, wxFile::write);
        opt_file->Write(utf8_bom, 3);
    } catch (...) {
        wxString error;
        error.Printf(Z("Could not create a temporary file for mkvmerge's command line option called '%s' (error code %d, %s)."), opt_file_name.c_str(), errno, wxUCS(strerror(errno)));
        wxMessageBox(error, Z("File creation failed"), wxOK | wxCENTER | wxICON_ERROR);
        throw 0;
    }
    arg_list = &static_cast<mmg_dialog *>(parent)->get_command_line_args();
    for (i = 1; i < arg_list->Count(); i++) {
        if ((*arg_list)[i].Length() == 0)
            opt_file->Write(wxT("#EMPTY#"));
        else {
            arg_utf8 = escape(wxMB((*arg_list)[i]));
            opt_file->Write(arg_utf8.c_str(), arg_utf8.length());
        }
        opt_file->Write(wxT("\n"));
    }
    delete opt_file;

#if defined(SYS_WINDOWS)
    if (get_windows_version() >= WINDOWS_VERSION_7) {
        m_taskbar_progress = new taskbar_progress_c(mdlg);
        m_taskbar_progress->set_state(TBPF_NORMAL);
        m_taskbar_progress->set_value(0, 100);
    }
#endif  // SYS_WINDOWS

    m_start_time                 = get_current_time_millis();
    m_next_remaining_time_update = m_start_time + 8000;

    wxString command_line = wxString::Format(wxT("\"%s\" \"@%s\""), (*arg_list)[0].c_str(), opt_file_name.c_str());
    pid = wxExecute(command_line, wxEXEC_ASYNC, process);
    if (0 == pid) {
        wxLogError(wxT("Execution of '%s' failed."), command_line.c_str());
        done(2);
        return;
    }
    out = process->GetInputStream();

    line = "";
    log = wxEmptyString;
    while (1) {
        while (app->Pending())
            app->Dispatch();

        if (!out->CanRead() && !out->Eof()) {
            wxMilliSleep(5);
            continue;
        }

        if (!out->Eof())
            c = out->GetC();
        else
            c = '\n';

        if ((c == '\n') || (c == '\r') || out->Eof()) {
            wx_line = wxU(line);
            log += wx_line;
            if (c != '\r')
                log += wxT("\n");
            if (wx_line.Find(Z("Warning:")) == 0)
                tc_warnings->AppendText(wx_line + wxT("\n"));
            else if (wx_line.Find(Z("Error:")) == 0)
                tc_errors->AppendText(wx_line + wxT("\n"));
            else if (wx_line.Find(Z("Progress")) == 0) {
                if (wx_line.Find(wxT("%")) != 0) {
                    wx_line.Remove(wx_line.Find(wxT("%")));
                    tmp = wx_line.AfterLast(wxT(' '));
                    tmp.ToLong(&value);
                    if ((value >= 0) && (value <= 100))
                        update_gauge(value);
                }
            } else if (wx_line.Length() > 0)
                tc_output->AppendText(wx_line + wxT("\n"));
            line = "";

            update_remaining_time();

        } else if ((unsigned char)c != 0xff)
            line += c;

        if (out->Eof())
            break;
    }
}
Example #9
0
void
job_run_dialog::start_next_job() {
  t_update->Stop();

  ++current_job;

  if ((static_cast<int>(jobs_to_start.size()) <= current_job) || cb_abort_after_current->IsChecked() || abort) {
    if (   abort
        || (   cb_abort_after_current->IsChecked()
            && (current_job < static_cast<int>(jobs_to_start.size()))))
      add_to_log(wxString::Format(Z("Aborted processing on %s"), format_date_time(wxGetUTCTime()).c_str()));
    else
      add_to_log(wxString::Format(Z("Finished processing on %s"), format_date_time(wxGetUTCTime()).c_str()));

    b_abort->Enable(false);
    cb_abort_after_current->Enable(false);
    b_ok->Enable(true);
    b_ok->SetFocus();
    SetTitle(Z("mkvmerge has finished"));

    st_remaining_time->SetLabel(wxT("---"));
    st_remaining_time_total->SetLabel(wxT("---"));

#if defined(SYS_WINDOWS)
    if (m_taskbar_progress)
      m_taskbar_progress->set_state(TBPF_NOPROGRESS);
#endif

    return;
  }

  m_start_time                 = mtx::sys::get_current_time_millis();
  m_next_remaining_time_update = m_start_time + 8000;
  st_remaining_time->SetLabel(Z("is being estimated"));

#if defined(SYS_WINDOWS)
  if (m_taskbar_progress) {
    m_taskbar_progress->set_state(TBPF_NORMAL);
    m_taskbar_progress->set_value(current_job * 100, jobs_to_start.size() * 100);
  }
#endif

  int ndx = jobs_to_start[current_job];
  st_jobs->SetLabel(wxString::Format(Z("Processing job %d/%d"), current_job + 1, (int)jobs_to_start.size()));
  st_current->SetLabel(wxString::Format(Z("Current job ID %d:"), jobs[ndx].id));

  mdlg->load(wxString::Format(wxT("%s/%d.mmg"), app->get_jobs_folder().c_str(), jobs[ndx].id), true);

  opt_file_name = get_temp_settings_file_name();

  wxFile *opt_file;
  try {
    opt_file = new wxFile(opt_file_name, wxFile::write);
  } catch (...) {
    jobs[ndx].log->Printf(Z("Could not create a temporary file for mkvmerge's command line option called '%s' (error code %d, %s)."),
                          opt_file_name.c_str(), errno, wxUCS(strerror(errno)));
    jobs[ndx].status = JOBS_FAILED;
    mdlg->save_job_queue();
    if (process) {
      delete process;
      process = nullptr;
    }
    start_next_job();
    return;
  }

  static const unsigned char utf8_bom[3] = {0xef, 0xbb, 0xbf};
  opt_file->Write(utf8_bom, 3);
  opt_file->Write(wxT("--gui-mode\n"));

  mdlg->update_command_line();
  wxArrayString *arg_list = &mdlg->get_command_line_args();

  size_t i;
  for (i = 1; i < arg_list->Count(); i++) {
    if ((*arg_list)[i].Length() == 0)
      opt_file->Write(wxT("#EMPTY#"));
    else {
      std::string arg_utf8 = escape(wxMB((*arg_list)[i]));
      opt_file->Write(arg_utf8.c_str(), arg_utf8.length());
    }
    opt_file->Write(wxT("\n"));
  }
  delete opt_file;

  process = new wxProcess(this, 1);
  process->Redirect();
  wxString command_line = wxString::Format(wxT("\"%s\" \"@%s\""), (*arg_list)[0].c_str(), opt_file_name.c_str());
  pid = wxExecute(command_line, wxEXEC_ASYNC, process);
  if (0 == pid) {
    wxLogError(wxT("Execution of '%s' failed."), command_line.c_str());
    return;
  }
  out = process->GetInputStream();

  *jobs[ndx].log        = wxEmptyString;
  jobs[ndx].started_on  = wxGetUTCTime();
  jobs[ndx].finished_on = -1;

  add_to_log(wxString::Format(Z("Starting job ID %d (%s) on %s"), jobs[ndx].id, jobs[ndx].description->c_str(), format_date_time(jobs[ndx].started_on).c_str()));

  t_update->Start(100);
}