Changeset 25 for trunk/Packages/Common/UJobProgressView.pas
- Timestamp:
- Sep 10, 2022, 6:54:43 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Packages/Common/UJobProgressView.pas
r15 r25 1 1 unit UJobProgressView; 2 3 {$MODE Delphi}4 2 5 3 interface … … 7 5 uses 8 6 SysUtils, Variants, Classes, Graphics, Controls, Forms, Syncobjs, 9 Dialogs, ComCtrls, StdCtrls, ExtCtrls, Contnrs, UThreading,7 Dialogs, ComCtrls, StdCtrls, ExtCtrls, Generics.Collections, UThreading, Math, 10 8 DateUtils; 11 9 … … 13 11 EstimatedTimeShowTreshold = 4; 14 12 EstimatedTimeShowTresholdTotal = 1; 15 MemoLogHeight = 200;16 13 UpdateInterval = 100; // ms 17 14 … … 24 21 FLock: TCriticalSection; 25 22 FOnChange: TNotifyEvent; 23 FText: string; 26 24 FValue: Integer; 27 25 FMax: Integer; 28 26 procedure SetMax(const AValue: Integer); 27 procedure SetText(AValue: string); 29 28 procedure SetValue(const AValue: Integer); 30 29 public … … 35 34 property Value: Integer read FValue write SetValue; 36 35 property Max: Integer read FMax write SetMax; 36 property Text: string read FText write SetText; 37 37 property OnChange: TNotifyEvent read FOnChange write FOnChange; 38 38 end; … … 69 69 end; 70 70 71 TJobs = class(TObjectList<TJob>) 72 end; 73 71 74 TJobThread = class(TListedThread) 72 75 procedure Execute; override; … … 80 83 TFormJobProgressView = class(TForm) 81 84 ImageList1: TImageList; 85 LabelText: TLabel; 82 86 Label2: TLabel; 83 87 LabelOperation: TLabel; … … 86 90 ListViewJobs: TListView; 87 91 MemoLog: TMemo; 92 PanelText: TPanel; 88 93 PanelProgressTotal: TPanel; 89 94 PanelOperationsTitle: TPanel; … … 94 99 ProgressBarTotal: TProgressBar; 95 100 TimerUpdate: TTimer; 101 procedure FormHide(Sender: TObject); 102 procedure FormShow(Sender: TObject); 103 procedure ReloadJobList; 96 104 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); 97 procedure FormDestroy(Sender: TObject);98 105 procedure ListViewJobsData(Sender: TObject; Item: TListItem); 99 106 procedure TimerUpdateTimer(Sender: TObject); 100 107 procedure FormCreate(Sender: TObject); 101 108 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); 109 procedure UpdateHeight; 102 110 public 103 111 JobProgressView: TJobProgressView; … … 118 126 TotalStartTime: TDateTime; 119 127 Log: TStringList; 128 FForm: TFormJobProgressView; 120 129 procedure SetTerminate(const AValue: Boolean); 121 130 procedure UpdateProgress; 122 procedure ReloadJobList;123 procedure StartJobs;124 procedure UpdateHeight;125 131 procedure JobProgressChange(Sender: TObject); 126 132 public 127 Form: TFormJobProgressView; 128 Jobs: TObjectList; // TListObject<TJob> 133 Jobs: TJobs; 129 134 CurrentJob: TJob; 130 135 CurrentJobIndex: Integer; … … 132 137 destructor Destroy; override; 133 138 procedure Clear; 134 procedureAddJob(Title: string; Method: TJobProgressViewMethod;135 NoThreaded: Boolean = False; WaitFor: Boolean = False) ;136 procedure Start (AAutoClose: Boolean = True);139 function AddJob(Title: string; Method: TJobProgressViewMethod; 140 NoThreaded: Boolean = False; WaitFor: Boolean = False): TJob; 141 procedure Start; 137 142 procedure Stop; 138 143 procedure TermSleep(Delay: Integer); 144 property Form: TFormJobProgressView read FForm; 139 145 property Terminate: Boolean read FTerminate write SetTerminate; 140 146 published … … 156 162 SExecuted = 'Executed'; 157 163 164 158 165 implementation 159 166 … … 166 173 STotalEstimatedTime = 'Total estimated time: %s'; 167 174 SFinished = 'Finished'; 168 SOperations = 'Operations';169 175 170 176 procedure Register; … … 172 178 RegisterComponents('Common', [TJobProgressView]); 173 179 end; 180 181 { TJobThread } 174 182 175 183 procedure TJobThread.Execute; … … 190 198 end; 191 199 192 procedure TJobProgressView.AddJob(Title: string; Method: TJobProgressViewMethod; 193 NoThreaded: Boolean = False; WaitFor: Boolean = False); 200 { TFormJobProgressView } 201 202 procedure TFormJobProgressView.UpdateHeight; 194 203 var 195 NewJob: TJob; 196 begin 197 NewJob := TJob.Create; 198 NewJob.ProgressView := Self; 199 NewJob.Title := Title; 200 NewJob.Method := Method; 201 NewJob.NoThreaded := NoThreaded; 202 NewJob.WaitFor := WaitFor; 203 NewJob.Progress.Max := 100; 204 NewJob.Progress.Reset; 205 NewJob.Progress.OnChange := JobProgressChange; 206 Jobs.Add(NewJob); 204 H: Integer; 205 PanelOperationsVisible: Boolean; 206 PanelOperationsHeight: Integer; 207 PanelProgressVisible: Boolean; 208 PanelProgressTotalVisible: Boolean; 209 PanelLogVisible: Boolean; 210 MemoLogHeight: Integer = 200; 211 I: Integer; 212 ItemRect: TRect; 213 MaxH: Integer; 214 begin 215 H := PanelOperationsTitle.Height; 216 PanelOperationsVisible := JobProgressView.Jobs.Count > 0; 217 if PanelOperationsVisible <> PanelOperations.Visible then 218 PanelOperations.Visible := PanelOperationsVisible; 219 if ListViewJobs.Items.Count > 0 then begin 220 Maxh := 0; 221 for I := 0 to ListViewJobs.Items.Count - 1 do 222 begin 223 ItemRect := ListViewJobs.Items[i].DisplayRect(drBounds); 224 Maxh := Max(Maxh, ItemRect.Top + (ItemRect.Bottom - ItemRect.Top)); 225 end; 226 PanelOperationsHeight := Scale96ToScreen(12) + Maxh; 227 end else PanelOperationsHeight := Scale96ToScreen(8); 228 if PanelOperationsHeight <> PanelOperations.Height then 229 PanelOperations.Height := PanelOperationsHeight; 230 if PanelOperationsVisible then 231 H := H + PanelOperations.Height; 232 233 PanelProgressVisible := (JobProgressView.Jobs.Count > 0) and not JobProgressView.Finished; 234 if PanelProgressVisible <> PanelProgress.Visible then 235 PanelProgress.Visible := PanelProgressVisible; 236 if PanelProgressVisible then 237 H := H + PanelProgress.Height; 238 PanelProgressTotalVisible := (JobProgressView.Jobs.Count > 1) and not JobProgressView.Finished; 239 if PanelProgressTotalVisible <> PanelProgressTotal.Visible then 240 PanelProgressTotal.Visible := PanelProgressTotalVisible; 241 if PanelProgressTotalVisible then 242 H := H + PanelProgressTotal.Height; 243 Constraints.MinHeight := H; 244 PanelLogVisible := MemoLog.Lines.Count > 0; 245 if PanelLogVisible <> PanelLog.Visible then 246 PanelLog.Visible := PanelLogVisible; 247 if PanelLogVisible then 248 H := H + Scale96ToScreen(MemoLogHeight); 249 if PanelText.Visible then 250 H := H + PanelText.Height; 251 if Height <> H then begin 252 Height := H; 253 Top := (Screen.Height - H) div 2; 254 end; 255 end; 256 257 procedure TFormJobProgressView.TimerUpdateTimer(Sender: TObject); 258 var 259 ProgressBarPartVisible: Boolean; 260 ProgressBarTotalVisible: Boolean; 261 begin 262 JobProgressView.UpdateProgress; 263 if Visible and (not ProgressBarPart.Visible) and 264 Assigned(JobProgressView.CurrentJob) and 265 (JobProgressView.CurrentJob.Progress.Value > 0) then begin 266 ProgressBarPartVisible := True; 267 if ProgressBarPartVisible <> ProgressBarPart.Visible then 268 ProgressBarPart.Visible := ProgressBarPartVisible; 269 ProgressBarTotalVisible := True; 270 if ProgressBarTotalVisible <> ProgressBarTotal.Visible then 271 ProgressBarTotal.Visible := ProgressBarTotalVisible; 272 end; 273 if not Visible then begin 274 TimerUpdate.Interval := UpdateInterval; 275 if not JobProgressView.OwnerDraw then Show; 276 end; 277 if Assigned(JobProgressView.CurrentJob) then begin 278 LabelText.Caption := JobProgressView.CurrentJob.Progress.Text; 279 if LabelText.Caption <> '' then begin 280 PanelText.Visible := True; 281 UpdateHeight; 282 end; 283 end; 284 end; 285 286 procedure TFormJobProgressView.ListViewJobsData(Sender: TObject; Item: TListItem); 287 begin 288 if (Item.Index >= 0) and (Item.Index < JobProgressView.Jobs.Count) then 289 with JobProgressView.Jobs[Item.Index] do begin 290 Item.Caption := Title; 291 if Item.Index = JobProgressView.CurrentJobIndex then Item.ImageIndex := 1 292 else if Finished then Item.ImageIndex := 0 293 else Item.ImageIndex := 2; 294 Item.Data := JobProgressView.Jobs[Item.Index]; 295 end; 296 end; 297 298 procedure TFormJobProgressView.FormClose(Sender: TObject; 299 var CloseAction: TCloseAction); 300 begin 301 end; 302 303 procedure TFormJobProgressView.FormCreate(Sender: TObject); 304 begin 305 Caption := SPleaseWait; 306 try 307 //Animate1.FileName := ExtractFileDir(UTF8Encode(Application.ExeName)) + 308 // DirectorySeparator + 'horse.avi'; 309 //Animate1.Active := True; 310 except 311 312 end; 313 end; 314 315 procedure TFormJobProgressView.ReloadJobList; 316 begin 317 // Workaround for not showing first line 318 //Form.ListViewJobs.Items.Count := Jobs.Count + 1; 319 //Form.ListViewJobs.Refresh; 320 321 if ListViewJobs.Items.Count <> JobProgressView.Jobs.Count then 322 ListViewJobs.Items.Count := JobProgressView.Jobs.Count; 323 ListViewJobs.Refresh; 324 Application.ProcessMessages; 325 UpdateHeight; 326 end; 327 328 procedure TFormJobProgressView.FormShow(Sender: TObject); 329 begin 330 ReloadJobList; 331 end; 332 333 procedure TFormJobProgressView.FormHide(Sender: TObject); 334 begin 335 JobProgressView.Jobs.Clear; 336 ReloadJobList; 337 end; 338 339 procedure TFormJobProgressView.FormCloseQuery(Sender: TObject; var CanClose: Boolean); 340 begin 341 CanClose := JobProgressView.Finished; 342 JobProgressView.Terminate := True; 343 Caption := SPleaseWait + STerminate; 344 end; 345 346 347 { TJobProgressView } 348 349 function TJobProgressView.AddJob(Title: string; Method: TJobProgressViewMethod; 350 NoThreaded: Boolean = False; WaitFor: Boolean = False): TJob; 351 begin 352 Result := TJob.Create; 353 Result.ProgressView := Self; 354 Result.Title := Title; 355 Result.Method := Method; 356 Result.NoThreaded := NoThreaded; 357 Result.WaitFor := WaitFor; 358 Result.Progress.Max := 100; 359 Result.Progress.Reset; 360 Result.Progress.OnChange := JobProgressChange; 361 Jobs.Add(Result); 207 362 //ReloadJobList; 208 363 end; 209 364 210 procedure TJobProgressView.Start(AAutoClose: Boolean = True); 211 begin 212 AutoClose := AAutoClose; 213 StartJobs; 214 end; 215 216 procedure TJobProgressView.StartJobs; 365 procedure TJobProgressView.Start; 217 366 var 218 367 I: Integer; … … 229 378 Form.MemoLog.Clear; 230 379 380 Form.PanelText.Visible := False; 231 381 Form.LabelEstimatedTimePart.Visible := False; 232 382 Form.LabelEstimatedTimeTotal.Visible := False; … … 249 399 I := 0; 250 400 while I < Jobs.Count do 251 with TJob(Jobs[I])do begin401 with Jobs[I] do begin 252 402 CurrentJobIndex := I; 253 CurrentJob := TJob(Jobs[I]);403 CurrentJob := Jobs[I]; 254 404 JobProgressChange(Self); 255 405 StartTime := Now; … … 258 408 Form.ProgressBarPart.Visible := False; 259 409 //Show; 260 ReloadJobList;410 Form.ReloadJobList; 261 411 Application.ProcessMessages; 262 412 if NoThreaded then begin … … 264 414 Method(CurrentJob); 265 415 end else begin 416 Thread := TJobThread.Create(True); 266 417 try 267 Thread := TJobThread.Create(True);268 418 with Thread do begin 269 419 FreeOnTerminate := False; … … 296 446 //if Visible then Hide; 297 447 Form.MemoLog.Lines.Assign(Log); 298 if (Form.MemoLog.Lines.Count = 0) and AutoClose then begin448 if (Form.MemoLog.Lines.Count = 0) and FAutoClose then begin 299 449 Form.Hide; 300 450 end; 301 Clear;451 if not Form.Visible then Clear; 302 452 Form.Caption := SFinished; 303 453 //LabelEstimatedTimePart.Visible := False; 304 454 Finished := True; 305 455 CurrentJobIndex := -1; 306 ReloadJobList; 307 end; 308 end; 309 310 procedure TJobProgressView.UpdateHeight; 311 var 312 H: Integer; 313 PanelOperationsVisible: Boolean; 314 PanelOperationsHeight: Integer; 315 PanelProgressVisible: Boolean; 316 PanelProgressTotalVisible: Boolean; 317 PanelLogVisible: Boolean; 318 begin 319 with Form do begin 320 H := PanelOperationsTitle.Height; 321 PanelOperationsVisible := Jobs.Count > 0; 322 if PanelOperationsVisible <> PanelOperations.Visible then 323 PanelOperations.Visible := PanelOperationsVisible; 324 PanelOperationsHeight := 8 + 18 * Jobs.Count; 325 if PanelOperationsHeight <> PanelOperations.Height then 326 PanelOperations.Height := PanelOperationsHeight; 327 if PanelOperationsVisible then 328 H := H + PanelOperations.Height; 329 330 PanelProgressVisible := (Jobs.Count > 0) and not Finished; 331 if PanelProgressVisible <> PanelProgress.Visible then 332 PanelProgress.Visible := PanelProgressVisible; 333 if PanelProgressVisible then 334 H := H + PanelProgress.Height; 335 PanelProgressTotalVisible := (Jobs.Count > 1) and not Finished; 336 if PanelProgressTotalVisible <> PanelProgressTotal.Visible then 337 PanelProgressTotal.Visible := PanelProgressTotalVisible; 338 if PanelProgressTotalVisible then 339 H := H + PanelProgressTotal.Height; 340 Constraints.MinHeight := H; 341 PanelLogVisible := MemoLog.Lines.Count > 0; 342 if PanelLogVisible <> PanelLog.Visible then 343 PanelLog.Visible := PanelLogVisible; 344 if PanelLogVisible then 345 H := H + MemoLogHeight; 346 if Height <> H then Height := H; 456 Form.ReloadJobList; 347 457 end; 348 458 end; … … 352 462 if Assigned(FOnOwnerDraw) then 353 463 FOnOwnerDraw(Self); 354 end;355 356 procedure TFormJobProgressView.TimerUpdateTimer(Sender: TObject);357 var358 ProgressBarPartVisible: Boolean;359 ProgressBarTotalVisible: Boolean;360 begin361 JobProgressView.UpdateProgress;362 if Visible and (not ProgressBarPart.Visible) and363 Assigned(JobProgressView.CurrentJob) and364 (JobProgressView.CurrentJob.Progress.Value > 0) then begin365 ProgressBarPartVisible := True;366 if ProgressBarPartVisible <> ProgressBarPart.Visible then367 ProgressBarPart.Visible := ProgressBarPartVisible;368 ProgressBarTotalVisible := True;369 if ProgressBarTotalVisible <> ProgressBarTotal.Visible then370 ProgressBarTotal.Visible := ProgressBarTotalVisible;371 end;372 if not Visible then begin373 TimerUpdate.Interval := UpdateInterval;374 if not JobProgressView.OwnerDraw then Show;375 end;376 end;377 378 procedure TFormJobProgressView.FormDestroy(Sender:TObject);379 begin380 end;381 382 procedure TFormJobProgressView.ListViewJobsData(Sender: TObject; Item: TListItem);383 begin384 if (Item.Index >= 0) and (Item.Index < JobProgressView.Jobs.Count) then385 with TJob(JobProgressView.Jobs[Item.Index]) do begin386 Item.Caption := Title;387 if Item.Index = JobProgressView.CurrentJobIndex then Item.ImageIndex := 1388 else if Finished then Item.ImageIndex := 0389 else Item.ImageIndex := 2;390 Item.Data := JobProgressView.Jobs[Item.Index];391 end;392 end;393 394 procedure TFormJobProgressView.FormClose(Sender: TObject;395 var CloseAction: TCloseAction);396 begin397 ListViewJobs.Clear;398 end;399 400 procedure TFormJobProgressView.FormCreate(Sender: TObject);401 begin402 Caption := SPleaseWait;403 try404 //Animate1.FileName := ExtractFileDir(UTF8Encode(Application.ExeName)) +405 // DirectorySeparator + 'horse.avi';406 //Animate1.Active := True;407 except408 409 end;410 464 end; 411 465 … … 428 482 end; 429 483 430 procedure TFormJobProgressView.FormCloseQuery(Sender: TObject; var CanClose: Boolean);431 begin432 CanClose := JobProgressView.Finished;433 JobProgressView.Terminate := True;434 Caption := SPleaseWait + STerminate;435 end;436 437 484 procedure TJobProgressView.SetTerminate(const AValue: Boolean); 438 485 var … … 441 488 if AValue = FTerminate then Exit; 442 489 for I := 0 to Jobs.Count - 1 do 443 TJob(Jobs[I]).Terminate := AValue;490 Jobs[I].Terminate := AValue; 444 491 FTerminate := AValue; 445 492 end; … … 490 537 end; 491 538 492 procedure TJobProgressView.ReloadJobList;493 begin494 UpdateHeight;495 // Workaround for not showing first line496 Form.ListViewJobs.Items.Count := Jobs.Count + 1;497 Form.ListViewJobs.Refresh;498 499 if Form.ListViewJobs.Items.Count <> Jobs.Count then500 Form.ListViewJobs.Items.Count := Jobs.Count;501 Form.ListViewJobs.Refresh;502 //Application.ProcessMessages;503 end;504 505 539 constructor TJobProgressView.Create(TheOwner: TComponent); 506 540 begin 507 541 inherited; 508 542 if not (csDesigning in ComponentState) then begin 509 F orm := TFormJobProgressView.Create(Self);510 F orm.JobProgressView := Self;511 end; 512 Jobs := T ObjectList.Create;543 FForm := TFormJobProgressView.Create(Self); 544 FForm.JobProgressView := Self; 545 end; 546 Jobs := TJobs.Create; 513 547 Log := TStringList.Create; 514 548 //PanelOperationsTitle.Height := 80; 515 ShowDelay := 0; //1000; // ms 549 AutoClose := True; 550 ShowDelay := 0; 516 551 end; 517 552 … … 519 554 begin 520 555 Jobs.Clear; 556 Log.Clear; 521 557 //ReloadJobList; 522 558 end; … … 528 564 inherited; 529 565 end; 566 567 { TProgress } 530 568 531 569 procedure TProgress.SetMax(const AValue: Integer); … … 536 574 if FMax < 1 then FMax := 1; 537 575 if FValue >= FMax then FValue := FMax; 576 finally 577 FLock.Release; 578 end; 579 end; 580 581 procedure TProgress.SetText(AValue: string); 582 begin 583 try 584 FLock.Acquire; 585 if FText = AValue then Exit; 586 FText := AValue; 538 587 finally 539 588 FLock.Release; … … 563 612 end; 564 613 565 { TProgress }566 567 614 procedure TProgress.Increment; 568 615 begin 569 try570 FLock.Acquire;616 FLock.Acquire; 617 try 571 618 Value := Value + 1; 572 619 finally … … 577 624 procedure TProgress.Reset; 578 625 begin 579 try580 FLock.Acquire;626 FLock.Acquire; 627 try 581 628 FValue := 0; 582 629 finally … … 594 641 begin 595 642 FLock.Free; 596 inherited Destroy;643 inherited; 597 644 end; 598 645 … … 625 672 destructor TJob.Destroy; 626 673 begin 627 Progress.Free;674 FreeAndNil(Progress); 628 675 inherited; 629 676 end;
Note:
See TracChangeset
for help on using the changeset viewer.