unit RemoveForms;
interface
uses
{$IFDEF WIN32}
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, Buttons, IniFiles, ExtCtrls;
{$ENDIF}
{$IFDEF LINUX}
SysUtils, Variants, Classes, QGraphics, QControls, QForms,
QDialogs, QComCtrls, QStdCtrls, QButtons, IniFiles, QExtCtrls;
{$ENDIF}
type
TRemoveForm = class(TForm)
Animate1: TAnimate;
Label1: TLabel;
GroupBox1: TGroupBox;
ProgressBar1: TProgressBar;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
BitBtn1: TBitBtn;
Timer1: TTimer;
Image1: TImage;
procedure Timer1Timer(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
Abort: Boolean;
Entry: AnsiString;
CloseWhenDone: Boolean;
ReqVersion: AnsiString;
end;
var
RemoveForm: TRemoveForm;
implementation
uses
PackmanUtils;
{$R *.dfm}
procedure RemoveDirsRec(dir: AnsiString);
//this file removes all empty directories up to the root of dev-c++
//for example if files are installed only in c:\dev-cpp\a\b\c\*.*
//it will attempt to delete c, b, a if not empty
var
strDevRoot: AnsiString;
tempDirs: TStrings;
i: Integer;
begin
{$MESSAGE 'this will not work in Linux'}
strDevRoot := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));
//make relative path if file is within dev-c++ root
if Pos(strDevRoot, dir) = 1 then
Delete(dir, 1, Length(strDevRoot));
if Length(dir) < 1 then
Exit
else if Length(dir) = 1 then
begin
RemoveDir(dir);
Exit;
end
else if (dir[1] = '\') or (dir[2] = ':') then
begin
//full path outside of dev-c++ root
RemoveDir(dir);
Exit;
end;
if Copy(dir, length(dir), 1) = '\' then
Delete(dir, Length(dir), 1);
tempDirs := TStringList.Create;
with tempDirs do
begin
Delimiter := '\';
DelimitedText := dir;
for i := Count -1 downto 0 do
begin
RemoveDir(DelimitedText);
Delete(i);
end;
Free;
end;
end;
procedure TRemoveForm.Timer1Timer(Sender: TObject);
var
Ini: TIniFile;
Files, Dirs: TStringList;
i, IMod: Integer;
currdir: AnsiString;
begin
Timer1.Enabled := False;
Abort := False;
Label1.Caption := 'Reading file list...';
Application.ProcessMessages;
{ Read entry information }
Ini := TIniFile.Create(Entry);
Caption := Format(Caption,
[Ini.ReadString('Setup', 'AppName', '')]);
if (ReqVersion = '')
or (ReqVersion = Ini.ReadString('Setup', 'AppVersion', '')) then
begin
Files := TStringList.Create;
Files.LoadFromFile(Entry);
Dirs := TStringList.Create;
for i := 0 to Files.Count - 1 do
begin
if CompareText(Files.Strings[0], '[Files]') = 0 then
begin
Files.Delete(0);
Break;
end else
Files.Delete(0);
end;
Application.ProcessMessages;
ProgressBar1.Max := Files.Count;
Label5.Caption := IntToStr(Files.Count);
{ Delete the files }
IMod := CalcMod(Files.Count);
currdir := GetCurrentDir;
SetCurrentDir(ExtractFilePath(ParamStr(0)));
for i := 0 to Files.Count - 1 do
begin
if Abort then
begin
Abort := False;
BorderIcons := BorderIcons + [biSystemMenu];
Caption := 'Aborted';
Label1.Caption := 'Aborted.';
Animate1.Active := False;
BitBtn1.Kind := bkClose;
BitBtn1.Default := True;
BitBtn1.OnClick := nil;
Exit;
end;
Label1.Caption := 'Deleting file ' + ExtractFileName(Files.Strings[i]);
DeleteFile(Files.Strings[i]);
if Dirs.IndexOf(ExtractFileDir(Files.Strings[i])) = -1 then
Dirs.Add(ExtractFileDir(Files.Strings[i]));
if (IMod = 0) or (i mod IMod = 0) then
begin
ProgressBar1.Position := i + 1;
GroupBox1.Caption := 'Progress (' +
IntToStr(Round(i / (Files.Count / 100)) + 1) + '%)';
Label6.Caption := IntToStr(i + 1);
Label7.Caption := IntToStr(Files.Count - i - 1);
Application.ProcessMessages;
end;
end;
Label1.Caption := 'Removing empty directories...';
Dirs.CaseSensitive := False;
for i := Dirs.Count - 1 downto 0 do
begin
if Abort then
begin
Abort := False;
BorderIcons := BorderIcons + [biSystemMenu];
Caption := 'Aborted';
Label1.Caption := 'Aborted.';
Animate1.Active := False;
BitBtn1.Kind := bkClose;
BitBtn1.Default := True;
BitBtn1.OnClick := nil;
Exit;
end;
RemoveDirsRec(Dirs.Strings[i]);
if (IMod = 0) or (i mod IMod = 0) then
Application.ProcessMessages;
end;
SetCurrentDir(currdir);
Label1.Caption := 'Removing package entry...';
DeleteFile(Entry);
Application.ProcessMessages;
Caption := 'Finished removing ' + Ini.ReadString('Setup', 'AppName', '');
GroupBox1.Caption := 'Progress (100%)';
Label1.Caption := 'Finished.';
Animate1.Active := False;
BorderIcons := BorderIcons + [biSystemMenu];
Abort := False;
Ini.Free;
Files.Free;
Dirs.Free;
end; //if ReqVersion
BitBtn1.Kind := bkOK;
BitBtn1.OnClick := nil;
if CloseWhenDone then
begin
ModalResult := mrOK;
Close;
end;
end;
procedure TRemoveForm.BitBtn1Click(Sender: TObject);
begin
if Application.MessageBox('Do you really want to abort removal?' + #13#10 +
'Because some files are already deleted, the package may not function ' +
'correctly.', 'Confirmation', MB_ICONQUESTION + MB_YESNO) = 6 then
Abort := True;
end;
procedure TRemoveForm.FormCreate(Sender: TObject);
begin
CloseWhenDone := False;
ReqVersion := '';
end;
end.