Ignore:
Timestamp:
May 14, 2010, 7:03:09 AM (15 years ago)
Author:
george
Message:
  • Upraveno: Změna podpory pro Lazarus.
  • Upraveno: Přepracovány struktury tříd do čistější podoby.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • JobProgressView/UJobProgressView.pas

    r2 r22  
    11unit UJobProgressView;
    22
     3{$MODE Delphi}
     4
    35interface
    46
    57uses
    6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    7   Dialogs, ImgList, ComCtrls, StdCtrls, ExtCtrls;
     8  SysUtils, Variants, Classes, Graphics, Controls, Forms,
     9  Dialogs, ComCtrls, StdCtrls, ExtCtrls;
     10
     11const
     12  EstimatedTimeShowTreshold = 4;
    813
    914type
    10   TMethod = procedure(Thread: TThread) of object;
     15
     16  { TProgress }
     17
     18  TProgress = class
     19  private
     20    FOnChange: TNotifyEvent;
     21    FValue: Integer;
     22    FMax: Integer;
     23    procedure SetMax(const AValue: Integer);
     24    procedure SetValue(const AValue: Integer);
     25  public
     26    procedure Increment;
     27    procedure Reset;
     28    constructor Create;
     29    property Value: Integer read FValue write SetValue;
     30    property Max: Integer read FMax write SetMax;
     31    property OnChange: TNotifyEvent read FOnChange write FOnChange;
     32  end;
     33
     34  TJobProgressView = class;
     35  TJobThread = class;
     36  TJob = class;
     37
     38  TJobProgressViewMethod = procedure(Job: TJob) of object;
     39
     40  { TJob }
     41
     42  TJob = class
     43    StartTime: TDateTime;
     44    EndTime: TDateTime;
     45    ProgressView: TJobProgressView;
     46    Title: string;
     47    Method: TJobProgressViewMethod;
     48    Direct: Boolean;
     49    WaitFor: Boolean;
     50    Terminate: Boolean;
     51    Progress: TProgress;
     52    Thread: TJobThread;
     53    constructor Create;
     54    destructor Destroy; override;
     55  end;
    1156
    1257  TJobThread = class(TThread)
    1358    procedure Execute; override;
     59  private
     60    ExceptionText: string;
    1461  public
    15     ExceptionText: string;
    16     Index: Integer;
    17     Title: string;
    18     Method: TMethod;
    19   end;
     62    ProgressView: TJobProgressView;
     63    Job: TJob;
     64  end;
     65
     66  { TJobProgressView }
    2067
    2168  TJobProgressView = class(TForm)
     
    2673    Label2: TLabel;
    2774    Timer1: TTimer;
    28     Label3: TLabel;
    29     Animate1: TAnimate;
     75    LabelEstimatedTime: TLabel;
    3076    procedure Timer1Timer(Sender: TObject);
    3177    procedure FormCreate(Sender: TObject);
    3278    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    3379  private
    34     //FLastProgress: Real;
    35     FProgress: Real;
    36     FPosition: Integer;
    37     Jobs: array of record
    38       Method: TMethod;
    39       Direct: Boolean;
    40     end;
    41     Job: TJobThread;
    42     WindowList: Pointer;
    43     StartTime: TDateTime;
    44     procedure SetProgress(Value: Real);
     80    FTerminate: Boolean;
     81    procedure SetTerminate(const AValue: Boolean);
     82    //WindowList: Pointer;
    4583    procedure UpdateProgress;
     84    procedure ReloadJobList;
    4685  public
    47     Terminate: Boolean;
    48     procedure AddJob(Title: string; Method: TMethod; Direct: Boolean = False);
     86    Jobs: TList; // of TJob
     87    CurrentJob: TJob;
     88    constructor Create(TheOwner: TComponent); override;
     89    destructor Destroy; override;
     90    procedure Clear;
     91    procedure AddJob(Title: string; Method: TJobProgressViewMethod;
     92      Direct: Boolean = False; WaitFor: Boolean = False);
    4993    procedure Start;
    5094    procedure Stop;
    5195    procedure TermSleep(Delay: Integer);
    52     property Progress: Real read FProgress write SetProgress;
    53   end;
    54 
    55 var
    56   JobProgressView: TJobProgressView;
     96    property Terminate: Boolean read FTerminate write SetTerminate;
     97  end;
    5798
    5899implementation
    59100
    60 {$R *.dfm}
     101{$R *.lfm}
    61102
    62103procedure TJobThread.Execute;
     
    65106  try
    66107    //raise Exception.Create('dsds');
    67     Method(Self);
     108    Job.Method(Self.Job);
    68109    Terminate;
    69110  except
    70111    on E:Exception do begin
    71       ExceptionText := 'V úloze "' + Title + '" došlo k vyjímce: ' + E.Message;
     112      ExceptionText := 'V úloze "' + Job.Title + '" došlo k vyjímce: ' + E.Message;
    72113      Terminate;
    73114    end;
     
    75116end;
    76117
    77 procedure TJobProgressView.AddJob(Title: string; Method: TMethod; Direct: Boolean = False);
    78 var
    79   NewItem: TListItem;
    80 begin
    81   with ListView1, Items do begin
    82     BeginUpdate;
    83     NewItem := Add;
    84     with NewItem do begin
    85       Caption := Title;
    86       ImageIndex := 2;
     118procedure TJobProgressView.AddJob(Title: string; Method: TJobProgressViewMethod;
     119  Direct: Boolean = False; WaitFor: Boolean = False);
     120var
     121  NewJob: TJob;
     122begin
     123  NewJob := TJob.Create;
     124  NewJob.ProgressView := Self;
     125  NewJob.Title := Title;
     126  NewJob.Method := Method;
     127  NewJob.Direct := Direct;
     128  NewJob.WaitFor := WaitFor;
     129  NewJob.Progress.Max := 100;
     130  NewJob.Progress.Reset;
     131  Jobs.Add(NewJob);
     132  ReloadJobList;
     133end;
     134
     135procedure TJobProgressView.Start;
     136var
     137  LocalExceptionText: string;
     138  JobThread: TJobThread;
     139  I: Integer;
     140begin
     141  Caption := 'Prosím čekejte...';
     142  try
     143    //WindowList := DisableTaskWindows(0);
     144    Height := 100 + 18 * Jobs.Count;
     145    //Show;
     146    Timer1.Enabled := True;
     147    // Timer1Timer(Self);
     148    for I := 0 to Jobs.Count - 1 do
     149    with TJob(Jobs[I]) do begin
     150      CurrentJob := Jobs[I];
     151      StartTime := Now;
     152      ListView1.Items.Item[I].ImageIndex := 1;
     153      LabelEstimatedTime.Caption := '';
     154      ProgressBar1.Position := 0;
     155      Application.ProcessMessages;
     156      if Direct then Method(CurrentJob) else begin
     157        JobThread := TJobThread.Create(True);
     158        with JobThread do begin
     159          Job := CurrentJob;
     160          ProgressView := Self;
     161          Resume;
     162          while not Terminated do begin
     163            Application.ProcessMessages;
     164            Sleep(1);
     165          end;
     166          WaitFor;
     167          LocalExceptionText := ExceptionText;
     168          Free;
     169        end;
     170        if LocalExceptionText <> '' then
     171          raise Exception.Create(LocalExceptionText);
     172      end;
     173      ProgressBar1.Hide;
     174      ListView1.Items.Item[I].ImageIndex := 0;
     175      if Terminate then Break;
     176      EndTime := Now;
    87177    end;
    88     SetLength(Jobs, Length(Jobs) + 1);
    89     Jobs[High(Jobs)].Method := Method;
    90     Jobs[High(Jobs)].Direct := Direct;
    91     EndUpdate;
    92   end;
    93 end;
    94 
    95 procedure TJobProgressView.Start;
    96 var
    97   I: Integer;
    98   LocalExceptionText: string;
    99 begin
    100   Caption := 'Prosím èekejte...';
    101   try
    102   Terminate := False;
    103   WindowList := DisableTaskWindows(0);
    104   Height := 100 + 18 * ListView1.Items.Count;
    105   //Show;
    106   Timer1.Enabled := True;
    107 //  Timer1Timer(Self);
    108   for I := 0 to High(Jobs) do begin
    109     StartTime := Now;
    110     ListView1.Items.Item[I].ImageIndex := 1;
    111     Label3.Caption := '';
    112     ProgressBar1.Position := 0;
    113     FPosition := 0;
    114     FProgress := 0;
    115     Application.ProcessMessages;
    116     if Jobs[I].Direct then Jobs[I].Method(nil) else begin
    117       Job := TJobThread.Create(True);
    118       with Job do begin
    119         Method := Jobs[I].Method;
    120         Title := ListView1.Items.Item[I].Caption;
    121         Index := I;
    122         Resume;
    123         while not Terminated do begin
    124           Application.ProcessMessages;
    125           Sleep(1);
    126         end;
    127         WaitFor;
    128         LocalExceptionText := ExceptionText;
    129         Free;
    130       end;
    131       if LocalExceptionText <> '' then raise Exception.Create(LocalExceptionText);
    132     end;
    133     ProgressBar1.Hide;
    134     ListView1.Items.Item[I].ImageIndex := 0;
    135     if Terminate then Break;
    136   end;
     178    CurrentJob := nil;
    137179  finally
    138180    Timer1.Enabled := False;
    139     EnableTaskWindows(WindowList);
    140     if Visible then begin
    141       JobProgressView.Hide;
    142     end;
    143     SetLength(Jobs, 0);
    144     with ListView1.Items do begin
    145       BeginUpdate;
    146       Clear;
    147       EndUpdate;
    148     end;
     181    //EnableTaskWindows(WindowList);
     182    if Visible then Hide;
    149183  end;
    150184end;
     
    153187begin
    154188  UpdateProgress;
    155   if (not ProgressBar1.Visible) and (FProgress > 0) then ProgressBar1.Visible := True;
     189  if (not ProgressBar1.Visible) and Assigned(CurrentJob) and
     190  (CurrentJob.Progress.Value > 0) then
     191    ProgressBar1.Visible := True;
    156192  if not Visible then Show;
    157193end;
     
    160196begin
    161197  try
    162     Animate1.FileName := ExtractFileDir(Application.ExeName) + '\horse.avi';
    163     Animate1.Active := True;
     198    //Animate1.FileName := ExtractFileDir(Application.ExeName) + '\horse.avi';
     199    //Animate1.Active := True;
    164200  except
    165201
     
    189225  CanClose := Terminate;
    190226  Terminate := True;
    191   Caption := 'Prosím èekejte...pøerušení';
    192 end;
    193 
    194 procedure TJobProgressView.SetProgress(Value: Real);
    195 begin
    196   if (Value * 100) > FPosition then begin
    197     FPosition := Trunc(Value * 100) + 1;
    198     UpdateProgress;
    199   end;
    200   FProgress := Value;
     227  Caption := 'Prosím čekejte...přerušení';
     228end;
     229
     230procedure TJobProgressView.SetTerminate(const AValue: Boolean);
     231var
     232  I: Integer;
     233begin
     234  for I := 0 to Jobs.Count - 1 do
     235    TJob(Jobs[I]).Terminate := AValue;
     236  FTerminate := AValue;
    201237end;
    202238
    203239procedure TJobProgressView.UpdateProgress;
    204240begin
    205   ProgressBar1.Position := FPosition;
    206   if (FPosition > 4) and (FProgress > 0) then
    207     Label3.Caption := TimeToStr((Now - StartTime) / FProgress * (1 - FProgress));
     241  if Assigned(CurrentJob) then
     242  with CurrentJob do begin
     243    ProgressBar1.Max := Progress.Max;
     244    ProgressBar1.Position := Progress.Value;
     245    if (Progress.Value >= EstimatedTimeShowTreshold) then
     246      LabelEstimatedTime.Caption :=
     247        TimeToStr((Now - StartTime) / Progress.Value * (Progress.Max - Progress.Value));
     248  end;
     249end;
     250
     251procedure TJobProgressView.ReloadJobList;
     252var
     253  NewItem: TListItem;
     254  I: Integer;
     255begin
     256  with ListView1, Items do begin
     257    BeginUpdate;
     258    Clear;
     259    for I := 0 to Jobs.Count - 1 do
     260    with TJob(Jobs[I]) do begin
     261      NewItem := Add;
     262      with NewItem do begin
     263        Caption := Title;
     264        ImageIndex := 2;
     265        Data := Jobs[I];
     266      end;
     267    end;
     268    EndUpdate;
     269  end;
     270end;
     271
     272constructor TJobProgressView.Create(TheOwner: TComponent);
     273begin
     274  inherited;
     275  Jobs := TList.Create;
     276end;
     277
     278procedure TJobProgressView.Clear;
     279var
     280  I: Integer;
     281begin
     282  for I := 0 to Jobs.Count - 1 do
     283    TJob(Jobs[I]).Destroy;
     284  Jobs.Clear;
     285  ReloadJobList;
     286end;
     287
     288destructor TJobProgressView.Destroy;
     289begin
     290  Clear;
     291  Jobs.Destroy;
     292  inherited Destroy;
     293end;
     294
     295procedure TProgress.SetMax(const AValue: Integer);
     296begin
     297  FMax := AValue;
     298  if FValue >= FMax then FValue := FMax;
     299end;
     300
     301procedure TProgress.SetValue(const AValue: Integer);
     302var
     303  Change: Boolean;
     304begin
     305  if AValue < Max then begin
     306    change := AValue <> FValue;
     307    FValue := AValue;
     308    if Change and Assigned(FOnChange) then FOnChange(Self);
     309  end;
     310end;
     311
     312{ TProgress }
     313
     314procedure TProgress.Increment;
     315begin
     316  Value := Value + 1;
     317end;
     318
     319procedure TProgress.Reset;
     320begin
     321  FValue := 0;
     322end;
     323
     324constructor TProgress.Create;
     325begin
     326  FMax := 100;
     327end;
     328
     329{ TJob }
     330
     331constructor TJob.Create;
     332begin
     333  Progress := TProgress.Create;
     334  Terminate := False;
     335end;
     336
     337destructor TJob.Destroy;
     338begin
     339  Progress.Destroy;
     340  inherited Destroy;
    208341end;
    209342
Note: See TracChangeset for help on using the changeset viewer.