#############################################################################
# ui.pm extension file, included from the puic-generated form implementation.
# If you wish to add, delete or rename signals or slots use
# the Perl-enabled Qt Designer which will update this file,
# preserving your code.
#
# 'SLOT:' markers are not meant to be created or edited manually.
# Please use the Slots dialog and/or the Object Browser.
#############################################################################


our $vamps_version;
our $dvdauthor_version;
our $dvdr_total_sectors = read_setting ("/Vamps/dvdr_total_sectors");
our $dvdr_spare_sectors = read_setting ("/Vamps/dvdr_spare_sectors");


sub init
{
  my $extension = VTSList (this, "VTSList");
  setExtension ($extension);
  setOrientation (&Qt::Horizontal);
  showExtension (0);
  vts_list = $extension -> vts_list ();

  menu_preview = MenuPreview (undef, "menu_preview", 0,
			      &Qt::WType_Dialog       |&Qt::WStyle_Customize|
			      &Qt::WStyle_NormalBorder|&Qt::WStyle_Title    |
			      &Qt::WStyle_ContextHelp);

  my $devs = read_list_setting ("/General/DVD_read_devices");
  device_edit -> insertStrList ($devs);

  my $tools_base_path = make_base_path ("");
  $tools_base_path =~ s|/$|| or $tools_base_path =~ s|//|/|;
  tools_base_path_edit -> setText ($tools_base_path);

  dvd_dir_validator = Qt::RegExpValidator (Qt::RegExp ("[!-~]+"),
					   this, "dvd_dir_validator");
  dvd_dir_edit -> setValidator (dvd_dir_validator);

  vol_id_validator = Qt::RegExpValidator (Qt::RegExp ("[A-Za-z0-9_]+"),
					  this, "vol_id_validator");
  vol_id_edit -> setValidator (vol_id_validator);

  settings_mapping =
  {
    "/General/language"                => \lang_edit,
    "/General/DVD_burner"              => \dvd_burner_edit,
    "/General/DVD_burn_speed"          => \dvd_burn_speed_spin_box,
    "/General/disk_change_cmd"         => \disk_change_cmd_edit,
    "/General/burn_done_cmd"           => \burn_done_cmd_edit,
    "/General/burn_failed_cmd"         => \burn_failed_cmd_edit,
    "/General/DVD_max_read_retries"    => \dvd_max_read_retries_spin_box,

    "/MediaPlayer/play_dvd"            => \play_dvd_edit,
    "/MediaPlayer/play_dvd_title"      => \play_dvd_title_edit,
    "/MediaPlayer/play_dvd_cells"      => \play_dvd_cells_edit,
    "/MediaPlayer/select_angle"        => \player_select_angle_edit,
    "/MediaPlayer/select_audio"        => \player_select_audio_edit,
    "/MediaPlayer/select_subtitle"     => \player_select_subtitle_edit,

    "/Dvdauthor/base_path"             => \base_path_edit,
    "/Dvdauthor/command"               => \dvdauthor_cmd_edit,
    "/Dvdauthor/spumux_mpv"            => \spumux_mpv_edit,
    "/Dvdauthor/spumux_mpg"            => \spumux_mpg_edit,
    "/Dvdauthor/burn_cmds"             => \burn_cmds_combo_box,

    "/Vamps/evaporate_cell"            => \evaporate_cell_edit,
    "/Vamps/select_subtitles"          => \vamps_select_subtitles_edit,
    "/Vamps/ignore_read_errors"        => \vamps_ignore_read_errors_edit,
    "/Vamps/dvdr_total_sectors"        => \dvdr_total_spin_box,
    "/Vamps/dvdr_spare_sectors"        => \dvdr_spare_spin_box,

    "/Menu/Preferences/tv_standard"    => \tv_standard_combo,
    "/Menu/Preferences/audio_es"       => \pref_audio_es_edit,
    "/Menu/Preferences/audio_language" => \pref_audio_lang_edit,
    "/Menu/Preferences/audio_format"   => \audio_format_combo,
    "/Menu/Preferences/audio_channels" => \audio_channels_combo,
    "/Menu/Preferences/ppm2mpv_ntsc"   => \ppm2mpv_ntsc_edit,
    "/Menu/Preferences/ppm2mpv_pal"    => \ppm2mpv_pal_edit,

    "/Menu/Spacing/top"                => \top_spin_box,
    "/Menu/Spacing/heading"            => \heading_spin_box,
    "/Menu/Spacing/subheading"         => \subheading_spin_box,
    "/Menu/Spacing/button"             => \button_spin_box,
    "/Menu/Spacing/bottom"             => \bottom_spin_box,

    "/Menu/Fonts/heading"              => \heading_font_setting,
    "/Menu/Fonts/subheading"           => \subheading_font_setting,
    "/Menu/Fonts/buttons"              => \buttons_font_setting,

    "/Menu/Colors/heading"             => \heading_color_setting,
    "/Menu/Colors/subheading"          => \subheading_color_setting,
    "/Menu/Colors/button_base"         => \base_color_setting,
    "/Menu/Colors/button_hilited"      => \hilited_color_setting,
    "/Menu/Colors/button_selected"     => \selected_color_setting
  };

  load_settings ();

  $vamps_version = &trUtf8 ("Failed to execute vamps");

  if (open FH, "-|", "vamps -: 2>&1")
  {
    while (<FH>)
    {
      last if (($vamps_version) = /^Vamps V(.+)$/i);
    }

    close FH;

    error (&trUtf8 ("Found Vamps version ") . $vamps_version .
    &trUtf8 (". For proper operation at\nleast version 0.99.1 is required. ") .
	   trUtf8 ("Please consider updating."))
      if ($vamps_version lt "0.99.1");
  }

  $dvdauthor_version = &trUtf8 ("Failed to execute dvdauthor");

  if (open FH, "-|", "dvdauthor -h 2>&1")
  {
    ($dvdauthor_version) = <FH> =~ /version (.+)\.$/;
    close FH;
  }

  unload (0);
}


sub destroy
{
#  print STDERR "MainWindow::destroy\n";

  menu_preview -> remove_all ();
  menu_preview      = undef;
  copy_dvd_maker    = undef;
  tools_dvd_maker   = undef;
  dvd_dir_validator = undef;
  vol_id_validator  = undef;
  fpc_mgr           = undef;
}


sub showEvent
{
  my $xl = copy_xml_label;
  my $bg = copy_button_group;
  my $lw = $xl -> width ();
  my $gw = $bg -> width ();
  my $fm = Qt::FontMetrics ($xl -> font ());
  my $tw = $fm -> boundingRect ($xl -> text ()) -> width ();
  my $m  = $fm -> width ("x") / 2;

  $bg -> setMaximumWidth ($tw + $gw - $lw + $m + 1);
}


sub closeEvent
{
#  print STDERR "MainWindow::closeEvent\n";

  my $ev = shift;

  # remove everything we created before actual dtor is called
  if (dev)
  {
    mtable_items     -> remove_all ();
    vts_list_items   -> remove_all ();
    title_list_items -> remove_all ();

    mtable_items     = undef;
    vts_list_items   = undef;
    title_list_items = undef;
  }

  close_settings ();

  $ev -> accept ();

#  print STDERR "MainWindow::closeEvent: children:\n";
#
#  foreach my $item (@{this -> children ()})
#  {
#    print STDERR $item -> name () . "\n";
#  }
}


# overload function of Qt::Dialog to prevent Esc to close window
sub keyPressEvent
{
  ;
}


sub load_or_unload # SLOT: ( bool )
{
  my $button_down = shift;

  if ($button_down)
  {
    load (device_edit -> currentText ());
  }
  else
  {
    unload (0);
  }
}


sub load # SLOT: ( const QString & )
{
  my $dev = shift;

  return if (dev);

  dev = $dev;
  load_button -> toggle () unless (load_button -> isOn ());
  load_button -> setText (&trUtf8 ("Reading DVD..."));
  load_button -> adjustSize ();
  Qt::Application::processEvents ();

  my $dvd = DvdIfoRead -> new ($dev);
  load_button -> setText (&trUtf8 ("Release DVD"));

  unless ($dvd)
  {
    dev = undef;
    load_button -> toggle ();

    error (sprintf "%s: %s", &trUtf8 ("Failed reading DVD"),
	   scalar (stat ($dev)) ? &trUtf8 ("Unknown error") : $!);

    return;
  }

  dvd              = $dvd;
  title_list_items = TitleListItems ($dev, $dvd, title_list,
				     "title_list_items", vts_list);
  vts_list_items   = title_list_items -> vts_list_items ();
  mtable_items     = MenuTableItems (menu_table, "menu_table_items",
				     title_list_items, dvd);
  fpc_mgr          = FpcMgr (this, "fpc_mgr", fpc_title_combo,
			     fpc_audio_combo, fpc_subtitle_combo,
			     title_list_items, mtable_items);

  this -> connect (vts_list_items,
		   SIGNAL "total_selected_changed(int)",
		   SLOT   "total_selected_update(int)");
  this -> connect (vts_list_items,
		   SIGNAL "title_selected_changed(int)",
		   SLOT   "title_selected_update(int)");

  my $total_sectors = vts_list_items -> nr_of_total_sectors ();
  total_size_label -> setText (sprintf "%.2f GB",
			       $total_sectors / (512. * 1024.));

  my $vol_id = $dvd -> volume_identifier ();
  dvd_title_label -> setText ($vol_id);

  my $heading = $vol_id;
  $heading    =~ s/_/ /g;
  heading_edit -> setText ($heading);

  my $dvd_dir = $vol_id;
  $dvd_dir    = unpack ("H*", $dvd -> disc_identifier ()) unless ($dvd_dir);
  $dvd_dir    =~ s/ /_/g;
  dvd_dir_edit -> setText ($dvd_dir);

  tools_base_path_edit -> setText (make_base_path ($dvd_dir));

  $dvd_dir =~ s/(.{1,29}).*/$1_QV/;
  vol_id_edit -> setText ($dvd_dir);

  my $prefix     = read_setting ("/Installation/prefix");
  my $background = read_setting ("/Menu/Preferences/background");
  $background    = replace ($background, { "p" => $prefix });
  background_edit -> setText ($background);

  vts_list_items -> size_update ();
  device_edit    -> clearFocus ();
  device_edit    -> setEnabled (0);
  selection_tab  -> setEnabled (1);
  menu_tab       -> setEnabled (1);
  copy_sub_frame -> setEnabled (1);
  tab_widget     -> setCurrentPage (0);

  my @devs = map { my @rv = ( $_ ) unless ($_ eq $dev); @rv }
                 @{read_list_setting ("/General/DVD_read_devices")};
  unshift @devs, $dev;
  @devs = @devs [0..9] if (@devs > 10);
  write_list_setting ("/General/DVD_read_devices", \@devs);
}


sub unload
{
  my $enable_copy = shift;

  load_button    -> toggle () if (load_button -> isOn ());
  load_button    -> setText (&trUtf8 ("Read DVD"));
  selection_tab  -> setEnabled (0);
  menu_tab       -> setEnabled (0);
  copy_sub_frame -> setEnabled ($enable_copy);

  return unless (dev);

  device_edit         -> setEnabled (1);
  title_size_label    -> setText ("");
  selected_size_label -> setText ("");
  total_size_label    -> setText ("");
  dvd_title_label     -> setText ("");

  mtable_items     -> remove_all ();
  vts_list_items   -> remove_all ();
  title_list_items -> remove_all ();

  fpc_mgr          = undef;
  mtable_items     = undef;
  vts_list_items   = undef;
  title_list_items = undef;
  dvd              = undef;
  dev              = undef;
}


sub showExtension # SLOT: ( bool )
{
  my $show_it = shift;

  extension_shown = $show_it;
  SUPER -> showExtension ($show_it);

  vts_button -> setText ($show_it ?
			 &trUtf8 ("Hide Video Title Sets <<") :
			 &trUtf8 ("Show Video Title Sets >>"));
}


sub tab_changed # SLOT: ( QWidget * )
{
  my $tab = shift;

  my $tab_index = tab_widget -> indexOf ($tab);

  SUPER -> showExtension ($tab_index == 0) if (extension_shown);

  if (settings_is_current)
  {
    settings_is_current = 0;

    if (compare_settings ())
    {
      if (Qt::MessageBox::information (undef, &trUtf8 ("Unsaved Settings"),
  &trUtf8 ("You have modified settings. Would you like to save your changes?"),
				       &trUtf8 ("Yes"), &trUtf8 ("No")) == 0)
      {
	save_settings ();
      }
      else
      {
	load_settings ();
      }
    }
  }

  if ($tab_index == 1)		# menu
  {
    if (dev)
    {
      my $table_items = mtable_items;

      $table_items -> end_edit_mode ();
      $table_items -> update (1);
      fpc_mgr      -> update ();
    }
  }
  elsif ($tab_index == 2)	# copy
  {
    if (dev && elapsed_label -> text () eq "0:00:00")
    {
      my $capacity = $dvdr_total_sectors - $dvdr_spare_sectors;
      my $selected = vts_list_items -> nr_of_selected_sectors ();
      my $tgt_size = $capacity;
      $tgt_size    = $selected if ($tgt_size > $selected);
      dst_space_label -> setText (sprintf "0/%d MB", $tgt_size / 512.);
    }
  }
  elsif ($tab_index == 4)	# settings
  {
    settings_is_current = 1;
  }
  elsif ($tab_index == 5)	# about
  {
    my $text = sprintf
       '<center><h1><font color="#ff0000">qVamps</font></h1></center>' .
       '<p>%s: %s<br>%s: %s<br>%s: %s<br>%s: %s<br>%s: %s<br>%s: %s<br>' .
          '%s: %s<br>%s: %s<br>%s: %s<br>%s: %s<br>%s: %s<br>%s: %s<br>' .
	  '%s: %s</p>' .
       '<p>%s<br>http://vamps.sourceforge.net/</p>' .
       '<p>%s &lt vamps-adm@sourceforge.net&gt ,<br>%s /dev/null ;-)</p>',
       &trUtf8 ("qVamps version"), $QVamps::version,
       &trUtf8 ("rc file version"), read_setting ("/General/version"),
       &trUtf8 ("Perl version"), (sprintf "%vd", $^V),
       &trUtf8 ("PerlQt version"), $Qt::VERSION,
       &trUtf8 ("Qt version"), Qt::GlobalSpace::qVersion (),
       &trUtf8 ("Vamps version"), $vamps_version,
       &trUtf8 ("dvdauthor version"), $dvdauthor_version,
       &trUtf8 ("Operating system"), $Config {"osname"},
       &trUtf8 ("Machine architecture"), $Config {"archname"},
       &trUtf8 ("User interface language"), $::lang,
       &trUtf8 ("Installation prefix"), read_setting ("/Installation/prefix"),
       &trUtf8 ("Load prefix"), $QVamps::load_prefix,
       &trUtf8 ("qVamps home"), $QVamps::qvamps_home,
       &trUtf8 ("To learn more about qVamps please visit"),
       &trUtf8 ("Please send positive feedback to"),
       &trUtf8 ("complaints go to");

    my $about_edit = about_edit;
    $about_edit -> setText ($text);
    $about_edit -> setMinimumWidth ($about_edit -> contentsWidth () + 2);
    $about_edit -> setMinimumHeight ($about_edit -> contentsHeight () + 2);

    my $color = $about_edit ->
      palette () -> color (&Qt::Palette::Active, &Qt::ColorGroup::Background);
    $about_edit -> setPaletteBackgroundColor ($color);
  }
}


sub total_selected_update # SLOT: ( int )
{
  my $total_selected = shift;

  selected_size_label -> setText (sprintf "%.2f GB",
				  $total_selected / (512. * 1024.));

  my $compression;

  if ($total_selected)
  {
    my $capacity = $dvdr_total_sectors - $dvdr_spare_sectors;
    $compression = sprintf "%d", $capacity * 100 / ($total_selected + 0.0);
    $compression = 100 if ($compression > 100);
  }
  else
  {
    $compression = 100;
  }

  vap_dialer -> setValue ($compression);
  vap_label  -> setText ("$compression%");
}


sub title_selected_update # SLOT: ( int )
{
  my $title_selected = shift;

  title_size_label -> setText (sprintf "%.2f GB",
			       $title_selected / (512. * 1024.));
}


sub copy_or_abort
{
  my $dvd_maker = copy_dvd_maker;

  if ($dvd_maker)
  {
    copy_dvd_maker = undef;

    $dvd_maker  -> try_terminate ();
    copy_button -> setEnabled (0);

    return;
  }

  my $capacity = $dvdr_total_sectors - $dvdr_spare_sectors;
  my $selected = vts_list_items -> nr_of_selected_sectors ();
  my $vap_fact = ($selected + 0.0) / $capacity;
  my $tgt_size = $capacity;
  $vap_fact = 1.0 if ($vap_fact < 1.0);
  $tgt_size = $selected if ($tgt_size > $selected);

  my $base_path = make_base_path (dvd_dir_edit -> text ());

  mkpath ($base_path);

  my $stat;
  my $mtable_items     = mtable_items;
  my $menu_box_checked = menu_check_box               -> isChecked ();
  my $fpc_box_checked  = fpc_check_box                -> isChecked ();
  my $ignore_errors    = ignore_read_errors_check_box -> isChecked ();
  my $rm_temps         = !keep_temps_check_box        -> isChecked ();
  my $dump_mode        = radio_button_4               -> isChecked ();
  my $add_unseen       = $menu_box_checked && !$mtable_items -> nr_of_items ();
  my $dst_dir          = $dump_mode ? "mpegs" : "image/VIDEO_TS";
  $mtable_items -> update ($add_unseen);
  fpc_mgr       -> update ();

  $dvd_maker     = DvdMaker (copy_log_viewer, elapsed_label,
			     dst_space_label, $tgt_size / 512.,
			     "$base_path/$dst_dir", this, "copy_dvd_maker");
  copy_dvd_maker = $dvd_maker;

  my $button      = copy_button;
  my $button_text = $button -> text ();
  $button     -> setText (&trUtf8 ("Abort"));
  load_button -> setEnabled (0);

  unless ($dump_mode)
  {
    my $xml_writer = XmlWriter (dev, dvd, title_list_items, vts_list_items,
				fpc_mgr, $mtable_items, $vap_fact, $base_path,
				$ignore_errors, this, "xml_writer");

    $stat   = $xml_writer -> write ($fpc_box_checked, $menu_box_checked);
    $stat ||= $xml_writer -> close ();
    undef $xml_writer;

    return if ($stat);

    my $menu_preview = menu_preview;
    $menu_preview -> generate (this);

    my $make_menu = $menu_box_checked && $mtable_items -> nr_of_items ();

    if ($make_menu)
    {
      my $menu_writer = MenuWriter (mtable_items, $menu_preview,
				    $base_path, this, "menu_writer");

      $stat   = $menu_writer -> write_xml ();
      $stat ||= $menu_writer -> close ();
      $stat ||= $menu_writer -> write_images ();

      return if ($stat);
    }

    my $disk_change = disk_change_check_box -> isChecked ();
    my $vol_id      = vol_id_edit -> text ();

    $stat = $dvd_maker -> write_script ($base_path, $make_menu,
					$disk_change, $rm_temps, $vol_id);

    if (!$stat &&
	(radio_button_2 -> isChecked () || radio_button_3 -> isChecked ()))
    {
      $stat   = $dvd_maker -> run_spumux ($base_path, $make_menu, $rm_temps);
      $stat ||= $dvd_maker -> run_dvdauthor ($base_path, $rm_temps);

      $stat ||= !open FH, ">", "$base_path/volume_id.txt";
      $stat ||= !print FH "$vol_id\n";
      $stat ||= !close FH;

      if (!$stat && radio_button_3 -> isChecked ())
      {
	if ($disk_change)
	{
	  unload (1);

	  my $cmd = read_setting ("/General/disk_change_cmd");
	  system ("$cmd &") if ($cmd);

	  info (&trUtf8 ("Please insert blank DVD into burner"));
	}

	$stat = $dvd_maker -> run_burn_cmd ($base_path, $vol_id);

	copy_sub_frame -> setEnabled (0) if ($disk_change);
      }

      if ($stat)
      {
	my $cmd = read_setting ("/General/burn_failed_cmd");
	system ("$cmd &") if ($cmd);
      }
      else
      {
	my $cmd = read_setting ("/General/burn_done_cmd");
	system ("$cmd &") if ($cmd);
      }
    }
  }
  else
  {
    # create MPEG files only
    my $mpg_dumper = MpgDumper (dev, dvd, $dvd_maker, title_list_items,
				vts_list_items, $vap_fact, $base_path,
				$ignore_errors, this, "mpg_dumper");
    $stat = $mpg_dumper -> run ($rm_temps);
  }

  undef $dvd_maker;

  $button     -> setText ($button_text);
  $button     -> setEnabled (1);
  load_button -> setEnabled (1);

  if (copy_dvd_maker)
  {
    copy_dvd_maker = undef;

    if ($stat)
    {
      error ('<font color="#ff0000">' . &trUtf8 ("Copy failed!") . '</font> ' .
	     &trUtf8 ("You may find further information in the output log."));
    }
    else
    {
      info (&trUtf8 ("Copy successfully completed"));
    }
  }
  else
  {
    info (&trUtf8 ("Copy aborted!"));
  }
}


sub tools_run_dvdauthor_or_abort
{
  my $dvd_maker = tools_dvd_maker;

  if ($dvd_maker)
  {
    tools_dvd_maker = undef;

    $dvd_maker             -> try_terminate ();
    tools_dvdauthor_button -> setEnabled (0);

    return;
  }

  my $base_path = tools_base_path_edit -> text ();

  if (stat ("$base_path/dvdauthor.xml") == 0)
  {
    error (sprintf "%s: %s", $base_path,
	   &trUtf8 ("No dvdauthor XML control file"));

    return;
  }

  $dvd_maker      = DvdMaker (tools_log_viewer, undef, undef,
			      0, undef, this, "tools_dvd_maker");
  tools_dvd_maker = $dvd_maker;

  my $button      = tools_dvdauthor_button;
  my $button_text = $button -> text ();
  $button           -> setText (&trUtf8 ("Abort image creation"));
  tools_burn_button -> setEnabled (0);

  my $stat = $dvd_maker -> run_dvdauthor ($base_path, 1);

  $button           -> setText ($button_text);
  $button           -> setEnabled (1);
  tools_burn_button -> setEnabled (1);

  if (tools_dvd_maker)
  {
    if ($stat)
    {
      my $cmd = read_setting ("/General/burn_failed_cmd");
      system ("$cmd &") if ($cmd);

      error ('<font color="#ff0000">' .
	     &trUtf8 ("Image creation failed!") . '</font> ' .
	     &trUtf8 ("You may find further information in the output log."));
    }
    else
    {
      my $cmd = read_setting ("/General/burn_done_cmd");
      system ("$cmd &") if ($cmd);

      info (&trUtf8 ("Image creation successfully completed"));
    }
  }
  else
  {
    info (&trUtf8 ("Image creation aborted!"));
  }

  tools_dvd_maker = undef;
}


sub tools_burn_or_abort
{
  my $dvd_maker = tools_dvd_maker;

  if ($dvd_maker)
  {
    tools_dvd_maker = undef;

    $dvd_maker        -> try_terminate ();
    tools_burn_button -> setEnabled (0);

    return;
  }

  my $vol_id;
  my $base_path = tools_base_path_edit -> text ();

  unless (base_path_has_image ($base_path))
  {
    error (sprintf "%s: %s", $base_path, &trUtf8 ("No DVD image found"));

    return;
  }

  if (open FH, "<", "$base_path/volume_id.txt")
  {
    $vol_id = <FH>;
    chomp ($vol_id);
    close FH;
  }
  else
  {
    $base_path =~ m|([^/]+)/*$|;
    $vol_id    = $1;
    $vol_id    =~ s/[^A-Za-z0-9_]+//g;
    $vol_id    =~ s/(.{1,29}).*/$1_QV/;
  }

  $dvd_maker      = DvdMaker (tools_log_viewer, undef, undef,
			      0, undef, this, "tools_dvd_maker");
  tools_dvd_maker = $dvd_maker;

  my $button      = tools_burn_button;
  my $button_text = $button -> text ();
  $button                -> setText (&trUtf8 ("Abort burning"));
  tools_dvdauthor_button -> setEnabled (0);

  my $stat = $dvd_maker -> run_burn_cmd ($base_path, $vol_id);

  $button                -> setText ($button_text);
  $button                -> setEnabled (1);
  tools_dvdauthor_button -> setEnabled (1);

  if (tools_dvd_maker)
  {
    if ($stat)
    {
      my $cmd = read_setting ("/General/burn_failed_cmd");
      system ("$cmd &") if ($cmd);

      error ('<font color="#ff0000">' .
	     &trUtf8 ("Burning failed!") . '</font> ' .
	     &trUtf8 ("You may find further information in the output log."));
    }
    else
    {
      my $cmd = read_setting ("/General/burn_done_cmd");
      system ("$cmd &") if ($cmd);

      info (&trUtf8 ("Burning successfully completed"));
    }
  }
  else
  {
    info (&trUtf8 ("Burning aborted!"));
  }

  tools_dvd_maker = undef;
}


sub make_base_path
{
  my $dvd_dir = shift;

  my $home      = $ENV {"HOME"};
  my $base_path = read_setting ("/Dvdauthor/base_path");
  $base_path    =~ s/~/$home/;

  return replace ($base_path, { "t" => $dvd_dir });
}


sub base_path_has_image
{
  my $base_path = shift;

  return stat ("$base_path/image/VIDEO_TS/VIDEO_TS.IFO") != 0;
}


sub tools_base_path_dialog
{
  my $base_path = make_base_path ("");
  $base_path    =
    Qt::FileDialog::getExistingDirectory ($base_path, this,
					  "tools_base_path_dialog",
					  "Base Path Selection");

  return unless ($base_path);

  $base_path =~ s|/+$||;
  tools_base_path_edit -> setText ($base_path);
}


sub tools_preview
{
  my $base_path = tools_base_path_edit -> text ();

  unless (base_path_has_image ($base_path))
  {
    error (sprintf "%s: %s", $base_path, &trUtf8 ("No DVD image found"));

    return;
  }

  my $cmd = read_setting ("/MediaPlayer/play_dvd");
  $cmd    = replace ($cmd, { "i" => "$base_path/image" });
  system ("$cmd &");
}


sub is_proper_base_path
{
  my $base_path = shift;

  return stat ("$base_path/dvdauthor.xml") != 0 &&
    stat ("$base_path/run_me") != 0 &&
    (() = glob ("$base_path/vts*-pgc*.yuv"));
}


sub remove_temp_files
{
  my $base_path = shift;

  rmtree ("$base_path/menu");
  unlink ("$base_path/vamps.inj");
}


sub remove_image
{
  my $base_path = shift;

  rmtree ("$base_path/image");
  unlink ("$base_path/volume_id.txt");
}


sub tools_remove_files
{
  my $base_path = tools_base_path_edit -> text ();

  unless (is_proper_base_path ($base_path))
  {
    error (sprintf "%s: %s", $base_path,
	   &trUtf8 ("Does not look like a qVamps copy directory"));

    return;
  }

  my $remove_files_dialog = RemoveFilesDialog (this, "remove_files_dialog");

  return unless ($remove_files_dialog -> exec () == &Qt::Dialog::Accepted);

  for ($remove_files_dialog -> selected_button_index ())
  {
    if ($_ == 0)
    {
      remove_temp_files ($base_path);

      last;
    }

    if ($_ == 1)
    {
      remove_image ($base_path);

      last;
    }

    if ($_ == 2)
    {
      remove_temp_files ($base_path);
      remove_image ($base_path);

      last;
    }

    if ($_ == 3)
    {
      rmtree ($base_path);

      last;
    }
  }
}


sub menu_table_item_up
{
  mtable_items -> up_item ();
}


sub menu_table_item_down
{
  mtable_items -> down_item ();
}


sub menu_table_item_add
{
  mtable_items -> add_item ();
}


sub menu_table_item_remove
{
  mtable_items -> remove_item ();
}


sub menu_table_renumber_labels
{
  mtable_items -> renumber_labels ();
}


sub background_file_dialog
{
  my $filename = background_edit -> text ();
  $filename    = Qt::FileDialog::getOpenFileName ($filename,
    "Images (*.jpg *.jpeg *.png *.pnm *.ppm *.bmp);;" .
    "More Images (*.xbm *.xpm *.pgm *.pbm);;" .
    "DVD Program Streams (*.mpg *.mpeg)",
    this, "background_file_dialog", "Menu Background Selection");

  return unless ($filename);

  background_edit -> setText ($filename);
}


sub show_menu_preview
{
  my $menu_preview = menu_preview;

  $menu_preview -> preview (this);
  $menu_preview -> show ();
}


sub close_menu_preview # SLOT: ( bool )
{
  my $on = shift;

  menu_preview -> close () unless ($on);
}


sub background_filename
{
  return background_edit -> text ();
}


sub heading
{
  return heading_edit -> text ();
}


sub subheading
{
  return subheading_edit -> text ();
}


sub menu_table_items
{
  return mtable_items;
}


sub fpc_title_activated
{
  my $ttn = shift;

  fpc_mgr -> title_changed ($ttn);
}


sub get_heading_font
{
  get_font (\heading_font_setting);
}


sub get_subheading_font
{
  get_font (\subheading_font_setting);
}


sub get_buttons_font
{
  get_font (\buttons_font_setting);
}


sub get_font
{
  my $ref = shift;

  my $ok;
  my $font = Qt::Font (@{${$ref}});
  $font    = Qt::FontDialog::getFont ($ok, $font);

  ${$ref} = [ $font -> family (), $font -> pointSize (), 50, 0 ];
}


sub get_heading_color
{
  get_color (\heading_color_setting);
}


sub get_subheading_color
{
  get_color (\subheading_color_setting);
}


sub get_base_color
{
  get_color (\base_color_setting);
}


sub get_hilited_color
{
  get_color (\hilited_color_setting);
}


sub get_selected_color
{
  get_color (\selected_color_setting);
}


sub get_color
{
  my $ref = shift;

  my $color = Qt::Color (@{${$ref}});
  $color    = Qt::ColorDialog::getColor ($color);

  ${$ref} = [ $color -> red (), $color -> green (), $color -> blue () ]
    if ($color -> isValid ());
}


sub set_default_settings
{
  while (my ($key, $ref) = each %{&settings_mapping})
  {
    if (ref ($ref) eq "SCALAR")
    {
      ${$ref} = get_default_list_setting ($key);
    }
    else
    {
      for (${$ref})
      {
	if (/ARRAY/)
	{
	  ${$ref} = get_default_list_setting ($key);
	  last;
	}

	if (/LineEdit/)
	{
	  ${$ref} -> setText (get_default_setting ($key));
	  last;
	}

	if (/SpinBox/)
	{
	  ${$ref} -> setValue (get_default_setting ($key));
	  last;
	}

	if (/ComboBox/)
	{
	  if (${$ref} -> editable ())
	  {
	    ${$ref} -> clear ();
	    ${$ref} -> insertStringList (get_default_list_setting ($key));
	    ${$ref} -> setCurrentItem (get_default_setting ($key . "_item"));
	  }
	  else
	  {
	    ${$ref} -> setCurrentText (get_default_setting ($key));
	  }

	  last;
	}
      }
    }
  }
}


sub load_settings
{
  while (my ($key, $ref) = each %{&settings_mapping})
  {
    if (ref ($ref) eq "SCALAR")
    {
      ${$ref} = read_list_setting ($key);
    }
    else
    {
      for (${$ref})
      {
	if (/ARRAY/)
	{
	  ${$ref} = read_list_setting ($key);
	  last;
	}

	if (/LineEdit/)
	{
	  ${$ref} -> setText (read_setting ($key));
	  last;
	}

	if (/SpinBox/)
	{
	  ${$ref} -> setValue (read_setting ($key));
	  last;
	}

	if (/ComboBox/)
	{
	  if (${$ref} -> editable ())
	  {
	    ${$ref} -> clear ();
	    ${$ref} -> insertStringList (read_list_setting ($key));
	    ${$ref} -> setCurrentItem (read_setting ($key . "_item"));
	  }
	  else
	  {
	    ${$ref} -> setCurrentText (read_setting ($key));
	  }

	  last;
	}
      }
    }
  }
}


sub compare_settings
{
  while (my ($key, $ref) = each %{&settings_mapping})
  {
    my $value;

    if (ref ($ref) eq "SCALAR")
    {
      return scalar (keys %{&settings_mapping}, 1)
	unless (compare_lists (${$ref}, read_list_setting ($key)));
    }
    else
    {
      for (${$ref})
      {
	if (/ARRAY/)
	{
	  return scalar (keys %{&settings_mapping}, 1)
	    unless (compare_lists (${$ref}, read_list_setting ($key)));
	  last;
	}

	if (/LineEdit/)
	{
	  return scalar (keys %{&settings_mapping}, 1)
	    unless (${$ref} -> text () eq read_setting ($key));
	  last;
	}

	if (/SpinBox/)
	{
	  return scalar (keys %{&settings_mapping}, 1)
	    unless (${$ref} -> value () eq read_setting ($key));
	  last;
	}

	if (/ComboBox/)
	{
	  if (${$ref} -> editable ())
	  {
	    my @list;

	    for (my $i = 0; $i < ${$ref} -> count (); $i++)
	    {
	      push @list, ${$ref} -> text ($i);
	    }

	    my $item      = ${$ref} -> currentItem ();
	    $list [$item] = ${$ref} -> currentText ();

	    return scalar (keys %{&settings_mapping}, 1)
	      unless (compare_lists (\@list, read_list_setting ($key)));

	    return scalar (keys %{&settings_mapping}, 1)
	      unless ($item eq read_setting ($key . "_item"));
	  }
	  else
	  {
	    return scalar (keys %{&settings_mapping}, 1)
	      unless (${$ref} -> currentText () eq read_setting ($key));
	  }

	  last;
	}
      }
    }
  }

  return 0;
}


sub save_settings
{
  while (my ($key, $ref) = each %{&settings_mapping})
  {
    my $value;

    if (ref ($ref) eq "SCALAR")
    {
      print STDERR "save_settings: SCALAR, key=$key\n";
      write_setting ($key, ${$ref});
    }
    else
    {
      for (${$ref})
      {
	if (/ARRAY/)
	{
	  write_list_setting ($key, ${$ref});
	  last;
	}

	if (/LineEdit/)
	{
	  write_setting ($key, ${$ref} -> text ());
	  last;
	}

	if (/SpinBox/)
	{
	  write_setting ($key, ${$ref} -> value ());
	  last;
	}

	if (/ComboBox/)
	{
	  if (${$ref} -> editable ())
	  {
	    my @list;

	    for (my $i = 0; $i < ${$ref} -> count (); $i++)
	    {
	      push @list, ${$ref} -> text ($i);
	    }

	    my $item      = ${$ref} -> currentItem ();
	    $list [$item] = ${$ref} -> currentText ();

	    write_list_setting ($key, \@list);
	    write_setting ($key . "_item", $item);
	  }
	  else
	  {
	    write_setting ($key, ${$ref} -> currentText ());
	  }

	  last;
	}
      }
    }
  }

  $dvdr_total_sectors =
    ${settings_mapping -> {"/Vamps/dvdr_total_sectors"}} -> value ();
  $dvdr_spare_sectors =
    ${settings_mapping -> {"/Vamps/dvdr_spare_sectors"}} -> value ();
}


sub show_license
{
  my $dialog = LicenseDialog (this, "license_dialog");
  $dialog -> exec ();
}
