Пример #1
0
void
tab_input_general::setup_languages() {
  size_t i;

  sorted_iso_codes.Clear();
  sorted_iso_codes.Add(Z("und (Undetermined)"));
  sorted_iso_codes.Add(Z("---common---"));

  std::map<wxString, bool> is_popular;
  for (i = 0; i < mdlg->options.popular_languages.Count(); ++i)
    is_popular[ mdlg->options.popular_languages[i] ] = true;

  for (auto &lang : iso639_languages) {
    wxString code = wxU(lang.iso639_2_code);
    if (!is_popular[code])
      continue;

    sorted_iso_codes.Add(wxString::Format(wxT("%s (%s)"), code.c_str(), wxUCS(lang.english_name)));
    is_popular[code] = false;
  }

  sorted_iso_codes.Add(Z("---all---"));

  wxArrayString temp;
  for (auto &lang : iso639_languages)
    temp.Add(wxString::Format(wxT("%s (%s)"), wxUCS(lang.iso639_2_code), wxUCS(lang.english_name)));
  temp.Sort();

  for (i = 0; temp.Count() > i; ++i)
    if ((0 == i) || (temp[i - 1].Lower() != temp[i].Lower()))
      sorted_iso_codes.Add(temp[i]);

  size_t selection = cob_language->GetSelection();
  cob_language->Clear();
  append_combobox_items(cob_language, sorted_iso_codes);
  cob_language->SetSelection(selection);
}
Пример #2
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;
    }
}
Пример #3
0
void
mux_dialog::run() {
  auto &arg_list = static_cast<mmg_dialog *>(GetParent())->get_command_line_args();

  opt_file_name = get_temp_settings_file_name();
  try {
    const unsigned char utf8_bom[3] = {0xef, 0xbb, 0xbf};
    wxFile opt_file{opt_file_name, wxFile::write};
    opt_file.Write(utf8_bom, 3);
    opt_file.Write(wxT("--gui-mode\n"));

    for (size_t i = 1; i < arg_list.Count(); i++) {
      if (arg_list[i].IsEmpty())
        opt_file.Write(wxT("#EMPTY#"));
      else {
        auto arg_utf8 = escape(to_utf8(arg_list[i]));
        opt_file.Write(arg_utf8.c_str(), arg_utf8.length());
      }
      opt_file.Write(wxT("\n"));
    }
  } catch (mtx::mm_io::exception &ex) {
    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(ex.error()));
    wxMessageBox(error, Z("File creation failed"), wxOK | wxCENTER | wxICON_ERROR);
    throw 0;
  }

#if defined(SYS_WINDOWS)
  if (mtx::sys::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

  update_label(Z("Muxing in progress."));

  m_start_time                 = mtx::sys::get_current_time_millis();
  m_next_remaining_time_update = m_start_time + 8000;

  m_process                    = new mux_process{this};
  m_pid                        = wxExecute(wxString::Format(wxT("\"%s\" \"@%s\""), arg_list[0].c_str(), opt_file_name.c_str()), wxEXEC_ASYNC, m_process);

  if (0 == m_pid) {
    wxCommandEvent evt(mux_process::event, mux_process::process_terminated);
    evt.SetInt(2);
    wxPostEvent(this, evt);

  } else {
    m_read_input_timer.SetOwner(this, ID_T_READ_INPUT);
    m_read_input_timer.Start(100);
  }

  ShowModal();
}
Пример #4
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);
}
Пример #5
0
optdlg_mmg_tab::optdlg_mmg_tab(wxWindow *parent,
                               mmg_options_t &options)
  : optdlg_base_tab(parent, options)
{
  // Create the controls.
  cb_autoset_output_filename = new wxCheckBox(this, ID_CB_AUTOSET_OUTPUT_FILENAME, Z("Auto-set output filename"));
  cb_autoset_output_filename->SetToolTip(TIP("If checked mmg will automatically set the output filename "
                                             "if it hasn't been set already. This happens when you add "
                                             "the first file. If unset mmg will not touch the output filename."));

  rb_odm_input_file = new wxRadioButton(this, ID_RB_ODM_INPUT_FILE, Z("Same directory as the first input file's"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
  rb_odm_previous   = new wxRadioButton(this, ID_RB_ODM_PREVIOUS, Z("Use the previous output directory"));
  rb_odm_fixed      = new wxRadioButton(this, ID_RB_ODM_FIXED, Z("Use this directory:"));

  tc_output_directory       = new wxTextCtrl(this, ID_TC_OUTPUT_DIRECTORY, m_options.output_directory);
  b_browse_output_directory = new wxButton(this, ID_B_BROWSE_OUTPUT_DIRECTORY, Z("Browse"));

  tc_output_directory->SetToolTip(TIP("If left empty then mmg will set the output file name to be in the same directory as the first file added to this job. "
                                      "Otherwise this directory will be used."));

  cb_ask_before_overwriting = new wxCheckBox(this, ID_CB_ASK_BEFORE_OVERWRITING, Z("Ask before overwriting things (files, jobs)"));
  cb_ask_before_overwriting->SetToolTip(TIP("If checked mmg will ask for "
                                            "confirmation before overwriting "
                                            "existing files, or before adding "
                                            "a new job if there's an old job "
                                            "whose description matches the "
                                            "new one."));

  cb_set_delay_from_filename = new wxCheckBox(this, ID_CB_SET_DELAY_FROM_FILENAME, Z("Set the delay input field from the file name"));
  cb_set_delay_from_filename->SetToolTip(TIP("When a file is added its name is scanned. If it contains "
                                             "the word 'DELAY' followed by a number then this number "
                                             "is automatically put into the 'delay' input field for "
                                             "any audio track found in the file."));

  cb_filenew_after_add_to_jobqueue = new wxCheckBox(this, ID_CB_NEW_AFTER_ADD_TO_JOBQUEUE, Z("Clear inputs after adding a job to the job queue"));

  cb_filenew_after_successful_mux  = new wxCheckBox(this, ID_CB_NEW_AFTER_SUCCESSFUL_MUX, Z("Clear inputs after a successful muxing run"));

  cb_on_top = new wxCheckBox(this, ID_CB_ON_TOP, Z("Always on top"));

  cb_warn_usage = new wxCheckBox(this, ID_CB_WARN_USAGE, Z("Warn about possible incorrect usage of mmg"));
  cb_warn_usage->SetToolTip(TIP("If checked mmg will warn if it thinks that "
                                "you're using it incorrectly. Such warnings "
                                "are shown at least once even if you turn "
                                "this feature off."));

  cb_disable_header_removal_compression = new wxCheckBox(this, ID_CB_DISABLE_HRC, Z("Disable header removal compression for audio and video tracks by default"));
  cb_disable_header_removal_compression->SetToolTip(TIP("If checked mmg will set the 'compression' drop down box to 'none' for all audio and video tracks by default. "
                                                        "The user can still change the compression setting afterwards."));

#if defined(HAVE_CURL_EASY_H)
  cb_check_for_updates = new wxCheckBox(this, ID_CB_CHECK_FOR_UPDATES, Z("Check online for the latest release"));
  cb_check_for_updates->SetToolTip(TIP("Check online whether or not a new release of MKVToolNix is available on the home page. "
                                       "Will only check when mmg starts and at most once a day. "
                                       "No information is transmitted to the server."));
#endif  // defined(HAVE_CURL_EASY_H)

  cb_gui_debugging = new wxCheckBox(this, ID_CB_GUI_DEBUGGING, Z("Show mmg's debug window"));
  cb_gui_debugging->SetToolTip(TIP("Shows mmg's debug window in which debug messages will appear. "
                                   "This is only useful if you're helping the author debug a problem in mmg."));

#if defined(HAVE_LIBINTL_H)
  wxStaticText *st_ui_language = new wxStaticText(this, -1, Z("Interface language:"));
  cob_ui_language = new wxMTX_COMBOBOX_TYPE(this, ID_COB_UI_LANGUAGE,  wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN | wxCB_READONLY);

  std::vector<translation_c>::iterator translation = translation_c::ms_available_translations.begin();
  wxString select_locale;
  std::vector<locale_sorter_t> sorted_entries;
  while (translation != translation_c::ms_available_translations.end()) {
    wxString curr_entry = wxU(boost::format("%1% (%2%)") % translation->m_translated_name % translation->m_english_name);
    sorted_entries.push_back(locale_sorter_t(curr_entry, translation->get_locale()));

    if (   (select_locale.IsEmpty() && (translation->m_english_name == "English"))
        || ba::iequals(app->m_ui_locale, translation->get_locale()))
      select_locale = curr_entry;

    ++translation;
  }

  wxLogMessage(wxT("Locale selection logic: select_locale %s uu_locale_lower %s translation_c::get_default_ui_locale() %s app->m_ui_locale %s"),
               select_locale.c_str(), wxUCS(app->m_ui_locale), wxUCS(translation_c::get_default_ui_locale()), wxUCS(app->m_ui_locale));

  std::sort(sorted_entries.begin(), sorted_entries.end());

  std::vector<locale_sorter_t>::iterator locale_entry = sorted_entries.begin();
  while (locale_entry != sorted_entries.end()) {
    cob_ui_language->Append(locale_entry->display_val);
    m_sorted_locales.push_back(locale_entry->locale);
    ++locale_entry;
  }
#endif  // HAVE_LIBINTL_H

  // Set the defaults.

  cb_autoset_output_filename->SetValue(m_options.autoset_output_filename);
  cb_ask_before_overwriting->SetValue(m_options.ask_before_overwriting);
  cb_on_top->SetValue(m_options.on_top);
  cb_filenew_after_add_to_jobqueue->SetValue(m_options.filenew_after_add_to_jobqueue);
  cb_filenew_after_successful_mux->SetValue(m_options.filenew_after_successful_mux);
  cb_warn_usage->SetValue(m_options.warn_usage);
  cb_gui_debugging->SetValue(m_options.gui_debugging);
  cb_set_delay_from_filename->SetValue(m_options.set_delay_from_filename);
  cb_disable_header_removal_compression->SetValue(m_options.disable_a_v_compression);

  rb_odm_input_file->SetValue(m_options.output_directory_mode == ODM_FROM_FIRST_INPUT_FILE);
  rb_odm_previous->SetValue(m_options.output_directory_mode == ODM_PREVIOUS);
  rb_odm_fixed->SetValue(m_options.output_directory_mode == ODM_FIXED);

#if defined(HAVE_LIBINTL_H)
  set_combobox_selection(cob_ui_language, select_locale);
#endif  // HAVE_LIBINTL_H

#if defined(HAVE_CURL_EASY_H)
  cb_check_for_updates->SetValue(m_options.check_for_updates);
#endif  // defined(HAVE_CURL_EASY_H)

  enable_output_filename_controls(m_options.autoset_output_filename);

  // Create the layout.

  wxBoxSizer *siz_all = new wxBoxSizer(wxVERTICAL);
  siz_all->AddSpacer(5);

  siz_all->Add(new wxStaticText(this, wxID_ANY, Z("mmg options")), 0, wxGROW | wxLEFT | wxRIGHT, 5);
  siz_all->AddSpacer(5);
  siz_all->Add(new wxStaticLine(this),                             0, wxGROW | wxLEFT | wxRIGHT, 5);
  siz_all->AddSpacer(5);

  wxBoxSizer *siz_line;
#if defined(HAVE_LIBINTL_H)
  siz_line = new wxBoxSizer(wxHORIZONTAL);
  siz_line->Add(st_ui_language, 0, wxALIGN_CENTER_VERTICAL);
  siz_line->Add(cob_ui_language, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5);

  siz_all->Add(siz_line, 0, wxGROW | wxLEFT, 5);
  siz_all->AddSpacer(5);
#endif  // HAVE_LIBINTL_H

  siz_all->Add(cb_autoset_output_filename, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

#if defined(SYS_WINDOWS)
  int left_offset = 16;
#else
  int left_offset = 24;
#endif

  siz_all->Add(rb_odm_input_file, 0, wxLEFT, left_offset);
  siz_all->AddSpacer(5);

  siz_all->Add(rb_odm_previous, 0, wxLEFT, left_offset);
  siz_all->AddSpacer(5);

  siz_line = new wxBoxSizer(wxHORIZONTAL);
  siz_line->Add(rb_odm_fixed, 0, wxALIGN_CENTER_VERTICAL, 0);
  siz_line->Add(tc_output_directory, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 5);
  siz_line->Add(b_browse_output_directory, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);

  siz_all->Add(siz_line, 0, wxGROW | wxLEFT, left_offset);
  siz_all->AddSpacer(5);

  siz_all->Add(cb_ask_before_overwriting, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

  siz_all->Add(cb_set_delay_from_filename, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

  siz_all->Add(cb_filenew_after_add_to_jobqueue, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

  siz_all->Add(cb_filenew_after_successful_mux, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

#if defined(SYS_WINDOWS)
  siz_all->Add(cb_on_top, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);
#else
  cb_on_top->Show(false);
#endif

  siz_all->Add(cb_warn_usage, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

  siz_all->Add(cb_disable_header_removal_compression, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

#if defined(HAVE_CURL_EASY_H)
  siz_all->Add(cb_check_for_updates, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);
#endif  // defined(HAVE_CURL_EASY_H)

  siz_all->Add(cb_gui_debugging, 0, wxLEFT, 5);
  siz_all->AddSpacer(5);

  SetSizer(siz_all);
}