unit Unit_gwrap;
{
 DESCRIPTION     :  PeaLauncher, component launching 7za/7z console application,
                    providing GUI for:
                    displaying output of console using pipes;
                    displaying and explain job exitcode.
                    Named PeaExtractor when built as standalone archive extractor
                    application, as set in PMODE const.

 REQUIREMENTS    :  FPC, Lazarus

 EXTERNAL DATA   :  ---

 MEMORY USAGE    :  ---

 DISPLAY MODE    :  ---

 REFERENCES      :  ---

 REMARK          :  ---

 Version  Date      Author      Modification
 -------  --------  -------     ------------------------------------------
 0.10     20061102  G.Tani      Initial version
 0.11     20061130  G.Tani
 0.12     20070117  G.Tani
 0.13     20070130  G.Tani
 0.14     20070226  G.Tani
 0.15     20070403  G.Tani
 0.16     20070607  G.Tani
 0.17     20070716  G.Tani
 0.18     20070804  G.Tani
 0.19     20071001  G.Tani
 0.20     20071030  G.Tani
 0.20b    20071124  G.Tani
 0.21     20080319  G.Tani
 0.22     20080510  G.Tani
 0.23     20080730  G.Tani
 0.24     20080922  G.Tani
 0.25     20081027  G.Tani
 0.26     20081118  G.Tani
 0.27     20090124  G.Tani
 0.28     20090215  G.Tani
 0.29     20090330  G.Tani
 0.30     20090508  G.Tani
 0.31     20090713  G.Tani
 0.32     20090825  G.Tani
 0.33     20090913  G.Tani
 0.34     20091016  G.Tani
 0.35     20091103  G.Tani
 0.36     20091109  G.Tani
 0.37     20091125  G.Tani
 0.38     20100108  G.Tani
 0.39     20100125  G.Tani
 0.40     20100207  G.Tani
 0.41     20100217  G.Tani
 0.42     20100313  G.Tani
 0.43     20100424  G.Tani
 0.44     20100602  G.Tani
          20100907  G.Tani
 0.45     20101014  G.Tani
 0.46     20101113  G.Tani
 0.47     20101224  G.Tani
 0.48     20110402  G.Tani
 0.49     20110426  G.Tani
 0.50     20110727  G.Tani
 0.51     20110813  G.Tani
 0.52     20110915  G.Tani
 0.53     20111016  G.Tani
 0.54     20111110  G.Tani
          20111224  G.Tani
 0.55     20120115  G.Tani
 0.56     20120315  G.Tani
          20120515  G.Tani
 0.57     20120807  G.Tani      (Windows) Added semaphore to perform one operation at time in order to optimize disk performances for some operations
          20120818  G.Tani      Uniformed Button Panels design over the application
 0.58     20120916  G.Tani      More information given on extraction, list and test jobs
 0.59     20121104  G.Tani      PeaLauncher (in standard mode) inherits previous instances minimized/normal status
                                New high definition Windows icon
 0.60     20130220  G.Tani      New theming engine
 0.61     20130310  G.Tani      Minor fixes in fallback if text file is not found
 0.62     20130617  G.Tani      Code cleanup, various usability improvements (new layout, input and output pats are linked)
 0.63     20130718  G.Tani      (Linux) Fixed opening input/output paths
                                Recompiled with Lazarus 1.0.10
 0.64     20130823  G.Tani      Various minor fixes
 0.65     20130922  G.Tani      Various minor fixes, recompiled with Lazarus 1.0.12
 0.66     20131106  G.Tani      Added context menu for input/output links featuring entries to explore and search the system, and pause/stop the task
 0.67     20140222  G.Tani      Improved standalone extraction launcher GUI
 0.68     20140403  G.Tani      New progress bar, visual updates
                                New syntetic Info mode
                                Recompiled with Lazarus 1.2.0
 0.69     20140416  G.Tani      Info function error handling
 0.70     20140703  G.Tani      New, lighter layout meant to better focus on relevant information
                                Various minor fixes
 0.71     20140810  G.Tani      Visual update for lighter layout but preserving tabs for quicker switching
 0.72     20141015  G.Tani      Priority setting moved to dropdown menu near OK/Cancel buttons
                                Improved stopping tasks
                                 Cancel all option in dropdown menu allows to stop all following tasks
                                 Cancel action reports to application's form rather than using a separate message box
 0.73     20141220  G.Tani      Improved system benchmark output presentation
 0.74     20150108  G.Tani      Fixed bug in Info function with newer 7z versions
 0.75     20150311  G.Tani      Improved usability as standalone application (PeaExtractor 1.0)
                                Added menu for online resources (updates, help...) and other options
                                Added ability to set program's localization and system context menu language when used as standalone application
 0.76     20150322  G.Tani      Fixed access to online help and resources when compiled as PeaExtractor
                                Improved Open file dialog adding custom file extension filters for common archive types
 0.77     20150425  G.Tani      Introduced support for ZPAQ 7.05 and BCM 1.0
 0.78     20150618  G.Tani      Updated Info function for new 7z/p7zip backend versions
 0.79     20150718  G.Tani      Recompiled for PeaZip 5.7 with Lazarus 1.4.0
 0.80     20150915  G.Tani      Improved UTF8 compatibility, recompiled for PeaZip 5.8
 0.81     20151010  G.Tani      Fixed use clWindow for keeping the application consistent with system's visual preferences
 0.82     20151121  G.Tani      Updated to use p7zip 15.x line, minor fixes, recompiled for PeaZip 5.9
 0.83     20160221  G.Tani      Recompiled for Lazarus 1.6.0 / FPC3 with full support for Unicode file/dir names in Windows
                                Code cleanup to remove unnecessary character encoding handling functions
                                New Ten theme set as default
 0.84     20160809  G.Tani      Various updates for standalone PeaExtractor 1.2
 0.85     20160909  G.Tani      Various updates for standalone PeaExtractor 1.3
 0.86     20161022  G.Tani      Various visual updates for standalone PeaExtractor 1.3
 0.87     20161124  G.Tani      DPI awareness improvements
 0.88     20170325  G.Tani      Recompiled for PeaZip 6.4, visual updates
 0.89     20170415  G.Tani      UI fixes

 Implicitly, PeaLauncher is recompiled updating PEAZIPVERSION according to current major.minor PeaZip release

(C) Copyright 2006 Giorgio Tani giorgio.tani.software@gmail.com
Official PeaZip site http://www.peazip.org
The program is released under GNU LGPL http://www.gnu.org/licenses/lgpl.txt

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
}

{$mode objfpc}{$H+}

interface

uses
  {$IFDEF MSWINDOWS}
  Windows, activex, shellapi,
  {$ENDIF}
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, strutils,
  StdCtrls, Buttons, Process, UTF8Process, Menus,
  pea_utils, list_utils, ansiutf8_utils, img_utils, Grids, Math;

type

  { TForm_gwrap }

  TForm_gwrap = class(TForm)
    ButtonEditName10: TSpeedButton;
    ButtonEditName11: TSpeedButton;
    ButtonEditName3: TButton;
    ButtonOk: TBitBtn;
    ButtonCancel: TBitBtn;
    ButtonOutputArchive: TButton;
    ButtonRefSize: TButton;
    ButtonStop1: TSpeedButton;
    cbAutoClose: TCheckBox;
    cbAutoOpen: TCheckBox;
    CheckBoxFolder: TCheckBox;
    CheckBoxFolder1: TCheckBox;
    CheckBoxHalt: TCheckBox;
    ComboBoxOverwrite: TComboBox;
    EditName3: TEdit;
    EditOpenOut: TEdit;
    EditUn7zaPW: TEdit;
    hbm1: TSpeedButton;
    hbm2: TSpeedButton;
    hbm3: TSpeedButton;
    ImageButton2: TLabel;
    Imagefixed: TImage;
    ImageSavePJ: TLabel;
    Imagestatus: TImage;
    ImageList1: TImageList;
    il_dtheme_16: TImageList;
    il_dtheme_big: TImageList;
    Button1: TBitBtn;
    ButtonStop: TBitBtn;
    ButtonPause: TBitBtn;
    l1: TLabel;
    l2: TLabel;
    l3: TLabel;
    l4: TLabel;
    l5: TLabel;
    Label1: TLabel;
    Label4: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    labelextto: TLabel;
    labelfullinput: TLabel;
    labelfullsize: TLabel;
    LabelInfo3: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Labeli: TLabel;
    LabelInfo1: TLabel;
    LabelInfo2: TLabel;
    Labelo: TLabel;
    labelopenfile0: TLabel;
    labelopenfile1: TLabel;
    labelopenfile2: TLabel;
    labelopenfile3: TLabel;
    LabelTitle1: TLabel;
    LabelTitle2: TLabel;
    LabelTitle3: TLabel;
    LabelTitle4: TLabel;
    LabelWarning1: TLabel;
    LabelWarning2: TLabel;
    LabelWarning3: TLabel;
    MainMenu1: TMainMenu;
    Memo1: TMemo;
    Memo2: TMemo;
    MenuItem1: TMenuItem;
    MenuItem11: TMenuItem;
    MenuItem5: TMenuItem;
    mCancelAll: TMenuItem;
    mainmenuhelp: TMenuItem;
    mmdonations: TMenuItem;
    mmlangsysmenu: TMenuItem;
    mmrunasadmin: TMenuItem;
    mmsp1: TMenuItem;
    mmsp2: TMenuItem;
    mmlang: TMenuItem;
    mmhelp: TMenuItem;
    mmupdate: TMenuItem;
    OpenDialog2: TOpenDialog;
    Panel4: TPanel;
    PanelFull1: TPanel;
    PanelFull2: TPanel;
    PanelTitle: TPanel;
    Notebook1: TPanel;
    Page1: TPanel;
    Page2: TPanel;
    Page3: TPanel;
    Page4: TPanel;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    PanelBench: TPanel;
    pmpause: TMenuItem;
    pmstop: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    pmei: TMenuItem;
    pmeo: TMenuItem;
    pmexplore: TMenuItem;
    pmsearch: TMenuItem;
    mpathexplore: TMenuItem;
    mpathreset: TMenuItem;
    OpenDialog1: TOpenDialog;
    Panel5: TPanel;
    PopupMenu1: TPopupMenu;
    PopupMenu2: TPopupMenu;
    pmmain: TPopupMenu;
    PopupMenupath: TPopupMenu;
    SaveDialog1: TSaveDialog;
    SaveDialog2: TSaveDialog;
    SelectDirectoryDialog1: TSelectDirectoryDialog;
    ShapeProgress: TPanel;
    ShapeTitle1: TShape;
    ShapeTitle2: TShape;
    ShapeTitle3: TShape;
    StringGrid1: TStringGrid;
    Timer1: TTimer;
    Timer2: TTimer;
    procedure ButtonCancelClick(Sender: TObject);
    procedure ButtonEditName10Click(Sender: TObject);
    procedure ButtonEditName11Click(Sender: TObject);
    procedure ButtonEditName3Click(Sender: TObject);
    procedure ButtonOkClick(Sender: TObject);
    procedure ButtonOutputArchiveClick(Sender: TObject);
    procedure ButtonStop1Click(Sender: TObject);
    procedure cbAutoOpenClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormDropFiles(Sender: TObject; const FileNames: array of String);
    procedure FormResize(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormWindowStateChange(Sender: TObject);
    procedure hbm1Click(Sender: TObject);
    procedure hbm2Click(Sender: TObject);
    procedure hbm3Click(Sender: TObject);
    procedure ImageSavePJClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ImageButton2Click(Sender: TObject);
    procedure ButtonStopClick(Sender: TObject);
    procedure ButtonPauseClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure l2Click(Sender: TObject);
    procedure l4Click(Sender: TObject);
    procedure Label4Click(Sender: TObject);
    procedure labelopenfile0Click(Sender: TObject);
    procedure labelopenfile2Click(Sender: TObject);
    procedure LabelTitle1Click(Sender: TObject);
    procedure LabelTitle1MouseEnter(Sender: TObject);
    procedure LabelTitle1MouseLeave(Sender: TObject);
    procedure LabelTitle2Click(Sender: TObject);
    procedure LabelTitle2MouseEnter(Sender: TObject);
    procedure LabelTitle2MouseLeave(Sender: TObject);
    procedure LabelTitle3Click(Sender: TObject);
    procedure LabelTitle3MouseEnter(Sender: TObject);
    procedure LabelTitle3MouseLeave(Sender: TObject);
    procedure LabelTitle4Click(Sender: TObject);
    procedure LabelTitle4MouseEnter(Sender: TObject);
    procedure LabelTitle4MouseLeave(Sender: TObject);
    procedure LabelWarning1Click(Sender: TObject);
    procedure LabelWarning2Click(Sender: TObject);
    procedure mCancelAllClick(Sender: TObject);
    procedure MenuItem1Click(Sender: TObject);
    procedure MenuItem2Click(Sender: TObject);
    procedure MenuItem3Click(Sender: TObject);
    procedure MenuItem4Click(Sender: TObject);
    procedure mainmenuhelpClick(Sender: TObject);
    procedure mmdonationsClick(Sender: TObject);
    procedure mmlangsysmenuClick(Sender: TObject);
    procedure mmrunasadminClick(Sender: TObject);
    procedure mmhelpClick(Sender: TObject);
    procedure mmlangClick(Sender: TObject);
    procedure mmupdateClick(Sender: TObject);
    procedure mpathexploreClick(Sender: TObject);
    procedure mpathresetClick(Sender: TObject);
    procedure pmeiClick(Sender: TObject);
    procedure pmeoClick(Sender: TObject);
    procedure pmexploreClick(Sender: TObject);
    procedure pmpauseClick(Sender: TObject);
    procedure pmsearchClick(Sender: TObject);
    procedure pmstopClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

procedure preparefull;

const
  PMODE         = 'pealauncher'; //peaextractor = standalone utility; pealauncher = peazip's task launcher
  PEAZIPVERSION = '6.4';
  WS_EX_LAYERED = $80000;
  LWA_ALPHA     = $2;
  STR_STOPALL   = '.pstopall';
  {$IFDEF MSWINDOWS}
  DEFAULT_THEME = 'ten-embedded';
  {$ELSE}
  DEFAULT_THEME = 'ten-embedded';
  {$ENDIF}
  {$IFDEF MSWINDOWS}
  EXEEXT        = '.exe';
  {$ELSE}
  EXEEXT        = '';
  {$ENDIF}

var
  Form_gwrap: TForm_gwrap;
  Barchive,Binfo,Bloadlayout,Bconsole,Bp1,Bp2,Bp3,Bp4,Bp5,Bp6,Bp7,Bp8,
  Bpriority1,Bpriority2,Bpriority3,Bpriority4,
  Bsuccess,Berror,Brunas,Bweb: TBitmap;
  cl,cl1,outpath,executable_path,graphicsfolder,dummy,Color1,Color2,Color3,
  Color4,Color5,caption_build,delimiter,confpath,peazippath,in_name,dummytitle:ansistring;
  modeofuse,fullmode,automode,max_l,ppriority,rowheight,autoclose,autoopen:integer;
  insize,incstep1,incstep2,incstep3,progress,tinsize:qword;
  opacity,desk_env,pcount,optype:byte;
  iperc:integer;
  patheditor:TEdit;
  T,conf:text;
  f:file of byte;
  launched,stopped,ended,ppause,pstarted,launchwithsemaphore:boolean;
  tsin:TTimestamp;
  activelabel_launcher :TLabel;
  //translations
  txt_5_6_update,txt_5_6_cml,txt_5_6_donations,txt_5_6_localization,txt_5_6_runasadmin,
  txt_5_6_help,
  txt_5_5_cancelall,
  txt_5_3_details,txt_5_3_files,txt_5_3_folders,txt_5_3_os,txt_5_3_ps,txt_5_3_info,
  txt_5_3_list,txt_5_3_test,
  txt_5_0_extract,txt_5_0_from,txt_5_0_in,txt_5_0_to,
  txt_4_5_search,
  txt_4_0_dragorselect,txt_4_0_drag,txt_4_0_select,
  txt_3_6_selectdir,
  txt_3_5_close,
  txt_3_0_details,txt_3_0_hints,txt_3_0_arc,txt_3_0_ext,
  txt_2_8_oop,
  txt_2_7_validatecl,txt_2_7_validatefn,
  txt_2_6_open,
  txt_2_5_ace_missing,
  txt_2_3_pw_errorchar_gwrap,txt_2_3_cancel,txt_2_3_encryption,txt_2_3_extinnew,
  txt_2_3_keyfile,txt_2_3_kf_not_found_gwrap,txt_2_3_moreoptions,txt_2_3_nopaths,
  txt_2_3_pw,txt_2_3_skipexisting,txt_2_3_overexisting,txt_2_3_renameextracted,
  txt_2_3_renameexisting,txt_2_3_options,
  txt_status,txt_jobstatus,txt_rating,txt_threads,txt_input,
  txt_output,txt_time,txt_isrunning,txt_autoclose,txt_halt,txt_report,txt_console,
  txt_explore,txt_ok,txt_stop,txt_pause,txt_rt,txt_high,txt_normal,txt_idle,txt_priority,
  txt_savejob,txt_savelog,txt_bench,txt_saveas,txt_job_success,txt_job1,txt_job2,
  txt_job7,txt_job8,txt_job127,txt_job255,txt_job_unknown,txt_benchscale,txt_lt,txt_extto,
  txt_create,txt_nocl,txt_job_started,txt_jobstopped,txt_jstopped,txt_jpaused,txt_jresumed,
  txt_p_realtime,txt_p_high,txt_p_normal,txt_p_idle,txt_paused,txt_running,txt_speedscale,
  txt_crscale,txt_done,txt_halted,txt_error,txt_hardware,txt_software,txt_resume,
  txt_stdjob,txt_benchmarkjob,txt_defragjob,txt_consolejob,lang_file,lver,wincomspec,
  winver:ansistring;
  {$IFDEF MSWINDOWS}
  //semaphore
  psem: THandle;
  {$ENDIF}

implementation

///launcher

procedure setpanel_launcher(i:integer);
begin
with Form_gwrap do
begin
imagebutton2.visible:=false;
imagesavepj.visible:=false;
case i of
   1: begin Page1.Visible:=true; Page2.Visible:=false; Page3.Visible:=false; Page4.Visible:=false; end;
   2: begin Page1.Visible:=false; Page2.Visible:=true; Page3.Visible:=false; Page4.Visible:=false; imagebutton2.visible:=true; end;
   3: begin Page1.Visible:=false; Page2.Visible:=false; Page3.Visible:=true; Page4.Visible:=false; imagesavepj.visible:=true; end;
   4: begin Page1.Visible:=false; Page2.Visible:=false; Page3.Visible:=false; Page4.Visible:=true; end;
   end;
end;
end;

procedure exitlabel_launcher(var a: TLabel);
begin
if activelabel_launcher=a then exit;
a.Font.Color:=clgray;
end;

procedure deselectlabels_launcher;
begin
with Form_gwrap do
begin
exitlabel_launcher(LabelTitle1);
exitlabel_launcher(LabelTitle2);
exitlabel_launcher(LabelTitle3);
exitlabel_launcher(LabelTitle4);
end;
end;

procedure setlabelpanel_launcher(var a: Tlabel);
begin
with Form_gwrap do
begin
if a = LabelTitle1 then setpanel_launcher(1);
if a = LabelTitle2 then setpanel_launcher(2);
if a = LabelTitle3 then setpanel_launcher(3);
if a = LabelTitle4 then setpanel_launcher(4);
end;
end;

procedure clicklabel_launcher(var a: TLabel);
begin
activelabel_launcher:=a;
deselectlabels_launcher;
a.Font.Color:=clDefault;
setlabelpanel_launcher(a);
end;

procedure enterlabel_launcher(var a: TLabel);
begin
if activelabel_launcher=a then exit;
a.Font.Color:=PLBLUE;
end;

///

procedure conf_critical_error_msg; //hardcoded
begin
MessageDlg(PMODE+' cannot find or parse critical configuration files (probably because deleted, moved or corrupted); PeaZip should be reinstalled', mtError, [mbOK], 0);
end;

procedure lang_critical_error_msg; //hardcoded
begin
MessageDlg(PMODE+' cannot parse language file '+lang_file+' and will now try to fall back to default language file default.txt', mtError, [mbOK], 0);
end;

function valorize_text:integer;
var
   s:ansistring;
begin
valorize_text:=-1;
try
readln(t,s);
readln(t,s); txt_5_6_update:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_6_cml:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_6_donations:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_6_localization:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_6_runasadmin:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_6_help:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_5_cancelall:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_details:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_files:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_folders:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_info:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_list:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_os:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_ps:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_3_test:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_0_extract:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_0_from:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_0_in:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_5_0_to:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_4_5_search:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_4_0_drag:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_4_0_dragorselect:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_4_0_select:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_3_6_selectdir:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_3_5_close:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_3_0_details:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_3_0_hints:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_3_0_arc:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_3_0_ext:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_8_oop:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_7_validatefn:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_7_validatecl:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_6_open:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_5_ace_missing:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_pw_errorchar_gwrap:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_renameexisting:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_renameextracted:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_cancel:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_encryption:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_extinnew:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_keyfile:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_kf_not_found_gwrap:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_moreoptions:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_nopaths:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_options:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_overexisting:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_pw:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_2_3_skipexisting:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job_unknown:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_stdjob:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_benchmarkjob:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_defragjob:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_consolejob:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job1:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job127:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job2:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job255:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job7:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job8:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_autoclose:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_crscale:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_console:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_benchscale:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_create:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_done:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_nocl:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_error:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_explore:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_extto:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_halt:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_halted:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_hardware:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_high:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_idle:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_input:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_jpaused:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_jresumed:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job_started:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_jobstatus:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_jstopped:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_jobstopped:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_job_success:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_lt:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_normal:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_ok:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_output:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_pause:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_paused:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_p_high:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_p_idle:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_p_normal:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_p_realtime:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_rating:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_rt:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_report:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_resume:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_priority:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_running:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_isrunning:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_saveas:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_savejob:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_savelog:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_software:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_speedscale:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_status:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_stop:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_bench:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_threads:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s); txt_time:=copy(s,pos(':',s)+2,length(s)-pos(':',s));
readln(t,s);
readln(t,s); if s<>'=== end PeaLauncher text group ===' then exit;
valorize_text:=0;
except
valorize_text:=-1;
end;
end;

function valorize_headers:integer;
var
   s:ansistring;
begin
valorize_headers:=-1;
readln(t,s);//translator(s)
readln(t,s);//last revision's translator(s)
readln(t,s);//last revision date
readln(t,s);
readln(t,s);//peazip text group
if s<>'=== PeaZip text group ===' then exit
else valorize_headers:=0;
end;

procedure assign_guitext;
begin
with Form_gwrap do
begin
mmhelp.Caption:=txt_5_6_help+' (F1)';
mmupdate.Caption:=txt_5_6_update;
mmdonations.Caption:=txt_5_6_donations;
mmlang.Caption:=txt_5_6_localization;
mmlangsysmenu.Caption:=txt_5_6_cml;
mmrunasadmin.Caption:=txt_5_6_runasadmin;
mCancelAll.Caption:=txt_5_5_cancelall;
labelopenfile0.Caption:=txt_4_5_search;
labelopenfile1.Caption:=txt_4_0_drag;
labelopenfile2.Caption:=txt_4_0_select;
labelWarning1.Caption:=txt_3_0_hints;
CheckBoxFolder.Caption:=txt_2_3_extinnew;
CheckBoxFolder1.Caption:=txt_2_3_nopaths;
Label4.Caption:=txt_2_3_moreoptions;
ButtonCancel.Caption:='   '+txt_2_3_cancel+'   ';
LabelWarning3.Caption:=txt_2_3_pw;
LabelWarning2.Caption:=txt_2_3_keyfile;
labelextto.Caption:=txt_extto;
ButtonOk.caption:='   '+txt_ok+'   ';
LabelTitle1.Caption:='      '+txt_status+'      ';
LabelTitle2.Caption:='      '+txt_report+'      ';
LabelTitle3.Caption:='      '+txt_console+'      ';
LabelTitle4.Caption:='      '+txt_2_3_options+'      ';
Label1.Caption:=txt_isrunning+', ';
Label2.Caption:=txt_rating;
Label3.Caption:=txt_threads;
Labeli.Caption:=txt_input+' ';
Labelo.Caption:=txt_output+' ';
cbAutoClose.Caption:=txt_autoclose;
CheckBoxHalt.Caption:=txt_halt;
cbAutoOpen.Caption:=txt_2_8_oop;
Button1.Caption:='   '+txt_3_5_close+'   ';
ButtonStop.Caption:='   '+txt_2_3_cancel+'   ';
ButtonPause.Caption:='   '+txt_pause+'   ';
MenuItem1.Caption:=txt_rt;
MenuItem2.Caption:=txt_high;
MenuItem3.Caption:=txt_normal;
MenuItem4.Caption:=txt_idle;
ImageSavePJ.Caption:=txt_savejob;
ImageButton2.Caption:=txt_savelog;
Label2.Hint:=txt_benchscale;
OpenDialog1.Title:=txt_2_6_open;
SaveDialog1.Title:=txt_saveas;
SaveDialog2.Title:=txt_saveas;
SelectDirectoryDialog1.Title:=txt_3_6_selectdir;
pmexplore.caption:=txt_explore+'...';
pmsearch.caption:=txt_4_5_search;
pmpause.caption:=txt_pause;
pmstop.caption:=txt_stop;
end
end;

function load_texts(lang:ansistring):integer; //valorize localized text strings
var
   s:ansistring;
   i:integer;
begin
load_texts:=-1;
try
   assignfile(t,(executable_path+'lang'+directoryseparator+lang));
   filemode:=0;
   reset(t);
   read_header(t);
   readln(t,s); //declaration
   if s<>'=== PeaZip language file ===' then
      begin
      closefile(t);
      exit;
      end;
   readln(t,s);//language
   readln(t,lver);//version
   i:=valorize_headers;
   repeat //skip until about text group
      readln(t,s);
   until (eof(t)) or (s='=== end PeaZip text group ===');
   if eof(t)=true then
      begin
      closefile(t);
      exit;
      end;
   readln(t,s);//empty
   readln(t,s);//declaration
   if s<>'=== PeaLauncher text group ===' then
      begin
      closefile(t);
      exit;
      end;
   if lver<>PEAZIPVERSION then
      {if i=0 then i:=fallback_valorize_text
      else}
   else
      if i=0 then i:=valorize_text;
   if i=0 then assign_guitext
   else
      begin
      closefile(t);
      exit;
      end;
   closefile(t);
   load_texts:=0;
except
   try
   closefile(t);
   except
   end;
   load_texts:=-1;
end;
end;

function texts(lang:ansistring):integer;
begin
   //preload default language file to valorize possibly untranslated strings (i.e. older translations)
   texts:=load_texts('default.txt');
   //fallback to english if default language file is not ok
   if texts<>0 then texts:=load_texts('en.txt');
   //fallback to british english if even english language file is not ok
   if texts<>0 then texts:=load_texts('en-gb.txt');
   if lang<>'default.txt' then
      if load_texts(lang)<>0 then //try to load language file sequentially; fallback to a slower recoursive procedure to valorize each known variable from lang file strings if the language file version doesn't match with PeaZip's version
         begin
         lang_file:='default.txt'; //try to load default language file on failure
         load_texts(lang_file);
         end
      else texts:=0;
{if texts<>0 then
   begin
   //conf_critical_error_msg;
   Application.Terminate;
   end;}//use compile time strings if no valid text file is found
end;

function cp_open(s:ansistring; desk_env:byte):integer;
var
   w:widestring;
begin
cp_open:=-1;
if s='' then exit;
if validatecl(s)<>0 then begin MessageDlg(txt_2_7_validatecl+' '+s, mtWarning, [mbOK], 0); exit; end;
{$IFDEF MSWINDOWS}
w:=utf8decode(s);
cp_open:=ShellExecuteW(Form_gwrap.Handle, PWideChar ('open'), PWideChar(w), PWideChar (''), PWideChar (''), SW_SHOWNORMAL);
if cp_open<33 then
   cp_open:=shellexecuteW(Form_gwrap.handle,PWideChar('open'),PWideChar('RUNDLL32.EXE'),PWideChar('shell32.dll,OpenAs_RunDLL '+w),PWideChar (''), SW_SHOWNORMAL);
{$ENDIF}
{$IFDEF LINUX}cp_open:=cp_open_linuxlike(s,desk_env);{$ENDIF}//try to open via Gnome or KDE
{$IFDEF FREEBSD}cp_open:=cp_open_linuxlike(s,desk_env);{$ENDIF}
{$IFDEF NETBSD}cp_open:=cp_open_linuxlike(s,desk_env);{$ENDIF}
end;

procedure set_items_height;
var
   refsize,stdbtnheight,lfontsizeb,lfontsizebb,tabheight,smbtnw,mbtnw:integer;
begin
with Form_gwrap do
begin
refsize:=ButtonRefSize.Height;
if refsize<3 then refsize:=25;
Width:=560*refsize div 25;
Height:=270*refsize div 25;
imagestatus.Top:=imagefixed.Top-12;
//buttons
stdbtnheight:=26*refsize div 25;
Button1.Height:=stdbtnheight;
ButtonStop.Height:=stdbtnheight;
ButtonPause.Height:=stdbtnheight;
ButtonOk.Height:=stdbtnheight;
ButtonCancel.Height:=stdbtnheight;
ButtonStop1.Height:=stdbtnheight;
hbm1.Height:=stdbtnheight;
hbm2.Height:=stdbtnheight;
hbm3.Height:=stdbtnheight;
//tabs
tabheight:=36*refsize div 25;
PanelTitle.Height:=tabheight;
Panel5.Height:=tabheight+12;
//buttons width
smbtnw:=24*refsize div 25;
mbtnw:=stdbtnheight;
hbm1.Width:=mbtnw;
hbm2.Width:=mbtnw;
hbm3.Width:=mbtnw;
ButtonEditName10.Width:=smbtnw;
ButtonEditName11.Width:=smbtnw;
ButtonEditName3.Width:=smbtnw;
ButtonOutputArchive.Width:=smbtnw;
ButtonStop1.Width:=smbtnw;
//grid
rowheight:=22*refsize div 25;
StringGrid1.DefaultRowHeight:=rowheight;
//custom fonts
lfontsizeb:=9+(2*refsize div 25);
lfontsizebb:=9+(6*refsize div 25);
labelopenfile0.Font.Size:=lfontsizeb;
labelopenfile1.Font.Size:=lfontsizeb;
labelopenfile2.Font.Size:=lfontsizeb;
labelopenfile3.Font.Size:=lfontsizeb;
l1.Font.Size:=lfontsizeb;
l2.Font.Size:=lfontsizeb;
l3.Font.Size:=lfontsizeb;
l4.Font.Size:=lfontsizeb;
l5.Font.Size:=lfontsizebb;
end;
end;

procedure apply_theme;
begin

   Form_gwrap.Label1.Font.Color:=clgray;//clInactiveCaptionText;
   Form_gwrap.Label5.Font.Color:=clgray;//clInactiveCaptionText;
   Form_gwrap.Label6.Font.Color:=clgray;//clInactiveCaptionText;
   Form_gwrap.Labeli.Font.Color:=clgray;//clInactiveCaptionText;
   Form_gwrap.Labelo.Font.Color:=clgray;//clInactiveCaptionText;
   Form_gwrap.LabelInfo1.Font.Color:=clgray;//clInactiveCaptionText;
   Form_gwrap.LabelInfo2.Font.Color:=clgray;//clInactiveCaptionText;
   Form_gwrap.LabelInfo3.Font.Color:=clgray;//clInactiveCaptionText;

end;

procedure getthemepath(var thpath:ansistring);
var
   theme_name,s:ansistring;
begin
s:=graphicsfolder;
if s<>'' then setlength(s,length(s)-1);
theme_name:=extractfilename(s);
//default and no graphic themes are in application's path, custome themes are in configuration path (application's path for portable versions, user's home/application data for installable versions)
if (upcase(theme_name)<>upcase(DEFAULT_THEME)) and (upcase(theme_name)<>'NOGRAPHIC') then thpath:=confpath
else thpath:=executable_path;
end;

procedure load_icons;
var
   thpath:ansistring;
begin
with Form_gwrap do
   try
   //non-themed
   Bpriority1:=TBitmap.Create;
   Bpriority2:=TBitmap.Create;
   Bpriority3:=TBitmap.Create;
   Bpriority4:=TBitmap.Create;
   Bp1:=TBitmap.Create;
   Bp2:=TBitmap.Create;
   Bp3:=TBitmap.Create;
   Bp4:=TBitmap.Create;
   Bp5:=TBitmap.Create;
   Bp6:=TBitmap.Create;
   Bp7:=TBitmap.Create;
   Bp8:=TBitmap.Create;
   Brunas:=TBitmap.Create;
   Bweb:=TBitmap.Create;
   Imagelist1.getbitmap(0,ButtonEditname10.Glyph);
   Imagelist1.getbitmap(0,ButtonEditname11.Glyph);
   Imagelist1.getbitmap(0,ButtonStop1.Glyph);
   Imagelist1.getbitmap(1,Bpriority1);
   Imagelist1.getbitmap(2,Bpriority2);
   Imagelist1.getbitmap(3,Bpriority3);
   Imagelist1.getbitmap(4,Bpriority4);
   Imagelist1.getbitmap(5,Bp1);
   Imagelist1.getbitmap(6,Bp2);
   Imagelist1.getbitmap(7,Bp3);
   Imagelist1.getbitmap(8,Bp4);
   Imagelist1.getbitmap(9,Bp5);
   Imagelist1.getbitmap(10,Bp6);
   Imagelist1.getbitmap(11,Bp7);
   Imagelist1.getbitmap(12,Bp8);
   Imagelist1.getbitmap(14,hbm1.Glyph);
   Imagelist1.getbitmap(14,hbm2.Glyph);
   Imagelist1.getbitmap(14,hbm3.Glyph);
   Imagelist1.getbitmap(15,Brunas);
   Imagelist1.getbitmap(16,Bweb);
   //themed
   Bsuccess:=TBitmap.Create;
   Binfo:=TBitmap.Create;
   Barchive:=TBitmap.Create;
   Bloadlayout:=TBitmap.Create;
   Bconsole:=TBitmap.Create;
   Berror:=TBitmap.Create;
   getthemepath(thpath);
   if graphicsfolder<>'themes'+directoryseparator+'nographic'+directoryseparator then
      begin
      il_dtheme_16.getbitmap(0,Bsuccess);
      il_dtheme_16.getbitmap(1,Binfo);
      il_dtheme_16.getbitmap(2,Bloadlayout);
      il_dtheme_16.getbitmap(3,Bconsole);
      il_dtheme_16.getbitmap(4,Berror);
      il_dtheme_16.getbitmap(1,Binfo);
      il_dtheme_big.getbitmap(0,Barchive);
      end;
   if graphicsfolder='themes'+directoryseparator+'nographic'+directoryseparator then
      begin
      imagelist1.getbitmap(13,Bsuccess);
      imagelist1.getbitmap(13,Binfo);
      imagelist1.getbitmap(13,Bloadlayout);
      imagelist1.getbitmap(13,Bconsole);
      imagelist1.getbitmap(13,Berror);
      imagelist1.getbitmap(13,Binfo);
      imagelist1.getbitmap(13,Barchive);
      end;
   if (graphicsfolder<>'themes'+directoryseparator+'ten-embedded'+directoryseparator) and (graphicsfolder<>'themes'+directoryseparator+'nographic'+directoryseparator) then
      begin
      Bsuccess.LoadFromFile(thpath+graphicsfolder+'16'+directoryseparator+'16-test.bmp');
      Binfo.LoadFromFile(thpath+graphicsfolder+'16'+directoryseparator+'16-info.bmp');
      Bloadlayout.LoadFromFile(thpath+graphicsfolder+'16'+directoryseparator+'16-paste.bmp');
      Bconsole.LoadFromFile(thpath+graphicsfolder+'16'+directoryseparator+'16-file-script.bmp');
      Berror.LoadFromFile(thpath+graphicsfolder+'16'+directoryseparator+'16-stop.bmp');
      //Binfo.LoadFromFile(thpath+graphicsfolder+'16'+directoryseparator+'16-info.bmp');
      Barchive.LoadFromFile(thpath+graphicsfolder+'96'+directoryseparator+'96-folder.bmp');
      end;
   Bsuccess.Transparent:=True;
   Binfo.Transparent:=True;
   Barchive.Transparent:=True;
   Bloadlayout.Transparent:=True;
   Bconsole.Transparent:=True;
   Berror.Transparent:=True;
   Brunas.Transparent:=True;
   Imagefixed.Picture.Bitmap:=Barchive;
   Imagefixed.Transparent:=True;
   Imagestatus.Picture.Bitmap:=Bp1;
   Imagestatus.Transparent:=True;
   Buttonok.Glyph:=Bsuccess;
   ButtonCancel.Glyph:=Berror;
   MenuItem1.Bitmap:=Bpriority4;
   MenuItem2.Bitmap:=Bpriority3;
   MenuItem3.Bitmap:=Bpriority2;
   MenuItem4.Bitmap:=Bpriority1;
   mCancelAll.Bitmap:=Berror;
   mmlang.Bitmap:=Binfo;
   mmrunasadmin.Bitmap:=Brunas;
   //mmhelp.Bitmap:=Bweb;
   except
   end;
end;

procedure save_report;
var
   s,p:ansistring;
   i:integer;
begin
s:=formatdatetime('yyyymmdd_hh.nn.ss_',now)+'job_log.txt';
Form_gwrap.SaveDialog1.FileName:=s;
if outpath<>'' then
   if directoryexists(outpath) then Form_gwrap.SaveDialog1.InitialDir:=outpath
   else Form_gwrap.SaveDialog1.InitialDir:=extractfilepath(outpath);
if Form_gwrap.SaveDialog1.Execute then
   begin
   s:=Form_gwrap.SaveDialog1.FileName;
   assignfile(t,(s));
   rewrite(t);
   write_header(t);
   for i:=0 to Form_gwrap.StringGrid1.Rowcount-1 do writeln(t,Form_gwrap.StringGrid1.Cells[0,i]);
   writeln(t,'');
   writeln(t,Form_gwrap.Label1.Caption);
   if modeofuse=2 then
      begin
      writeln(t,'');
      writeln(t,Form_gwrap.Label2.Caption);
      writeln(t,Form_gwrap.Label3.Caption);
      writeln(t,Form_gwrap.Label7.Caption);
      writeln(t,Form_gwrap.Label8.Caption);
      end;
   closefile(t);
   p:=(getcurrentdir);
   if p[length(p)]<>DirectorySeparator then p:=p+DirectorySeparator;
   end;
end;

procedure save_cl;
var
s,p:ansistring;
begin
s:=formatdatetime('yyyymmdd_hh.nn.ss_',now)+'job_definition.txt';
Form_gwrap.SaveDialog1.FileName:=s;
if outpath<>'' then
   if directoryexists(outpath) then Form_gwrap.SaveDialog1.InitialDir:=outpath
   else Form_gwrap.SaveDialog1.InitialDir:=extractfilepath(outpath);
if Form_gwrap.SaveDialog1.Execute then
   begin
   s:=Form_gwrap.SaveDialog1.FileName;
   assignfile(t,(s));
   rewrite(t);
   write_header(t);
   writeln(t,cl);
   closefile(t);
   p:=(getcurrentdir);
   if p[length(p)]<>DirectorySeparator then p:=p+DirectorySeparator;
   end;
end;

procedure decode_exitcode(i:integer; var s:ansistring);
begin
case i of
   0: s:=txt_job_success;
   1: s:=txt_job1;
   2: s:=txt_job2;
   7: s:=txt_job7+' '+cl;
   8: s:=txt_job8;
   127: s:=txt_job127;
   255: s:=txt_job255;
   else s:=inttostr(i)+txt_job_unknown;
   end;
if stopped=true then s:=txt_jstopped;
end;

{procedure setspeedgraph(speed:integer);
var
   flog:single;
begin
with Form_gwrap do
begin
ShapeSpeed1.Visible:=true;
ShapeSpeed2.Visible:=true;
ShapeSpeed3.Visible:=true;
ShapeSpeed4.Visible:=true;
ShapeSpeed5.Visible:=true;
ShapeSpeed6.Visible:=true;
ShapeSpeed7.Visible:=true;
ShapeSpeed8.Visible:=true;
ShapeSpeed9.Visible:=true;
ShapeSpeed10.Visible:=true;
ImagePriority.Picture.Bitmap:=nil;
ShapeSpeed10.Height:=ShapeSpeed9.Height;
ShapeSpeed9.Height:=ShapeSpeed8.Height;
ShapeSpeed8.Height:=ShapeSpeed7.Height;
ShapeSpeed7.Height:=ShapeSpeed6.Height;
ShapeSpeed6.Height:=ShapeSpeed5.Height;
ShapeSpeed5.Height:=ShapeSpeed4.Height;
ShapeSpeed4.Height:=ShapeSpeed3.Height;
ShapeSpeed3.Height:=ShapeSpeed2.Height;
ShapeSpeed2.Height:=ShapeSpeed1.Height;
flog:=log10(speed);
ShapeSpeed1.Height:=round(flog*2);
end;
end;}

procedure progress10; //progress counter
var
   outsize,percentout,i,iprog:qword;
   tdiff,speed:integer;
   tsout:TTimeStamp;
   tpath:ansistring;
begin
with Form_gwrap do
begin
percentout:=0;
outsize:=0;
speed:=0;
tsout:=datetimetotimestamp(now);
tdiff:=((tsout.date-tsin.date)*24*60*60*1000)+tsout.time-tsin.time;
if tdiff<=0 then tdiff:=100000;
Form_gwrap.LabelInfo3.Caption:=nicetime(inttostr(tdiff));
tpath:=outpath;
if (optype=1) and (modeofuse=0) then
  if fileexists(tpath+'.tmp') then tpath:=outpath+'.tmp';
try
if fileexists(tpath) then
   if not(directoryexists(tpath)) then
      begin
      srcfilesize_multipart(tpath,outsize);
      if insize<>0 then percentout:=(outsize*1000000) div insize;
      if outsize>0 then
         begin
         Form_gwrap.Labelo.Visible:=true;
         Form_gwrap.LabelInfo2.Visible:=true;
         if (percentout>0) then Form_gwrap.LabelInfo2.Caption:=nicenumber(inttostr(outsize))+' ('+inttostr(percentout div 10000)+'%)'
         else Form_gwrap.LabelInfo2.Caption:=nicenumber(inttostr(outsize));
         if tdiff<>0 then speed:=outsize div tdiff * 1000;
         if speed>0 then
            begin
            Form_gwrap.LabelInfo2.Caption:=Form_gwrap.LabelInfo2.Caption+' @ '+nicenumber(inttostr(speed))+'/s';
            //setspeedgraph(speed);
            end;
         end
      else
         begin
         Form_gwrap.Labelo.Visible:=false;
         Form_gwrap.LabelInfo2.Visible:=false;
         end;
      end;
except
end;
if optype=0 then percentout:=percentout div 2
else percentout:=percentout * 2;
if percentout>1000000 then percentout:=1000000;

i:=(progress+percentout) div 2;
if i<330000 then progress:=progress+incstep1
else
   if i<660000 then progress:=progress+incstep2
   else progress:=progress+incstep3;

iprog:=(Form_gwrap.Width*i div 1000000)+3;
if iprog>=Form_gwrap.Width then
   begin
   iprog:=3;
   progress:=0;
   incstep1:=incstep1 div 4;
   incstep2:=incstep2 div 4;
   incstep3:=incstep3 div 4;
   if incstep1=0 then incstep1:=1;
   if incstep2=0 then incstep2:=1;
   if incstep3=0 then incstep3:=1;
   end;
ShapeProgress.Width:=iprog;
if ShapeProgress.Width<>0 then iperc:=(ShapeProgress.Width *100) div Form_gwrap.Width;
if iperc>0 then begin l5.Caption:=inttostr(iperc)+'% '; Form_gwrap.Caption:=l5.Caption+dummytitle; end;
end;
end;

procedure setiomenu;
begin
Form_gwrap.pmei.caption:=Form_gwrap.l2.caption;
Form_gwrap.pmeo.caption:=Form_gwrap.l4.caption;
if Form_gwrap.pmei.caption='' then Form_gwrap.pmei.visible:=false;
if Form_gwrap.pmeo.caption='' then Form_gwrap.pmeo.visible:=false;
Form_gwrap.pmei.caption:=txt_explore+' '+Form_gwrap.l2.caption;
Form_gwrap.pmeo.caption:=txt_explore+' '+Form_gwrap.l4.caption;
end;

procedure set_form_title;
var s,s1,s2:ansistring;
begin
Form_gwrap.l1.Visible:=false;
Form_gwrap.l2.Visible:=false;
Form_gwrap.l3.Visible:=false;
Form_gwrap.l4.Visible:=false;
Form_gwrap.l1.Caption:='';
Form_gwrap.l2.Caption:='';
Form_gwrap.l3.Caption:='';
Form_gwrap.l4.Caption:='';
Form_gwrap.l2.Hint:='';
Form_gwrap.l4.Hint:='';
case modeofuse of
   1 : s1:=txt_5_3_test+' '+extractfilename(in_name);
   4 : s1:=txt_5_3_info+' '+extractfilename(in_name);
   5 : s1:=txt_5_3_list+' '+extractfilename(in_name);
   end;
case modeofuse of
   3 :
   begin
   Form_gwrap.Caption:=cl;
   exit;
   end;
   2 :
   begin
   Form_gwrap.Caption:=txt_bench;
   exit;
   end;
   1,4,5 :
   begin
   s2:=copy(outpath,1,length(outpath)-1);
   {$IFDEF MSWINDOWS}if length(s2) = 2 then else{$ENDIF} s2:=extractfilename(s2);
   Form_gwrap.l1.Caption:=(s1+' '+txt_5_0_in+' ');
   Form_gwrap.l4.Caption:=(s2);
   Form_gwrap.l4.Hint:=(extractfilepath(outpath));
   Form_gwrap.Caption:=Form_gwrap.l1.Caption+Form_gwrap.l4.Caption;
   Form_gwrap.l1.Visible:=true;
   Form_gwrap.l4.Visible:=true;
   setiomenu;
   exit;
   end;
   end;
if extractfilename(outpath)='' then optype:=0
else optype:=1;//0 extract, 1 archive
if optype=0 then
   begin
   s2:=copy(outpath,1,length(outpath)-1);
   {$IFDEF MSWINDOWS}if length(s2) = 2 then else{$ENDIF} s2:=extractfilename(s2);
   s:=extractfilepath(in_name);
   s:=copy(s,1,length(s)-1);
   {$IFDEF MSWINDOWS}if length(s) = 2 then else{$ENDIF} s:=extractfilename(s);
   s1:=txt_5_0_extract+' '+extractfilename(in_name)+' '+txt_5_0_from+' ';
   Form_gwrap.l1.Caption:=(s1);
   Form_gwrap.l2.Caption:=(s);
   Form_gwrap.l2.Hint:=(extractfilepath(in_name));
   Form_gwrap.l3.Caption:=' '+txt_5_0_to+' ';
   Form_gwrap.l4.Caption:=(s2);
   Form_gwrap.l4.Hint:=(extractfilepath(outpath));
   Form_gwrap.Caption:=Form_gwrap.l1.Caption+Form_gwrap.l2.Caption+Form_gwrap.l3.Caption+Form_gwrap.l4.Caption;
   Form_gwrap.l1.Visible:=true;
   Form_gwrap.l2.Visible:=true;
   Form_gwrap.l3.Visible:=true;
   Form_gwrap.l4.Visible:=true;
   end
else
   begin
   s1:=txt_create+' '+extractfilename(outpath); //don't work properly for arc since needs no directoryseparator after outpath
   s2:=extractfilepath(outpath);
   s2:=copy(s2,1,length(s2)-1);
   {$IFDEF MSWINDOWS}if length(s2) = 2 then else{$ENDIF} s2:=extractfilename(s2);
   Form_gwrap.l1.Caption:=(s1+' '+txt_5_0_in+' ');
   Form_gwrap.l4.Caption:=(s2);
   Form_gwrap.l4.Hint:=(extractfilepath(outpath));
   Form_gwrap.Caption:=Form_gwrap.l1.Caption+Form_gwrap.l4.Caption;
   Form_gwrap.l1.Visible:=true;
   Form_gwrap.l4.Visible:=true;
   end;
setiomenu;
end;

procedure explore_out;
var
   i:integer;
   s,outpath2:ansistring;
begin
{$IFDEF MSWINDOWS}
outpath2:=outpath;
if (modeofuse=1) or (modeofuse=4) or (modeofuse=5) then outpath2:=in_name;
if (optype=1) and (modeofuse=0) then
   if fileexists(outpath+'.tmp') then outpath2:=outpath+'.tmp';
s:=outpath2;
if s='' then exit;
s:=(s);
winexplorepath(s);
{$ELSE}
i:=filegetattr(outpath);
if (i and faDirectory) = 0 then s:=extractfilepath(outpath)
else s:=outpath;
if s='' then exit;
cp_open(s,desk_env);
{$ENDIF}
end;

procedure explore_in;
var
   i:integer;
   s:ansistring;
begin
{$IFDEF MSWINDOWS}
s:=in_name;
if s='' then exit;
s:=(s);
winexplorepath(s);
{$ELSE}
i:=filegetattr(in_name);
if (i and faDirectory) = 0 then s:=extractfilepath(in_name)
else s:=in_name;
if s='' then exit;
cp_open(s,desk_env);
{$ENDIF}
end;

procedure setlabel1text;
begin
with Form_gwrap do
   begin
   if ppause=true then Label1.Caption:=txt_paused+' '
   else Label1.Caption:=txt_running+' ';
   case ppriority of
      1: Label1.Caption:=Label1.Caption+txt_rt+', ';
      2: Label1.Caption:=Label1.Caption+txt_high+', ';
      3: Label1.Caption:=Label1.Caption+txt_normal+', ';
      4: Label1.Caption:=Label1.Caption+txt_idle+', ';
      end;
   case modeofuse of
      3 : Label5.Caption:=txt_defragjob;//unused
      20 : Label5.Caption:=txt_consolejob;
      end;
   if modeofuse<>2 then
      if label5.caption<>'' then Label5.Visible:=true else Label5.Visible:=false;
   end;
end;

procedure updatereport(M:TMemoryStream; var stri1:ansistring);
var
   i:integer;
   stri2:ansistring;
begin
with Form_gwrap do
begin
SetString(stri2, M.Memory, M.Size);
stri2:=AnsiReverseString(stri2);
stri2:=copy(stri2,pos(char($0A)+char($0D),stri2)+2,length(stri2)-(pos(char($0A)+char($0D),stri2)));
stri1:=copy(stri2,1,pos(char($0A)+char($0D),stri2)-1);
stri1:=ReverseString(stri1);
stri2:=ReverseString(stri2);
Form_gwrap.Memo1.Clear;
Form_gwrap.Memo1.Append(stri2);
Form_gwrap.StringGrid1.Rowcount:=Form_gwrap.Memo1.Lines.Count;
for i:=0 to Form_gwrap.Memo1.Lines.Count-1 do Form_gwrap.StringGrid1.Cells[0,i]:=Form_gwrap.Memo1.Lines[i];//(Form_gwrap.Memo1.Lines[i]);
Form_gwrap.Memo1.Clear;
Form_gwrap.StringGrid1.RowCount:=Form_gwrap.StringGrid1.Rowcount-1; //last row may be incomplete
Form_gwrap.StringGrid1.Row:=Form_gwrap.StringGrid1.Rowcount-1;
Form_gwrap.StringGrid1.AutosizeColumns;
end;
end;

procedure fixbringtofront;
begin
{$IFDEF MSWINDOWS}
Form_gwrap.FormStyle:=fsStayOnTop;
Form_gwrap.FormStyle:=fsNormal;
{$ENDIF}
end;

procedure getschedule;
var
  pwait:boolean;
begin
{$IFDEF MSWINDOWS}
if launchwithsemaphore=false then exit;
pwait:=true;
Form_gwrap.WindowState:=wsMinimized;
Form_gwrap.Visible:=false;
while pwait=true do
begin
psem:=CreateSemaphore(nil, 0, 1, 'PeaLauncher semaphore');
if ((psem<>0) and (GetLastError=ERROR_ALREADY_EXISTS)) then
   begin
   CloseHandle(psem);
   sleep(500);
   end
else pwait:=false;
end;
{$ENDIF}
end;

procedure displayinfo(exit_code:integer; exit_string:ansistring);
var
   s,s1,dummystr:ansistring;
   i,rc:integer;
   osize,psize,cratio:qword;
   stopinfo:boolean;
begin
Form_gwrap.Visible:=false;
if exit_code=0 then
begin
try
//details (not localized)
stopinfo:=false;
i:=8;
rc:=Form_gwrap.StringGrid1.Rowcount;
while stopinfo=false do
begin
i:=i+1;
if i>=rc-1 then break;
dummystr:=Form_gwrap.StringGrid1.Cells[0,i];
if length(dummystr)=0 then stopinfo:=true
else s:=s+dummystr+char($0A)+char($0D);
end;
//original size
stopinfo:=false;
dummystr:=Form_gwrap.StringGrid1.Cells[0,rc-2];
{$IFDEF MSWINDOWS}dummystr:=copy(dummystr,22,length(dummystr)-21);{$ENDIF}
while stopinfo=false do
begin
if length(dummystr)<2 then break;
if dummystr[1]=' ' then dummystr:=copy(dummystr,2,length(dummystr)-1)
else stopinfo:=true;
end;
s1:=txt_5_3_os+' '+nicenumber(copy(dummystr,1,pos(' ',dummystr)-1))+char($0A)+char($0D);
osize:=strtoqword(copy(dummystr,1,pos(' ',dummystr)-1));
dummystr:=copy(dummystr,pos(' ',dummystr),length(dummystr)-pos(' ',dummystr)+1);
//packed size
stopinfo:=false;
while stopinfo=false do
begin
if length(dummystr)<2 then break;
if dummystr[1]=' ' then dummystr:=copy(dummystr,2,length(dummystr)-1)
else stopinfo:=true;
end;
s1:=s1+txt_5_3_ps+' '+nicenumber(copy(dummystr,1,pos(' ',dummystr)-1));
psize:=strtoqword(copy(dummystr,1,pos(' ',dummystr)-1));
if osize<>0 then
   begin
   cratio:=(100*psize) div osize;
   s1:=s1+' ('+inttostr(cratio)+'%)'+char($0A)+char($0D);
   end
else s1:=s1+char($0A)+char($0D);
dummystr:=copy(dummystr,pos(' ',dummystr),length(dummystr)-pos(' ',dummystr)+1);
//files number
stopinfo:=false;
while stopinfo=false do
begin
if length(dummystr)<2 then break;
if dummystr[1]=' ' then dummystr:=copy(dummystr,2,length(dummystr)-1)
else stopinfo:=true;
end;
s1:=s1+copy(dummystr,1,pos(' ',dummystr)-1)+' '+txt_5_3_files+', ';
dummystr:=copy(dummystr,pos(' ',dummystr),length(dummystr)-pos(' ',dummystr)+1);
//dirs number
i:=pos('folder',dummystr)-1;
s1:=s1+copy(dummystr,pos(', ',dummystr)+2,i-pos(', ',dummystr)-2)+' '+txt_5_3_folders+char($0A)+char($0D);
except
   if rc>4 then
   s:=Form_gwrap.StringGrid1.Cells[0,rc-4]+char($0A)+char($0D)+
   Form_gwrap.StringGrid1.Cells[0,rc-3]+char($0A)+char($0D)+
   Form_gwrap.StringGrid1.Cells[0,rc-2]+char($0A)+char($0D)+
   Form_gwrap.StringGrid1.Cells[0,rc-1]
   else s:='';
   s1:='';
end;
//presentation
s:=extractfilename(in_name)+char($0A)+char($0D)+char($0A)+char($0D)+s1+char($0A)+char($0D)+txt_5_3_details+char($0A)+char($0D)+'------'+char($0A)+char($0D)+s;
end
else s:=exit_string;
MessageDlg(s, mtInformation, [mbOK], 0);
Form_gwrap.Close;
end;

procedure launch_cl;
var
   P: TProcessUTF8;
   tsout,tevent:TTimeStamp;
   tdiff,speed1,speed2,i,exit_code,w,BytesRead,prevpriority,minline,protype:integer;
   outsize,cratio:qword;
   s,dummy,scltest,delimstr,stri,astri,bstri:ansistring;
   {$IFDEF MSWINDOWS}
   w0,w1:WideString;
   sei: TShellExecuteInfoW;
   {$ENDIF}
   prevpause,exit_code_bol:boolean;
   M:TmemoryStream;
begin
pstarted:=true;
if (autoclose=2) or (autoclose=4) then
   Form_gwrap.WindowState:=wsMinimized
else
   fixbringtofront;
Form_gwrap.Shapeprogress.visible:=true;
Form_gwrap.ShapeProgress.Width:=3;
progress:=0;
Form_gwrap.mmrunasadmin.enabled:=false;
Form_gwrap.mmlang.enabled:=false;
if (PMODE<>'peaextractor') and (automode=0) then Form_gwrap.hbm3.visible:=false; //don't show menu for standard launcher invoked by PeaZip, display it if the program is used standalone (either PeaLauncher bundled with PeaZip or packed as independent application PeaExtractor)
Form_gwrap.Memo2.Lines.Append(cl);
ppause:=false;
if ppriority=0 then ppriority:=3;//default: normal priority
prevpause:=false;
prevpriority:=ppriority;
if cl='' then
   begin
   MessageDlg(txt_nocl,mtError, [mbOK], 0);
   Application.Terminate;
   end;
Form_gwrap.LabelTitle1.caption:='      '+txt_isrunning+'      ';
clicklabel_launcher(Form_gwrap.LabelTitle1);
P:=TProcessUTF8.Create(nil);
P.CommandLine:=(cl);
if insize>0 then
   if (tinsize>0) and (tinsize<>insize) then Form_gwrap.LabelInfo1.Caption:=nicenumber(inttostr(insize))+' / '+nicenumber(inttostr(tinsize))
   else Form_gwrap.LabelInfo1.Caption:=nicenumber(inttostr(insize))
else Form_gwrap.LabelInfo1.Caption:=nicenumber(inttostr(tinsize));
set_form_title;
if Form_gwrap.Visible=true then Application.ProcessMessages;
M := TMemoryStream.Create;
BytesRead := 0;
if modeofuse=20 then
else
   begin
   P.Options := [poUsePipes, poNoConsole];
   end;
try
if validatecl(cl)<>0 then begin MessageDlg(txt_2_7_validatecl+' '+cl, mtWarning, [mbOK], 0); ended:=true; exit; end;
tsin:=datetimetotimestamp(now);
pcount:=1;
stri:='';
astri:='';
bstri:='';
if modeofuse<>2 then Form_gwrap.l5.visible:=true;
dummytitle:=Form_gwrap.Caption;

   protype:=0;
   P.Execute;
   while P.Running do
   begin
   if Form_gwrap.Visible=true then Application.ProcessMessages;
   if stopped=true then
      begin
      P.Terminate(255);
      Form_gwrap.ShapeProgress.Color:=PRED;
      tevent:=datetimetotimestamp(now);
      break;
      end;
   if ppause=true then
      begin
      if ppause<>prevpause then
         begin
         P.Suspend;
         tevent:=datetimetotimestamp(now);
         prevpause:=true;
         end;
      end
   else
      begin
      if ppause<>prevpause then
         begin
         P.Resume;
         tevent:=datetimetotimestamp(now);
         prevpause:=false;
         end;
      end;
   if ppriority<>prevpriority then //if priority has changed, update process priority and log the event
      begin
      case ppriority of
      1: begin
         P.Priority:=ppRealTime;
         tevent:=datetimetotimestamp(now);
         end;
      2: begin
         P.Priority:=ppHigh;
         tevent:=datetimetotimestamp(now);
         end;
      3: begin
         P.Priority:=ppNormal;
         tevent:=datetimetotimestamp(now);
         end;
      4: begin
         P.Priority:=ppIdle;
         tevent:=datetimetotimestamp(now);
         end;
      end;
      prevpriority:=ppriority;
      end;
   setlabel1text;
   if modeofuse>=20 then Sleep(100)
   else
      begin
      if P.output.NumBytesAvailable>0 then
         begin
         M.SetSize(BytesRead + max_l);
         i := P.Output.Read((M.Memory + BytesRead)^, max_l);
         if i>0 then
            begin
            astri:=bstri;
            SetString(stri, M.Memory, M.Size);
            bstri:=stri;
            if astri<>bstri then
               begin
               updatereport(M,stri);
               Form_gwrap.Label6.Caption:=stri;
               if Form_gwrap.label6.caption<>'' then Form_gwrap.Label6.Visible:=true else Form_gwrap.Label6.Visible:=false;
               end;
            end;
         end
      else i:=0;
      if i > 0 then Inc(BytesRead, i)
      else Sleep(100);
      end;
   end;

Form_gwrap.l5.caption:='100% ';
iperc:=100;
Form_gwrap.l5.visible:=false;
Form_gwrap.Caption:=dummytitle;
pstarted:=false;
Form_gwrap.Imagestatus.Cursor:=crDefault;
Form_gwrap.Imagestatus.Hint:='';
tsout:=datetimetotimestamp(now);
Form_gwrap.ShapeProgress.Width:=Form_gwrap.Width-6;//process terminated
Application.ProcessMessages;
if (protype=0) then
begin
if modeofuse>=20 then
   begin
   exit_code:=P.ExitStatus;
   P.Free;
   end
else
   begin
   repeat
      M.SetSize(BytesRead + max_l);
      i := P.Output.Read((M.Memory + BytesRead)^, max_l);
      if i>0 then
            begin
            astri:=bstri;
            SetString(stri, M.Memory, M.Size);
            bstri:=stri;
            if astri<>bstri then
               begin
               updatereport(M,stri);
               Form_gwrap.Label6.Caption:=stri;
               if Form_gwrap.label6.caption<>'' then Form_gwrap.Label6.Visible:=true else Form_gwrap.Label6.Visible:=false;
               end;
            end;
      if i > 0 then Inc(BytesRead, i)
      else Sleep(100);
   until i <= 0;
   M.SetSize(BytesRead);
   exit_code:=P.ExitStatus;
   P.Free;
   Form_gwrap.Memo1.Clear;
   Form_gwrap.Memo1.Lines.LoadFromStream(M);

            SetString(stri, M.Memory, M.Size);
               stri:=AnsiReverseString(stri);
               stri:=copy(stri,pos(char($0A)+char($0D),stri)+2,length(stri)-(pos(char($0A)+char($0D),stri)));
               stri:=copy(stri,1,pos(char($0A)+char($0D),stri)-1);
               stri:=ReverseString(stri);
               Form_gwrap.Label6.Caption:=stri;
               if Form_gwrap.label6.caption<>'' then Form_gwrap.Label6.Visible:=true else Form_gwrap.Label6.Visible:=false;

   M.Free;
   Form_gwrap.StringGrid1.Rowcount:=Form_gwrap.Memo1.Lines.Count+1;
   for i:=0 to Form_gwrap.Memo1.Lines.Count-1 do Form_gwrap.StringGrid1.Cells[0,i]:=Form_gwrap.Memo1.Lines[i];//(Form_gwrap.Memo1.Lines[i]);
   Form_gwrap.Memo1.Clear;
   i:=i+1;
   Form_gwrap.StringGrid1.Cells[0,i]:='';
   Form_gwrap.StringGrid1.AutosizeColumns;
   Form_gwrap.StringGrid1.Row:=Form_gwrap.StringGrid1.Rowcount-1;
   end;
end;
Form_gwrap.Stringgrid1.Cursor:=crDefault;
Form_gwrap.ShapeProgress.Width:=Form_gwrap.Width-3;//read from memory stream, if used
Application.ProcessMessages;
except
exit_code:=127; //"cannot execute" error
end;
tdiff:=((tsout.date-tsin.date)*24*60*60*1000)+tsout.time-tsin.time;
if tdiff<=0 then tdiff:=100000;
Form_gwrap.LabelTitle1.caption:='      '+txt_status+'      ';
clicklabel_launcher(Form_gwrap.LabelTitle1);
{$IFNDEF MSWINDOWS}
if stopped=true then exit_code:=255;
{$ENDIF}

decode_exitcode(exit_code,s);

if modeofuse=4 then displayinfo(exit_code,s);

Form_gwrap.Label1.Caption:=s+', ';
Form_gwrap.Label5.Caption:='';
Form_gwrap.Label6.Caption:='';
Form_gwrap.Label5.Visible:=false;
Form_gwrap.Label6.Visible:=false;
outsize:=0;
try
if fileexists((outpath)) then
   begin
   assignfile(f,(outpath));
   filemode:=0;
   reset(f);
   srcfilesize_multipart(outpath,outsize);
   closefile(f);
   end;
except
end;
if (outsize>0) then
   if (insize>0) and (Form_gwrap.labelo.visible=true) then
      begin
      cratio:=outsize * 100;
      cratio:=cratio div insize;
      Form_gwrap.LabelInfo2.Caption:=nicenumber(inttostr(outsize))+' ('+inttostr(cratio)+'%)';
      end
   else
      Form_gwrap.LabelInfo2.Caption:=nicenumber(inttostr(outsize));
Form_gwrap.Imagestatus.Picture.Bitmap:=Binfo;
//speed
speed1:=0;
speed2:=0;
if tdiff<>0 then speed1:=tinsize div tdiff * 1000;
if tdiff<>0 then speed2:=outsize div tdiff * 1000;
Form_gwrap.LabelInfo3.Caption:=nicetime(inttostr(tdiff));
if speed1>0 then Form_gwrap.LabelInfo1.Caption:=Form_gwrap.LabelInfo1.Caption+' @ '+nicenumber(inttostr(speed1))+'/s';
if speed2>0 then Form_gwrap.LabelInfo2.Caption:=Form_gwrap.LabelInfo2.Caption+' @ '+nicenumber(inttostr(speed2))+'/s';
if modeofuse>=20 then
   begin
   Form_gwrap.StringGrid1.Rowcount:=5;
   Form_gwrap.StringGrid1.Cells[0,0]:=datetimetostr(timestamptodatetime(tsout))+' - '+s;
   Form_gwrap.StringGrid1.Cells[0,1]:='';
   Form_gwrap.StringGrid1.Cells[0,2]:=Form_gwrap.Labeli.Caption+' '+Form_gwrap.LabelInfo1.Caption;
   Form_gwrap.StringGrid1.Cells[0,3]:=Form_gwrap.Labelo.Caption+' '+Form_gwrap.LabelInfo2.Caption;
   Form_gwrap.StringGrid1.Cells[0,4]:=Form_gwrap.LabelInfo3.Caption;
   Form_gwrap.StringGrid1.AutosizeColumns;
   end;
if exit_code=0 then
   begin
   Form_gwrap.Imagestatus.Picture.Bitmap:=Bsuccess;
   Form_gwrap.ShapeProgress.Color:=PGREEN;
   end
else
   begin
   Form_gwrap.Imagestatus.Picture.Bitmap:=Berror;
   Form_gwrap.ShapeProgress.Color:=PRED;
   end;
Form_gwrap.ButtonStop.Visible:=false;
Form_gwrap.ButtonStop1.Visible:=false;
Form_gwrap.Button1.Visible:=true;
Form_gwrap.ButtonPause.Visible:=false;
case exit_code of
   0: Form_gwrap.Caption:=txt_done+' '+Form_gwrap.Caption;
   255: Form_gwrap.Caption:=txt_halted+' '+Form_gwrap.Caption;
   else
      begin
      Form_gwrap.Caption:=txt_error+' '+Form_gwrap.Caption;
      if (modeofuse<>2) and (modeofuse<>3) then
         Form_gwrap.LabelWarning1.Visible:=true;
      end;
   end;
if Form_gwrap.LabelInfo2.width>Form_gwrap.LabelInfo3.width then i:=Form_gwrap.LabelInfo2.width
else i:=Form_gwrap.LabelInfo3.width;
case modeofuse of
   0: begin
      end;
   1,4,5: begin
      clicklabel_launcher(Form_gwrap.LabelTitle2);
      end;
   2: begin
      Form_gwrap.Panel2.Visible:=true;
      Form_gwrap.PanelBench.Visible:=true;;
      minline:=5;
      try
      Form_gwrap.Label2.Caption:='CPU';//+copy(Form_gwrap.Stringgrid1.Cells[0,minline-2],11,5)+' MHz'; //single and average results are quite discording with CPU clock
      Form_gwrap.Label3.Caption:=inttostr(strtoint(copy(Form_gwrap.Stringgrid1.Cells[0,minline+13],29,6)))+' MIPS ('+inttostr(strtoint(copy(Form_gwrap.Stringgrid1.Cells[0,minline],47,3)))+' threads)';
      Form_gwrap.Label7.Caption:=inttostr(strtoint(copy(Form_gwrap.Stringgrid1.Cells[0,minline+13],22,6)))+' Intel Core 2 rating (single core)';
      Form_gwrap.Label8.Caption:='RAM'+copy(Form_gwrap.Stringgrid1.Cells[0,minline],11,9);
      except
      end;
      end;
   3: begin
      clicklabel_launcher(Form_gwrap.LabelTitle2);
      Form_gwrap.Visible:=true;
      Form_gwrap.WindowState:=wsNormal;
      Form_gwrap.SetFocus;
      end;
   end;
Form_gwrap.ShapeProgress.Width:=Form_gwrap.Width;
ended:=true;
Application.ProcessMessages;
Form_gwrap.StringGrid1.AutosizeColumns;
if Form_gwrap.CheckBoxHalt.State=cbChecked then
   begin
   P:=TProcessUTF8.Create(nil);
   P.Options := [poUsePipes, poNoConsole];
   {$IFDEF MSWINDOWS}P.CommandLine:='shutdown /s /t 10';{$ENDIF}
   {$IFDEF LINUX}P.CommandLine:='halt';{$ENDIF}
   {$IFDEF FREEBSD}P.CommandLine:='halt';{$ENDIF}
   {$IFDEF NETBSD}P.CommandLine:='halt';{$ENDIF}
   if Form_gwrap.Visible=true then Application.ProcessMessages;
   scltest:=P.Commandline;
   if validatecl(scltest)<>0 then begin MessageDlg(txt_2_7_validatecl+' '+scltest, mtWarning, [mbOK], 0); exit; end;
   P.Execute;
   P.Free;
   end;
if autoopen=1 then
   if (modeofuse<>1) and (modeofuse<>4) and (modeofuse<>5) and (modeofuse<>2) then explore_out;
Form_gwrap.LabelTitle4.Visible:=false;
Form_gwrap.ShapeTitle3.Visible:=false;
sleep(500);
case autoclose of
   1: begin
      if exit_code=0 then
         if (modeofuse<>1) and (modeofuse<>4) and (modeofuse<>5) and (modeofuse<>2) then
            Form_gwrap.Close
         else
            Form_gwrap.SetFocus
      else
         Form_gwrap.SetFocus;
      end;
   2: begin
      if exit_code=0 then
         if (modeofuse<>1) and (modeofuse<>4) and (modeofuse<>5) and (modeofuse<>2) then
            Form_gwrap.Close
         else
            begin
            Form_gwrap.Visible:=true;
            Form_gwrap.WindowState:=wsNormal;
            Form_gwrap.SetFocus;
            end
      else
         begin
         Form_gwrap.Visible:=true;
         Form_gwrap.WindowState:=wsNormal;
         Form_gwrap.SetFocus;
         end;
      end;
   3: Form_gwrap.Close;
   4: begin
      if exit_code=0 then
         if (modeofuse<>1) and (modeofuse<>4) and (modeofuse<>5) and (modeofuse<>2) then
            Form_gwrap.Close
         else
            begin
            Form_gwrap.Visible:=true;
            Form_gwrap.WindowState:=wsNormal;
            Form_gwrap.SetFocus;
            end
      else
         begin
         Form_gwrap.Visible:=true;
         Form_gwrap.WindowState:=wsNormal;
         Form_gwrap.SetFocus;
         end;
      end;
   end;
end;

{ TForm_gwrap }

procedure TForm_gwrap.Timer1Timer(Sender: TObject);
begin
if launched=true then exit;
if fullmode=1 then exit;
launched:=true;
launch_cl;
end;

procedure TForm_gwrap.Timer2Timer(Sender: TObject);
begin
if stopped=true then exit;
if ppause=true then exit;
if ended=true then exit;
if pstarted=true then
   begin
      if modeofuse<20 then progress10;
      case pcount of
         1: begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp2; pcount:=2; end;
         2: begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp3; pcount:=3; end;
         3: begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp4; pcount:=4; end;
         4: begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp5; pcount:=5; end;
         5: begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp6; pcount:=6; end;
         6: begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp7; pcount:=7; end;
         7: begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp8; pcount:=8; end;
         else begin Form_gwrap.Imagestatus.Picture.Bitmap:=Bp1; pcount:=1; end;
         end;
   end;
end;

procedure TForm_gwrap.Button1Click(Sender: TObject);
begin
Close;
end;

procedure TForm_gwrap.ImageSavePJClick(Sender: TObject);
begin
save_cl;
end;

procedure TForm_gwrap.ButtonCancelClick(Sender: TObject);
begin
Form_gwrap.Close;
end;

procedure TForm_gwrap.ButtonEditName10Click(Sender: TObject);
begin
patheditor:=EditOpenOut;
mpathexplore.visible:=true;
popupmenupath.popup();
end;

procedure TForm_gwrap.ButtonEditName11Click(Sender: TObject);
begin
patheditor:=EditName3;
mpathexplore.visible:=false;
popupmenupath.popup();
end;

procedure TForm_gwrap.ButtonEditName3Click(Sender: TObject);
begin
if SaveDialog2.Execute then
   if SaveDialog2.FileName<>'' then EditName3.Text:=SaveDialog2.FileName
   else exit
else exit;
end;

procedure getoutfolder(var out_param:ansistring);
var
   out_created:boolean;
   s,s1:ansistring;
   i:integer;
begin
out_created:=false;
if Form_gwrap.Checkboxfolder.State=cbchecked then
   begin
   s1:=Form_gwrap.labelfullinput.Caption;
   cutextension(s1);
   s:=out_param+s1;
   i:=0;
   repeat
      if not(directoryexists(s)) then
         try
         forcedirectories(s);
         out_created:=true;
         except
         s:=out_param+'output';
         out_created:=true;
         end
      else
         begin
         i:=i+1;
         s:=out_param+s1+'-'+inttostr(i);
         if i=1000 then //to break recursivity if filename is not valid (ie unsupported character encoding)
            begin
            s:=out_param+'output';
            out_created:=true;
            end;
         end;
      {try
      umkdir(s); //no longer works in Lazarus 0.9.30, mkdir does not raise exception
      out_created:=true;
      except
      i:=i+1;
      s:=out_param+s1+'-'+inttostr(i);
      if i=1000 then //to break recursivity if filename is not valid (ie unsupported character encoding)
         begin
         s:=out_param+'unsupported_name';
         out_created:=true;
         end;
      end;}
   until out_created=true;
   if copy(s,length(s)-1,1)<>directoryseparator then s:=s+directoryseparator;
   out_param:=s;
   end;
end;

procedure clfromname(var in_param,out_param,pw: ansistring);
var
   j:integer;
   P:TProcessUTF8;
   s,jobcode,bin_name,overwrite_policy,archive_function,paq_ver,lpaq_ver,ext,exesubp:ansistring;
   f: file of byte;
begin
   j:=testinput(cl1,true);
   if paramstr(1)='-ext2folder' then Form_gwrap.CheckBoxFolder.State:=cbChecked;
   if PMODE<>'peaextractor' then exesubp:='res'+DirectorySeparator
   else exesubp:='';
   case j of
      0: exit; //unsupported, since custom types can be handled by PeaZip only, and are not passed to PeaLauncher
      1: begin
         out_param:=Form_gwrap.EditOpenOut.Text;
         outpath:=out_param;
         out_param:=delimiter+escapefilename(out_param,desk_env)+delimiter;
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'pea'+EXEEXT+delimiter;
         cl:=(bin_name)+' UNPEA '+in_param+' '+(out_param)+' RESETDATE SETATTR EXTRACT2DIR INTERACTIVE';
         end;
      2: begin
         out_param:=Form_gwrap.EditOpenOut.Text;
         outpath:=out_param;
         out_param:=delimiter+escapefilename(out_param,desk_env)+delimiter;
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'pea'+EXEEXT+delimiter;
         cl:=(bin_name)+' RFJ '+in_param+' BATCH '+(out_param);
         end;
      5: begin
         s:=(cl);
         paq_ver:=copy(extractfileext(s),2,length(extractfileext(s))-1);
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         out_param:=Form_gwrap.EditOpenOut.Text;
         if Form_gwrap.Checkboxfolder.State=cbchecked then getoutfolder(out_param);
         outpath:=out_param;
         if out_param[length(out_param)]=directoryseparator then out_param:=copy(out_param,1,length(out_param)-1);
         out_param:=delimiter+escapefilename(out_param,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'paq'+DirectorySeparator+paq_ver+EXEEXT+delimiter;
         if paq_ver='zpaq' then cl:=(bin_name)+' x '+in_param+' -to '+(out_param)
         else cl:=(bin_name)+' -d '+in_param+' '+(out_param);
         end;
      6: begin
         s:=(cl);
         ext:=copy(extractfileext(s),2,length(extractfileext(s))-1);
         s:=extractfilename(s);
         cutextension(s);
         out_param:=Form_gwrap.EditOpenOut.Text;
         if Form_gwrap.Checkboxfolder.State=cbchecked then getoutfolder(out_param);
         outpath:=out_param;
         out_param:=out_param+s;
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         out_param:=delimiter+escapefilename(out_param,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'quad'+DirectorySeparator+ext+EXEEXT+delimiter;
         if (ext='quad') or (ext='bcm') then cl:=(bin_name)+' -d '+in_param+' '+(out_param)
         else cl:=(bin_name)+' d '+in_param+' '+(out_param);
         end;
      7: begin
         if not(fileexists((peazippath+exesubp+'unace'+directoryseparator+'unace'+EXEEXT))) then
            begin
            MessageDlg(txt_2_5_ace_missing, mtWarning, [mbOK], 0);
            Halt;
            end;
         out_param:=Form_gwrap.EditOpenOut.Text;
         if Form_gwrap.Checkboxfolder.State=cbchecked then getoutfolder(out_param);
         outpath:=out_param;
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         out_param:=delimiter+escapefilename(out_param,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'unace'+DirectorySeparator+'unace'+EXEEXT+delimiter;
         cl:=(bin_name)+' x '+in_param;
         if out_param<>'' then setcurrentdir(out_param);
         end;
      8: begin
         s:=(cl);
         lpaq_ver:=copy(extractfileext(s),2,length(extractfileext(s))-1);
         s:=extractfilename(s);
         cutextension(s);
         out_param:=Form_gwrap.EditOpenOut.Text;
         if Form_gwrap.Checkboxfolder.State=cbchecked then getoutfolder(out_param);
         outpath:=out_param;
         out_param:=out_param+s;
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         out_param:=delimiter+escapefilename(out_param,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'lpaq'+DirectorySeparator+lpaq_ver+EXEEXT+delimiter;
         cl:=(bin_name)+' d '+in_param+' '+(out_param);
         end;
      9: begin
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         out_param:=Form_gwrap.EditOpenOut.Text;
         if Form_gwrap.Checkboxfolder.State=cbchecked then getoutfolder(out_param);
         outpath:=out_param;
         out_param[length(out_param)]:='/';
         out_param:=delimiter+'-dp'+escapefilename(out_param,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'arc'+DirectorySeparator+'arc'+EXEEXT+delimiter;
         if Form_gwrap.Checkboxfolder1.State=cbchecked then archive_function:='e' else archive_function:='x';
         case Form_gwrap.ComboBoxOverwrite.ItemIndex of
            0: overwrite_policy:='-o+';//overwrite
            1: overwrite_policy:='-o-';//skip
            end;
         cl:=(bin_name)+' '+archive_function+' '+overwrite_policy+' '+in_param;//for security and avoid blocking out of console mode, skip existing files is preset as oeverwrite policy
         if pw<>'' then cl:=cl+' '+(pw);
         cl:=cl+' '+(out_param);
         end;
     10: begin
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         out_param:=Form_gwrap.EditOpenOut.Text;
         if Form_gwrap.Checkboxfolder.State=cbchecked then getoutfolder(out_param);
         outpath:=out_param;
         if out_param[length(out_param)]=directoryseparator then out_param:=copy(out_param,1,length(out_param)-1);
         out_param:=delimiter+escapefilename(out_param,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'zpaq'+DirectorySeparator+'zpaq'+EXEEXT+delimiter;
         cl:=bin_name+' x '+in_param;
         end;
      else
         begin
         case Form_gwrap.ComboBoxOverwrite.ItemIndex of
            0: overwrite_policy:='-aou';//auto rename extracting files
            1: overwrite_policy:='-aot';//auto rename existing files
            2: overwrite_policy:='-aoa';//overwrite all existing files
            3: overwrite_policy:='-aos';//skip existing files
            end;
         out_param:=Form_gwrap.EditOpenOut.Text;
         if Form_gwrap.Checkboxfolder.State=cbchecked then getoutfolder(out_param);
         outpath:=out_param;
         out_param:=delimiter+'-o'+escapefilename(out_param,desk_env)+delimiter;
         in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
         bin_name:=delimiter+escapefilename(peazippath,desk_env)+exesubp+'7z'+DirectorySeparator+'7z'+EXEEXT+delimiter;
         if Form_gwrap.Checkboxfolder1.State=cbchecked then archive_function:='e' else archive_function:='x';
         cl:=(bin_name)+' '+archive_function;
         cl:=cl+' '+overwrite_policy;
         cl:=cl+' '+(out_param);
         cl:=cl+' '+(pw);
         cl:=cl+' '+in_param;
         end;
      end;
end;

procedure msg_pw_errorchar;
var
   errchar:ansistring;
begin
{$IFDEF MSWINDOWS}
errchar:='"';
{$ELSE}
errchar:='''';
{$ENDIF}
MessageDlg(errchar+' '+txt_2_3_pw_errorchar_gwrap, mtWarning, [mbOK], 0);
end;

procedure launch_fullmode;
var
   in_param,out_param,pw:ansistring;
begin
pw:=Form_gwrap.EditUn7zaPW.Text;
if Form_gwrap.EditName3.Text<>'' then
   if prepend_keyfile(pw,Form_gwrap.EditName3.Text)<>0 then
      begin
      MessageDlg(Form_gwrap.EditName3.Text+' '+txt_2_3_kf_not_found_gwrap, mtError,[mbOk],0);
      exit;
      end;
if pw<>'' then
   begin
   if pw4cl('-p',pw)<>0 then
      begin
      msg_pw_errorchar;
      exit;
      end;
   end
else pw:='-pdefault';
outpath:=Form_gwrap.EditOpenOut.Text;
clfromname(in_param,out_param,pw);
Form_gwrap.PanelFull2.Visible:=false;
Form_gwrap.Notebook1.visible:=true;
Form_gwrap.ButtonStop.Visible:=true;
Form_gwrap.ButtonStop1.Visible:=true;
Form_gwrap.ButtonPause.Visible:=true;
Form_gwrap.ButtonOK.Visible:=false;
Form_gwrap.ButtonCancel.Visible:=false;
fullmode:=0;
end;

procedure TForm_gwrap.ButtonOkClick(Sender: TObject);
begin
if cl<>'' then launch_fullmode;
end;

procedure TForm_gwrap.ButtonOutputArchiveClick(Sender: TObject);
begin
if SelectDirectoryDialog1.Execute then
   if SelectDirectoryDialog1.FileName<>'' then
      begin
      EditOpenOut.Text:=SelectDirectoryDialog1.FileName;
      if EditOpenOut.Text[length(EditOpenOut.Text)]<>directoryseparator then
         EditOpenOut.Text:=EditOpenOut.Text+directoryseparator;
      end
   else exit
else exit;
end;

procedure TForm_gwrap.ButtonStop1Click(Sender: TObject);
var
   p:TPoint;
begin
p.x:=ButtonStop1.Left;
p.y:=ButtonStop1.top+ButtonStop1.Height;
p:=clienttoscreen(p);
popupmenu1.popup(p.x,p.y);
end;

procedure TForm_gwrap.cbAutoOpenClick(Sender: TObject);
begin
if autoopen=1 then autoopen:=0
else autoopen:=1;
end;

procedure TForm_gwrap.FormDestroy(Sender: TObject);
begin
{$IFDEF MSWINDOWS}CloseHandle(psem);{$ENDIF}
end;

procedure TForm_gwrap.FormDropFiles(Sender: TObject;
  const FileNames: array of String);
var s:ansistring;
begin
s:=escapefilename(FileNames[0],desk_env);
if s<>'' then
   begin
   OpenDialog1.FileName:=s;
   cl:=(OpenDialog1.FileName);
   outpath:=extractfilepath((cl));
   try
      assignfile(f,OpenDialog1.FileName);
      filemode:=0;
      reset(f);
      srcfilesize_multipart(OpenDialog1.FileName,insize);
      closefile(f);
   except
      insize:=0;
   end;
   in_name:=OpenDialog1.FileName;
   preparefull;
   PanelFull1.Visible:=false;
   PanelFull2.Visible:=true;
   end;
end;

procedure TForm_gwrap.FormResize(Sender: TObject);
begin
if Form_gwrap.Width <> 0 then
   ShapeProgress.Width:=(Form_gwrap.Width*iperc) div 100;
imagestatus.Top:=imagefixed.Top-12;
end;

procedure TForm_gwrap.FormShow(Sender: TObject);
begin
set_items_height;
end;

procedure TForm_gwrap.FormWindowStateChange(Sender: TObject);
begin
if pstarted=false then exit;
case autoclose of
   1: if Form_gwrap.WindowState=wsMinimized then
         begin
         autoclose:=4;
         mkdir(confpath+'.minimized')
         end;
   4: begin
      autoclose:=1;
      if directoryexists(confpath+'.minimized') then removedir(confpath+'.minimized');
      Form_gwrap.Visible:=true;
      Form_gwrap.WindowState:=wsNormal;
      Form_gwrap.Position:=poScreenCenter;
      Form_gwrap.Width:=560;
      Form_gwrap.Height:=270;
      Form_gwrap.WindowState:=wsMaximized;
      Form_gwrap.WindowState:=wsNormal;
      fixbringtofront;
      end;
   end;
end;

procedure TForm_gwrap.hbm1Click(Sender: TObject);
var
   pp:TPoint;
begin
      pp.x:=hbm1.Left+hbm1.Width;
      pp.y:=hbm1.top+hbm1.height;
      pp:=clienttoscreen(pp);
      pmmain.Alignment:=paRight;
      pmmain.PopUp(pp.x,pp.y);
      pmmain.Alignment:=paLeft;
end;

procedure TForm_gwrap.hbm2Click(Sender: TObject);
var
   pp:TPoint;
begin
      pp.x:=hbm2.Left+hbm2.Width;
      pp.y:=hbm2.top+hbm2.height;
      pp:=clienttoscreen(pp);
      pmmain.Alignment:=paRight;
      pmmain.PopUp(pp.x,pp.y);
      pmmain.Alignment:=paLeft;
end;

procedure TForm_gwrap.hbm3Click(Sender: TObject);
var
   pp:TPoint;
begin
      pp.x:=hbm3.Left+hbm3.Width;
      pp.y:=hbm3.top+hbm3.height;
      pp:=clienttoscreen(pp);
      pmmain.Alignment:=paRight;
      pmmain.PopUp(pp.x,pp.y);
      pmmain.Alignment:=paLeft;
end;

procedure TForm_gwrap.ImageButton2Click(Sender: TObject);
begin
save_report;
end;

procedure TForm_gwrap.ButtonStopClick(Sender: TObject);
begin
stopped:=true;
end;

procedure toggle_pause;
begin
ppause:=not(ppause);
if ppause=false then
   begin
   Form_gwrap.ButtonPause.Caption:='   '+txt_pause+'   ';
   Form_gwrap.pmpause.Caption:=txt_pause;
   Form_gwrap.LabelTitle1.caption:='      '+txt_isrunning+'      ';
   Form_gwrap.ShapeProgress.Color:=PGREEN;
   end
else
   begin
   Form_gwrap.ButtonPause.Caption:='   '+txt_resume+'   ';
   Form_gwrap.pmpause.Caption:=txt_resume;
   Form_gwrap.LabelTitle1.caption:='      '+txt_status+'      ';
   Form_gwrap.ShapeProgress.Color:=PYELLOW;
   end;
end;

procedure TForm_gwrap.ButtonPauseClick(Sender: TObject);
begin
toggle_pause;
end;

procedure prepare_7zdrop;
begin
with form_gwrap do
   begin
   ComboBoxOverwrite.Clear;
   ComboBoxOverwrite.DropDownCount:=4;
   ComboBoxOverwrite.Items.Append(txt_2_3_renameextracted);
   ComboBoxOverwrite.Items.Append(txt_2_3_renameexisting);
   ComboBoxOverwrite.Items.Append(txt_2_3_overexisting);
   ComboBoxOverwrite.Items.Append(txt_2_3_skipexisting);
   ComboBoxOverwrite.ItemIndex:=3;
   ComboBoxOverwrite.Enabled:=true;
   end;
end;

procedure prepare_arcdrop;
begin
with form_gwrap do
   begin
   ComboBoxOverwrite.Clear;
   ComboBoxOverwrite.DropDownCount:=2;
   ComboBoxOverwrite.Items.Append(txt_2_3_overexisting);
   ComboBoxOverwrite.Items.Append(txt_2_3_skipexisting);
   ComboBoxOverwrite.ItemIndex:=1;
   ComboBoxOverwrite.Enabled:=true;
   end;
end;

function wingetappdata(var s:ansistring):integer;
{$IFDEF MSWINDOWS}
var
  pidl: PItemIDList;
  Buf: array [0..MAX_PATH] of Char;
{$ENDIF}
begin
wingetappdata:=-1;
{$IFDEF MSWINDOWS}
try
   if Succeeded(ShGetSpecialFolderLocation(Form_gwrap.Handle,26,pidl)) then //26 is CSIDL_APPDATA numerical value
      if ShGetPathfromIDList(pidl, Buf ) then
         begin
         s:=(Buf)+'\PeaZip\';
         CoTaskMemFree(pidl);
         wingetappdata:=0;
         end
      else CoTaskMemFree(pidl);
except
end;
{$ENDIF}
end;

procedure preparefull;
var
   j:integer;
begin
with form_gwrap do
begin
Form_gwrap.Visible:=true;
Form_gwrap.WindowState:=wsNormal;
cl1:=(cl);
j:=testinput(cl1,true);
case j of
   3: prepare_7zdrop;
   4: prepare_7zdrop;
   9: prepare_arcdrop;
   else ComboBoxOverwrite.Enabled:=false;
end;
if paramstr(1)='' then PanelFull1.Visible:=true
else PanelFull2.Visible:=true;
Notebook1.visible:=false;
ButtonStop.Visible:=false;
ButtonStop1.Visible:=false;
ButtonPause.Visible:=false;
ButtonOK.Visible:=true;
if cl<>'' then ButtonOk.Enabled:=true else ButtonOk.Enabled:=false;
ButtonCancel.Visible:=true;
EditOpenOut.Text:=outpath;
Form_gwrap.caption:=extractfilename((cl))+' ('+nicenumber(inttostr(insize))+')';
labelfullinput.caption:=extractfilename((cl));
//labelfullsize.caption:=' ('+nicenumber(inttostr(insize))+')';
end;
end;

procedure clearstopsequencefile;
begin
if fileexists(fget_usrtmp_path+STR_STOPALL) then
try
udeletefile (fget_usrtmp_path+STR_STOPALL);
except
sleep(500);
udeletefile (fget_usrtmp_path+STR_STOPALL);
end;
end;

procedure TForm_gwrap.FormCreate(Sender: TObject);
var
   i,j:integer;
   s,theme_name,testcl:ansistring;
begin
launched:=true;//prevent the timer to launch cl, in case it starts before variables are valorized
pstarted:=false;
ended:=false;
launchwithsemaphore:=false;
Button1.Visible:=false;
Form_gwrap.Label5.Visible:=false;
Form_gwrap.Label6.Visible:=false;
if PMODE<>'peaextractor' then
   begin
   mmlang.visible:=false;
   mmlangsysmenu.visible:=false;
   mmsp1.visible:=false;
   end;
ppriority:=0;
iperc:=1;
getdesk_env(desk_env,caption_build,delimiter);
executable_path:=extractfilepath((paramstr(0)));
if executable_path[length(executable_path)]<>directoryseparator then executable_path:=executable_path+directoryseparator;
setcurrentdir(executable_path);
peazippath:=executable_path;
if PMODE<>'peaextractor' then
   begin
   if peazippath[length(peazippath)]=directoryseparator then setlength(peazippath,length(peazippath)-1);
   peazippath:=extractfilepath(peazippath);
   end;

//get job type 0 archive/extract 1 test; 2 benchmark; (3 defrag, unused); 4 info (list and give message); 5 list and verbose list; 20 archive/extract, not using pipes, visible console (mode 10 was removed)
try
modeofuse:=strtoint(paramstr(1));
fullmode:=0;
automode:=0;
insize:=0;
if modeofuse>=1000 then
   begin
   launchwithsemaphore:=true;
   modeofuse:=modeofuse-1000;
   end;
case modeofuse of
   100: begin fullmode:=1; modeofuse:=0; end;
   120: begin fullmode:=1; modeofuse:=20; end;
   end;
except
   fullmode:=1;
   modeofuse:=0;
   automode:=1;
end;
case modeofuse of
   0: max_l:=1024;//1024
   1,4,5: max_l:=1024;
   2: max_l:=32;
   3: max_l:=32;
   end;
//use semaphore if needed to limit job execution to one instance
getschedule;
if launchwithsemaphore=true then mCancelAll.Enabled:=false;
//get selected input size and input file size
tinsize:=0;
if automode=0 then
   try
      if paramstr(3)<>'na' then
         begin
         srcfilesize_multipart((paramstr(3)),tinsize);
         in_name:=paramstr(3);
         end
      else in_name:='';
      insize:=strtoqword(paramstr(2));
   except
      insize:=0;
   end
else
   if paramcount>0 then
      begin
      if (paramstr(1)='-ext2here') or (paramstr(1)='-ext2folder') or (paramstr(1)='-ext2multi') then //automode: set s = paramstr 2 if performing "extract here", else s = paramstr 1
         if paramcount>1 then s:=paramstr(2)
         else
      else s:=paramstr(1);
      try
         assignfile(f,(s));
         filemode:=0;
         reset(f);
         srcfilesize_multipart((s),insize);
         closefile(f);
      except
         insize:=0;
      end;
      end;
ShapeProgress.Color:=PGREEN;
if insize > 0 then
   begin
   incstep1:=80000000000 div insize;
   incstep2:=120000000000 div insize;
   incstep3:=40000000000 div insize;
   if incstep1=0 then incstep1:=1;
   if incstep2=0 then incstep2:=1;
   if incstep3=0 then incstep3:=1;
   end
else
   begin
   incstep1:=2000;
   incstep2:=4000;
   incstep3:=1000;
   end;
if insize=0 then
   begin
   Form_gwrap.Labeli.Visible:=false;
   Form_gwrap.LabelInfo1.Visible:=false;
   end;
Form_gwrap.Labelo.Visible:=false;
Form_gwrap.LabelInfo2.Visible:=false; //set visible during progress

//get output path (finalized only when invoked)
if automode=0 then
   outpath:=(paramstr(4))
else
   if paramcount>0 then
      outpath:=extractfilepath((s));

//get cl
cl:='';
if automode=0 then
   begin
   if fullmode<>1 then
      begin
      for i:=5 to paramcount do
         if pos(' ',paramstr(i))<>0 then cl:=cl+delimiter+paramstr(i)+delimiter+' '
         else cl:=cl+paramstr(i)+' ';
      end
   else
      cl:=paramstr(5);
   end
else
   if paramcount>0 then cl:=s;

   {testcl:=utf8decode(cl);
   if pos('?',testcl)=0 then cl:=utf8decode(cl);}
   cl:=(cl);

try
   assignfile(conf,executable_path+'altconf.txt'); //load alternative configuration path
   filemode:=0;
   reset(conf);
   read_header(conf);
   readln(conf,dummy);
   readln(conf,confpath);
   CloseFile(conf);
   if (confpath='same') or (confpath='"same"') or (confpath='''same''') or (confpath=' ') or (confpath='') then confpath:=executable_path; //if confpath parameter is set to 'same' or empty use classic conf location (in res folder)
   {$IFDEF MSWINDOWS}
   if (confpath='appdata') or (confpath='"appdata"') or (confpath='''appdata''') or (confpath='%appdata%') then
      if wingetappdata(confpath)<>0 then confpath:=(GetEnvironmentVariable('APPDATA'))+'\PeaZip\'; //if wingetappdata fails use env variables
   {$ELSE}
   mmrunasadmin.visible:=false;
   mmsp2.visible:=false;
   {$ENDIF}
   {$IFDEF LINUX}
   if (confpath='appdata') or (confpath='"appdata"') or (confpath='''appdata''') or (confpath='%appdata%') then confpath:=GetEnvironmentVariable('HOME')+'/.PeaZip/';
   {$ENDIF}
   {$IFDEF FREEBSD}
   if (confpath='appdata') or (confpath='"appdata"') or (confpath='''appdata''') or (confpath='%appdata%') then confpath:=GetEnvironmentVariable('HOME')+'/.PeaZip/';
   {$ENDIF}
   {$IFDEF NETBSD}
   if (confpath='appdata') or (confpath='"appdata"') or (confpath='''appdata''') or (confpath='%appdata%') then confpath:=GetEnvironmentVariable('HOME')+'/.PeaZip/';
   {$ENDIF}
   if not(directoryexists(confpath)) then forcedirectories(confpath);
   if (confpath[1]='.') and (confpath[2]='.') then confpath:='..'+directoryseparator+confpath; //relative path, needs to be adjusted since pealauncher is in a subfolder of peazip path
   confpath:=expandfilename(confpath);
   if confpath[length(confpath)]<>directoryseparator then confpath:=confpath+directoryseparator;
   if not(directoryexists(confpath)) then confpath:=executable_path; //if alternative configuration directory does not exist or is not accessible, use res path
   if PMODE='peaextractor' then
      begin
      graphicsfolder:='themes'+directoryseparator+DEFAULT_THEME+directoryseparator;
      dodirseparators(graphicsfolder);
      opacity:=100;
      color1:=colortostring(clWindow);
      color2:=colortostring(clBtnFace);
      color3:=colortostring(clBtnFace);
      color4:='$00669999';
      color5:=colortostring(clWindowText);
      autoclose:=1;
      autoopen:=0;
      cbAutoClose.State:=cbUnchecked;
      try
      assignfile(conf,(confpath+'conf-extractor.txt'));
      filemode:=0;
      reset(conf);
      read_header(conf);
      readln(conf,lang_file);
      CloseFile(conf);
      except
      assignfile(conf,(confpath+'conf-extractor.txt'));
      rewrite(conf);
      write_header(conf);
      writeln(conf,'default.txt');
      CloseFile(conf);
      end;
      end
   else
   begin
   assignfile(conf,(confpath+'conf.txt'));
   filemode:=0;
   reset(conf);
   readln(conf,dummy);
   readln(conf,graphicsfolder);
   if graphicsfolder[1]='r' then graphicsfolder:='themes'+directoryseparator+DEFAULT_THEME+directoryseparator;
   readln(conf,dummy); opacity:=strtoint(dummy);
   readln(conf,color1);
   readln(conf,color2);
   readln(conf,color3);
   readln(conf,color4);
   readln(conf,color5);
   readln(conf,dummy);
   //rowheight:=strtoint(dummy);
   readln(conf,dummy);
   //itemheight:=strtoint(dummy);
   readln(conf,dummy);
   //autosizeitemheight:=strtoint(dummy);
   readln(conf,dummy);
   readln(conf,dummy);
   readln(conf,lang_file);
   readln(conf,dummy);
   readln(conf,dummy);
   readln(conf,dummy);
   autoclose:=strtoint(dummy);
   readln(conf,dummy);
   readln(conf,dummy);
   readln(conf,dummy);
   autoopen:=strtoint(dummy);
   CloseFile(conf);
   if opacity<0 then opacity:=0;
   if opacity>100 then opacity:=100;
   if color1='' then color1:=colortostring(clWindow);
   if color2='' then color2:=colortostring(clBtnFace);
   if color3='' then color3:=colortostring(clBtnFace);
   if color4='' then color4:='$00669999';
   if color5='' then color5:=colortostring(clWindowText);
   //if (rowheight<12) or (rowheight>32) then rowheight:=18;
   //if (itemheight<12) or (itemheight>32) then itemheight:=21;
   //if (autosizeitemheight<0) or (autosizeitemheight>1) then autosizeitemheight:=1;
   if (autoclose<0) or (autoclose>3) then autoclose:=1;
   if (autoopen<0) or (autoopen>1) then autoopen:=0;
   end;
except
   graphicsfolder:='themes'+directoryseparator+DEFAULT_THEME+directoryseparator;
   dodirseparators(graphicsfolder);
   opacity:=100;
   color1:=colortostring(clWindow);
   color2:=colortostring(clBtnFace);
   color3:=colortostring(clBtnFace);
   color4:='$00669999';
   color5:=colortostring(clWindowText);
   //rowheight:=18;
   //itemheight:=21;
   //autosizeitemheight:=1;
   autoclose:=1;
   autoopen:=0;
   cbAutoClose.State:=cbUnchecked;
   lang_file:='default.txt';
end;
if autoclose=1 then if directoryexists(confpath+'.minimized') then autoclose:=4;
if (autoclose<>2) and (autoclose<>4) then
   begin
   Form_gwrap.Visible:=true;
   Form_gwrap.WindowState:=wsNormal;
   Form_gwrap.Position:=poScreenCenter;
   Form_gwrap.Width:=560;
   Form_gwrap.Height:=270;
   end;
{$IFDEF MSWINDOWS}getwinenv(wincomspec,winver);{$ENDIF}
apply_theme;
load_icons;
texts(lang_file);
if fullmode=1 then preparefull;
Form_gwrap.caption:=txt_4_0_dragorselect;
if automode=1 then Label4.visible:=false;
if (opacity<100) then
   begin
   Form_gwrap.AlphaBlend:=true;
   Form_gwrap.AlphaBlendValue:=255+opacity-100;
   end;
clearstopsequencefile;
stopped:=false;
launched:=false;
if automode=1 then
   if (paramstr(1)='-ext2here') or (paramstr(1)='-ext2folder') then
      begin
      in_name:=paramstr(2);
      preparefull;
      PanelFull1.Visible:=false;
      PanelFull2.Visible:=true;
      launch_fullmode; //automode: launch process immediately if "extract here" is requested
      end
   else
      begin
      if paramcount>0 then
         begin
         in_name:=paramstr(1);
         preparefull;
         PanelFull1.Visible:=false;
         PanelFull2.Visible:=true;
         end;
      end;
end;

procedure TForm_gwrap.l2Click(Sender: TObject);
begin
explore_in;
end;

procedure TForm_gwrap.l4Click(Sender: TObject);
begin
explore_out;
end;

procedure TForm_gwrap.Label4Click(Sender: TObject);
var
   P:TProcessUTF8;
   bin_name,in_param:ansistring;
begin
P:=TProcessUTF8.Create(nil);
in_param:=delimiter+escapefilename(cl,desk_env)+delimiter;
bin_name:=delimiter+escapefilename(peazippath,desk_env)+'peazip'+EXEEXT+delimiter;
{$IFDEF MSWINDOWS}P.Options := [poNoConsole];{$ELSE}P.Options := [poNoConsole, poWaitOnExit];{$ENDIF}
cl:=bin_name+' -ext2open '; //ext2open handles a single input in open interface
cl:=(cl);
cl:=cl+in_param;//(cl was not trasformed in utf8 before)
P.CommandLine:=cl;
if validatecl(cl)<>0 then begin MessageDlg(txt_2_7_validatecl+' '+cl, mtWarning, [mbOK], 0); exit; end;
P.Execute;
P.Free;
Application.Terminate;
end;

procedure cp_search(desk_env:byte);
begin
{$IFDEF MSWINDOWS}
if winver='nt6+' then
   shellexecutew(Form_gwrap.handle, PWideChar('find'), PWideChar(''), PWideChar(''), PWideChar (''), SW_SHOWNORMAL)
else
   cp_open(executable_path+'res'+directoryseparator+'empty.fnd',desk_env);
{$ENDIF}
{$IFDEF LINUX}cp_search_linuxlike(desk_env);{$ENDIF}//try to search via Gnome or KDE
{$IFDEF FREEBSD}cp_search_linuxlike(desk_env);{$ENDIF}
{$IFDEF NETBSD}cp_search_linuxlike(desk_env);{$ENDIF}
end;

procedure TForm_gwrap.labelopenfile0Click(Sender: TObject);
begin
cp_search(desk_env);
end;

procedure TForm_gwrap.labelopenfile2Click(Sender: TObject);
begin
if OpenDialog1.execute then
   if OpenDialog1.FileName<>'' then
      begin
      cl:=(OpenDialog1.FileName);
      outpath:=extractfilepath((cl));
      try
         assignfile(f,OpenDialog1.FileName);
         filemode:=0;
         reset(f);
         srcfilesize_multipart(OpenDialog1.FileName,insize);
         closefile(f);
      except
         insize:=0;
      end;
      in_name:=OpenDialog1.FileName;
      preparefull;
      PanelFull1.Visible:=false;
      PanelFull2.Visible:=true;
      end;
end;

procedure TForm_gwrap.LabelTitle1Click(Sender: TObject);
begin
clicklabel_launcher(LabelTitle1);
end;

procedure TForm_gwrap.LabelTitle1MouseEnter(Sender: TObject);
begin
enterlabel_launcher(LabelTitle1);
end;

procedure TForm_gwrap.LabelTitle1MouseLeave(Sender: TObject);
begin
exitlabel_launcher(LabelTitle1);
end;

procedure TForm_gwrap.LabelTitle2Click(Sender: TObject);
begin
clicklabel_launcher(LabelTitle2);
end;

procedure TForm_gwrap.LabelTitle2MouseEnter(Sender: TObject);
begin
enterlabel_launcher(LabelTitle2);
end;

procedure TForm_gwrap.LabelTitle2MouseLeave(Sender: TObject);
begin
exitlabel_launcher(LabelTitle2);
end;

procedure TForm_gwrap.LabelTitle3Click(Sender: TObject);
begin
clicklabel_launcher(LabelTitle3);
end;

procedure TForm_gwrap.LabelTitle3MouseEnter(Sender: TObject);
begin
enterlabel_launcher(LabelTitle3);
end;

procedure TForm_gwrap.LabelTitle3MouseLeave(Sender: TObject);
begin
exitlabel_launcher(LabelTitle3);
end;

procedure TForm_gwrap.LabelTitle4Click(Sender: TObject);
begin
clicklabel_launcher(LabelTitle4);
end;

procedure TForm_gwrap.LabelTitle4MouseEnter(Sender: TObject);
begin
enterlabel_launcher(LabelTitle4);
end;

procedure TForm_gwrap.LabelTitle4MouseLeave(Sender: TObject);
begin
exitlabel_launcher(LabelTitle4);
end;

procedure TForm_gwrap.LabelWarning1Click(Sender: TObject);
var s:ansistring;
begin
clicklabel_launcher(LabelTitle2);
if (modeofuse=1) or (modeofuse=4) or (modeofuse=5) then s:=txt_3_0_arc+char($0D)+char($0A)+txt_3_0_ext
else
   if extractfilename(outpath)='' then s:=txt_3_0_arc+char($0D)+char($0A)+txt_3_0_ext
   else s:=txt_3_0_arc;
s:=s+char($0D)+char($0A)+txt_3_0_details;
if stopped=true then s:=txt_jobstopped+char($0D)+char($0A)+txt_3_0_details;
MessageDlg(s, mtWarning, [mbOK], 0);
end;

procedure TForm_gwrap.LabelWarning2Click(Sender: TObject);
begin
panel4.visible:=not(panel4.visible);
end;

procedure TForm_gwrap.mCancelAllClick(Sender: TObject);
var
  pstopfile:file of byte;
begin
assignfile(pstopfile,fget_usrtmp_path+STR_STOPALL);
rewrite(pstopfile);
closefile(pstopfile);
stopped:=true;
end;

procedure TForm_gwrap.MenuItem1Click(Sender: TObject);
begin
ppriority:=1;
end;

procedure TForm_gwrap.MenuItem2Click(Sender: TObject);
begin
ppriority:=2;
end;

procedure TForm_gwrap.MenuItem3Click(Sender: TObject);
begin
ppriority:=3;
end;

procedure TForm_gwrap.MenuItem4Click(Sender: TObject);
begin
ppriority:=4;
end;

procedure TForm_gwrap.mainmenuhelpClick(Sender: TObject);
begin
cp_open('http://www.peazip.org/peazip-help.html',desk_env);
end;

procedure TForm_gwrap.mmdonationsClick(Sender: TObject);
begin
cp_open('http://www.peazip.org/donations.html',desk_env);
end;

procedure TForm_gwrap.mmlangsysmenuClick(Sender: TObject);
begin
if PMODE<>'peaextractor' then exit;
//MessageDlg(txt_5_3_cmlmessage, mtInformation, [mbOk], 0);
cp_open(executable_path+'lang-wincontext'+directoryseparator,desk_env);
end;

procedure TForm_gwrap.mmrunasadminClick(Sender: TObject);
var
   w:widestring;
begin
{$IFDEF MSWINDOWS}
w:=utf8decode('"'+executable_path+PMODE+'.exe"');
ShellExecuteW(Form_gwrap.Handle, PWideChar ('runas'), PWideChar(w), PWideChar (''), PWideChar (''), SW_SHOWNORMAL);
Close;
{$ENDIF}
end;

procedure TForm_gwrap.mmlangClick(Sender: TObject);
var
   P:TProcessUTF8;
   cl:ansistring;
begin
if PMODE<>'peaextractor' then exit;
Form_gwrap.OpenDialog2.InitialDir:=executable_path+'lang'+directoryseparator;
if Form_gwrap.OpenDialog2.execute then
   if Form_gwrap.OpenDialog2.FileName<>'' then
      begin
      lang_file:=extractfilename(Form_gwrap.OpenDialog2.FileName);
      try
      assignfile(conf,(confpath+'conf-extractor.txt'));
      rewrite(conf);
      write_header(conf);
      writeln(conf,lang_file);
      CloseFile(conf);
      except
         try
         CloseFile(conf);
         except
         end;
      end;
      P:=TProcessUTF8.Create(nil);
      cl:=delimiter+executable_path+'peaextractor'+EXEEXT+delimiter;
      cl:=(cl);
      P.CommandLine:=cl;
      if validatecl(cl)<>0 then begin MessageDlg(txt_2_7_validatecl+' '+cl, mtWarning, [mbOK], 0); exit; end;
      P.Execute;
      P.Free;
      Form_gwrap.Close;
      end
   else exit
else exit;
end;

procedure TForm_gwrap.mmupdateClick(Sender: TObject);
begin
cp_open('http://www.peazip.org/',desk_env);
end;

procedure TForm_gwrap.mmhelpClick(Sender: TObject);
begin
cp_open('http://www.peazip.org/peazip-help.html',desk_env);
end;

procedure TForm_gwrap.mpathexploreClick(Sender: TObject);
var
   s:ansistring;
begin
s:=patheditor.Text;
if s='' then exit;
if s[1]='<' then exit;
s:=extractfilepath(s);
cp_open(s,desk_env);
end;

procedure TForm_gwrap.mpathresetClick(Sender: TObject);
begin
EditUn7zaPW.Caption:='';
patheditor.Text:='';
if patheditor=EditOpenOut then EditOpenOut.Text:=outpath;
end;

procedure TForm_gwrap.pmeiClick(Sender: TObject);
begin
explore_in;
end;

procedure TForm_gwrap.pmeoClick(Sender: TObject);
begin
explore_out;
end;

procedure do_explorepath;
begin
{$IFDEF MSWINDOWS}
if winver<>'nt6+' then
   ShellExecuteW(Form_gwrap.Handle, PWideChar  ('open'), PWideChar ('Explorer'), PWideChar  (''), PWideChar  (''), SW_SHOWNORMAL)
else
   ShellExecuteW(Form_gwrap.Handle, PWideChar  ('open'), PWideChar ('Explorer'), PWideChar  ('/E,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}'), PWideChar  (''), SW_SHOWNORMAL);
{$ELSE}
cp_open('/',desk_env);
{$ENDIF}
end;

procedure TForm_gwrap.pmexploreClick(Sender: TObject);
begin
do_explorepath;
end;

procedure TForm_gwrap.pmpauseClick(Sender: TObject);
begin
toggle_pause;
end;

procedure TForm_gwrap.pmsearchClick(Sender: TObject);
begin
cp_search(desk_env);
end;

procedure TForm_gwrap.pmstopClick(Sender: TObject);
begin
stopped:=true;
end;

initialization
  {$I unit_gwrap.lrs}

  {$IFDEF MSWINDOWS}
  OleInitialize(nil);
  {$ENDIF}

finalization
  {$IFDEF MSWINDOWS}
  OleUninitialize
  {$ENDIF}

end.

