• R/O
  • SSH
  • HTTPS

mantisbtmonitor: Commit


Commit MetaInfo

Revision81 (tree)
Time2022-06-11 05:27:15
Authorderekwildstar

Log Message

Novos recursos adicionados em substituição dos iCandy Jr
Um novo form exclusivo para exibição de status de operação demorada foi adicionado ao projeto
Vários pontos do código existente em UScrapFunctions.pas foram alterados para permitir a exibição do form de status e algumas funções foram alteradas para terem eu seus parâmetros a referência a uma tarefa e não o id da tarefa
Agora o tipo TTask possui mais dois atributos AssignToToken e AssignToLastUpdated e isso gerou alterações na função ParseTaskDetails
Algumas funções de scrap receberam o parâmetro ACommentHeaderDescription que permite que cabeçalhos padrão tenham uma descrição que aparece no canto direito do cabeçalho
As funções ShowStatusForm, HideStatusForm e UpdateStatusForm foram adicionadas
A classe TTasksChecking possui um novo campo FFormToBlock que serve para identificar o form que precisa ser bloqueado pelo form de status. O método ForceTimeOut agora possui um parâmetro que permite a configuração deste campo privado, o qual será usado no método execute da Thread
O método TDamoPrincipal.Refresh agora possui um parâmetro para indicar o form que precisa ser bloqueado pelo form de status
Método SendToTest implementado
O FormManageNote agora possui mais 2 modos especiais, SendToTest e SendToHomologation
Criada codificação para remover o separador órfão inicial da barra de ferramentas de FormTask

Change Summary

Incremental Difference

--- trunk/client/prj/MantisBTMonitor.dpr (revision 80)
+++ trunk/client/prj/MantisBTMonitor.dpr (revision 81)
@@ -17,7 +17,8 @@
1717 UScrapFunctions in '..\src\lib\UScrapFunctions.pas',
1818 UDamoTask in '..\src\UDamoTask.pas' {DamoTask: TDataModule},
1919 UInterposersAndHelpers in '..\src\lib\UInterposersAndHelpers.pas',
20- UTypes in '..\src\lib\UTypes.pas';
20+ UTypes in '..\src\lib\UTypes.pas',
21+ UFormStatus in '..\src\lib\UFormStatus.pas' {FormStatus};
2122
2223 {$R *.res}
2324
--- trunk/client/prj/MantisBTMonitor.dproj (revision 80)
+++ trunk/client/prj/MantisBTMonitor.dproj (revision 81)
@@ -119,7 +119,7 @@
119119 <VerInfo_MinorVer>0</VerInfo_MinorVer>
120120 <VerInfo_Release>0</VerInfo_Release>
121121 <VerInfo_Locale>1033</VerInfo_Locale>
122- <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.743;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
122+ <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.837;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
123123 <Debugger_RunParams>/desenvolvimento</Debugger_RunParams>
124124 <VerInfo_AutoGenVersion>false</VerInfo_AutoGenVersion>
125125 <VerInfo_AutoIncVersion>true</VerInfo_AutoIncVersion>
@@ -126,7 +126,7 @@
126126 <DCC_DebugInformation>2</DCC_DebugInformation>
127127 <DCC_SymbolReferenceInfo>2</DCC_SymbolReferenceInfo>
128128 <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
129- <VerInfo_Build>743</VerInfo_Build>
129+ <VerInfo_Build>837</VerInfo_Build>
130130 <DCC_MapFile>3</DCC_MapFile>
131131 </PropertyGroup>
132132 <ItemGroup>
@@ -170,6 +170,10 @@
170170 </DCCReference>
171171 <DCCReference Include="..\src\lib\UInterposersAndHelpers.pas"/>
172172 <DCCReference Include="..\src\lib\UTypes.pas"/>
173+ <DCCReference Include="..\src\lib\UFormStatus.pas">
174+ <Form>FormStatus</Form>
175+ <FormType>dfm</FormType>
176+ </DCCReference>
173177 <BuildConfiguration Include="Debug">
174178 <Key>Cfg_2</Key>
175179 <CfgParent>Base</CfgParent>
@@ -190,7 +194,44 @@
190194 <Source>
191195 <Source Name="MainSource">MantisBTMonitor.dpr</Source>
192196 </Source>
193- <Excluded_Packages/>
197+ <Excluded_Packages>
198+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclBaseExpert260.bpl">JCL Package containing common units for JCL Experts</Excluded_Packages>
199+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclDebugExpert260.bpl">JCL Debug IDE extension</Excluded_Packages>
200+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclFavoriteFoldersExpert260.bpl">JCL Open and Save IDE dialogs with favorite folders</Excluded_Packages>
201+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclProjectAnalysisExpert260.bpl">JCL Project Analyzer</Excluded_Packages>
202+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclRepositoryExpert260.bpl">JCL Package containing repository wizards</Excluded_Packages>
203+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclSIMDViewExpert260.bpl">JCL Debug Window of XMM registers</Excluded_Packages>
204+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclStackTraceViewerExpert260.bpl">JCL Stack Trace Viewer</Excluded_Packages>
205+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JclVersionControlExpert260.bpl">JCL Integration of version control systems in the IDE</Excluded_Packages>
206+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvAppFrmDesign260.bpl">JVCL Application and Form Components</Excluded_Packages>
207+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvCoreDesign260.bpl">JVCL Core Components</Excluded_Packages>
208+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvBandsDesign260.bpl">JVCL Band Objects</Excluded_Packages>
209+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvCmpDesign260.bpl">JVCL Non-Visual Components</Excluded_Packages>
210+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvControlsDesign260.bpl">JVCL Visual Controls</Excluded_Packages>
211+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvCryptDesign260.bpl">JVCL Encryption and Compression</Excluded_Packages>
212+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvCustomDesign260.bpl">JVCL Custom Controls</Excluded_Packages>
213+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvDBDesign260.bpl">JVCL Database Components</Excluded_Packages>
214+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvDlgsDesign260.bpl">JVCL Dialog Components</Excluded_Packages>
215+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvDockingDesign260.bpl">JVCL Docking Components</Excluded_Packages>
216+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvDotNetCtrlsDesign260.bpl">JVCL DotNet Controls</Excluded_Packages>
217+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvGlobusDesign260.bpl">JVCL Globus Components</Excluded_Packages>
218+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvHMIDesign260.bpl">JVCL HMI Controls</Excluded_Packages>
219+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvJansDesign260.bpl">JVCL Jans Components</Excluded_Packages>
220+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvManagedThreadsDesign260.bpl">JVCL Managed Threads</Excluded_Packages>
221+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvMMDesign260.bpl">JVCL Multimedia and Image Components</Excluded_Packages>
222+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvNetDesign260.bpl">JVCL Network Components</Excluded_Packages>
223+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvPageCompsDesign260.bpl">JVCL Page Style Components</Excluded_Packages>
224+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvPascalInterpreterDesign260.bpl">JVCL Interpreter Components</Excluded_Packages>
225+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvPrintPreviewDesign260.bpl">JVCL Print Preview Components</Excluded_Packages>
226+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvRuntimeDesignDesign260.bpl">JVCL Runtime Design Components</Excluded_Packages>
227+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvStdCtrlsDesign260.bpl">JVCL Standard Controls</Excluded_Packages>
228+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvSystemDesign260.bpl">JVCL System Components</Excluded_Packages>
229+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvTimeFrameworkDesign260.bpl">JVCL Time Framework</Excluded_Packages>
230+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvWizardsDesign260.bpl">JVCL Wizard</Excluded_Packages>
231+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvXPCtrlsDesign260.bpl">JVCL XP Controls</Excluded_Packages>
232+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\JvPluginSystemDesign260.bpl">JVCL Plugin Components</Excluded_Packages>
233+ <Excluded_Packages Name="D:\componentesdelphi\03-Implementacao\01-Src\_BPL\d26\KRKExpertsD260.bpl">Anak Krakatoa Experts</Excluded_Packages>
234+ </Excluded_Packages>
194235 </Delphi.Personality>
195236 <Platforms>
196237 <Platform value="Win32">True</Platform>
--- trunk/client/src/lib/UFORMStatus.pas (nonexistent)
+++ trunk/client/src/lib/UFORMStatus.pas (revision 81)
@@ -0,0 +1,24 @@
1+unit UFormStatus;
2+
3+interface
4+
5+uses
6+ Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7+ Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ExtCtrls,
8+ Vcl.Imaging.GIFImg, Vcl.Imaging.pngimage, Vcl.StdCtrls;
9+
10+type
11+ TFormStatus = class(TForm)
12+ IMAG: TImage;
13+ LABE: TLabel;
14+ private
15+ { Private declarations }
16+ public
17+ { Public declarations }
18+ end;
19+
20+implementation
21+
22+{$R *.dfm}
23+
24+end.
--- trunk/client/src/lib/UFunctions.pas (revision 80)
+++ trunk/client/src/lib/UFunctions.pas (revision 81)
@@ -3,8 +3,9 @@
33 interface
44
55 uses
6- WinApi.Windows, Vcl.Graphics, System.Classes, SHDocVw, DBClient,
7- UPngImageList, UScrapFunctions, UTypes, KRK.Internet.Edge;
6+ WinApi.Windows, Vcl.Graphics, Vcl.Forms, System.Classes, SHDocVw, DBClient,
7+ UPngImageList, UScrapFunctions, UTypes, KRK.Internet.Edge,
8+ KRK.Vcl.Forms.FormBlender;
89
910 //function DecodeIssueInfo(AIssueData: String): TIssueInfo;
1011 procedure OpenTaskWithMantis(ATaskNumber: Cardinal);
@@ -28,13 +29,16 @@
2829 //: especiais de aprovação/reprovação de tarefas, apenas os cabeçalhos padrão de
2930 //: comentários de acordo com a unidade do usuário
3031 procedure AddCommentHeader(var AComment: String; AHeaderDescription: String = '');
32+function ShowStatusForm(AFormToBlock: TForm): TKRKFormBlender;
33+procedure HideStatusForm(AFormBlender: TKRKFormBlender);
34+procedure UpdateStatusForm(AFormBlender: TKRKFormBlender; ADescription: String);
3135
3236 implementation
3337
3438 uses
35- SysUtils, ShellApi, EncdDecd, Forms, Controls, UConfigurations,
39+ SysUtils, ShellApi, EncdDecd, Controls, UConfigurations,
3640 IdGlobalProtocols, RegularExpressionsCore, NetEncoding, Data.DB, ActiveX,
37- StrUtils, KRK.Rtl.Common.FileUtils, RTTI;
41+ StrUtils, KRK.Rtl.Common.FileUtils, RTTI, UFormStatus;
3842
3943 function RegExMatch(ASubject, APattern: String; AGroup: Byte; out AMatch: String): Boolean;
4044 begin
@@ -1195,4 +1199,31 @@
11951199 end;
11961200 end;
11971201
1202+function ShowStatusForm(AFormToBlock: TForm): TKRKFormBlender;
1203+begin
1204+ if Assigned(AFormToBlock) then
1205+ TKRKFormBlender.ShowMe(AFormToBlock,TFORMStatus,Result)
1206+ else
1207+ Result := nil;
1208+end;
1209+
1210+procedure HideStatusForm(AFormBlender: TKRKFormBlender);
1211+begin
1212+ if Assigned(AFormBlender) then
1213+ begin
1214+ AFormBlender.Close;
1215+ AFormBlender.Free;
1216+ end;
1217+end;
1218+
1219+procedure UpdateStatusForm(AFormBlender: TKRKFormBlender; ADescription: String);
1220+begin
1221+ if Assigned(AFormBlender) then
1222+ begin
1223+ AFormBlender.WaitForInternalForm;
1224+ TFORMStatus(AFormBlender.InternalFormInstance).LABE.Caption := ADescription;
1225+ TFORMStatus(AFormBlender.InternalFormInstance).Update;
1226+ end;
1227+end;
1228+
11981229 end.
--- trunk/client/src/lib/UScrapFunctions.pas (revision 80)
+++ trunk/client/src/lib/UScrapFunctions.pas (revision 81)
@@ -3,20 +3,21 @@
33 interface
44
55 uses
6- System.UITypes, System.Classes, UTypes;
6+ System.UITypes, System.Classes, Vcl.Forms, UTypes;
77
88 function Login(AHandle: Cardinal; AUserName: String; APassword: String; out AUserInfo: TUserInfo): Boolean;
99 function Logout(AHandle: Cardinal): Boolean;
1010 procedure GetMantisConfigs(AHandle: Cardinal; out AMantisConfigs: TMantisConfigs);
1111 function GetUserInfo(AHandle: Cardinal; out AUserInfo: TUserInfo): Boolean;
12-function AssignedTasks(AHandle: Cardinal; out ATasks: TTasks; AFullInfo: Boolean = False): Boolean;
13-function TaskDetails(AHandle: Cardinal; var ATask: TTask): Boolean;
14-function GetAttachmentData(AHandle: Cardinal; AId: Cardinal; out AData: TMemoryStream): Boolean;
15-function GetCommentForEdition(AHandle: Cardinal; ACommentId: Cardinal; out AComment: String; out AUpdateToken: String): Boolean;
12+function AssignedTasks(AHandle: Cardinal; AFormToBlock: TForm; out ATasks: TTasks; AFullInfo: Boolean = False): Boolean;
13+function TaskDetails(AHandle: Cardinal; AFormToBlock: TForm; var ATask: TTask): Boolean;
14+function GetAttachmentData(AHandle: Cardinal; AFormToBlock: TForm; AId: Cardinal; out AData: TMemoryStream): Boolean;
15+function GetCommentForEdition(AHandle: Cardinal; AFormToBlock: TForm; ACommentId: Cardinal; out AComment: String; out AUpdateToken: String): Boolean;
1616 function PrepareCommentForJavaScriptString(AComment: String): String; deprecated 'Não acho que vou usar isso no futuro, mas mantenha por ora';
17-function UpdateComment(AHandle: Cardinal; ACommentId: Cardinal; AComment: String; AUpdateToken: String): Boolean;
18-function AddComment(AHandle: Cardinal; ATask: TTask; AComment: String; ACommentIsPrivate: Boolean; AAttachments: array of String; out AError: String): Boolean;
19-function ChangeStatus(AHandle: Cardinal; ATaskId: Cardinal; ANewStatus: String; AComment: String = ''; ACommentIsPrivate: Boolean = False; ACounter: Word = 0): Boolean;
17+function UpdateComment(AHandle: Cardinal; AFormToBlock: TForm; ACommentId: Cardinal; AComment: String; AUpdateToken: String): Boolean;
18+function AddComment(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AComment: String; ACommentHeaderDescription: String; ACommentIsPrivate: Boolean; AAttachments: TArray<String>; out AError: String): Boolean;
19+function ChangeStatus(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; ANewStatus: String; AComment: String = ''; ACommentIsPrivate: Boolean = False; ACounter: Word = 0): Boolean;
20+function ForwardToTestOrHomologation(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AHomologation: Boolean; AComment: String; ACommentIsPrivate: Boolean; AAttachments: TArray<String>; out ACommentError: String): Boolean;
2021
2122 implementation
2223
@@ -23,8 +24,9 @@
2324 uses
2425 WinApi.Windows, WinApi.WinInet, System.SysUtils, MSHTML,
2526 KRK.Rtl.Win.WinInet.Utilities, KRK.RegExp.Utils, UConfigurations,
26- Vcl.Graphics, System.Variants, Vcl.Forms, System.JSON,
27- KRK.Internet.MSHTML.Utilities, ActiveX, KRK.Rtl.Common.FileUtils, UFunctions;
27+ Vcl.Graphics, System.Variants, System.JSON,
28+ KRK.Internet.MSHTML.Utilities, ActiveX, KRK.Rtl.Common.FileUtils, UFunctions,
29+ KRK.Vcl.Forms.FormBlender, UFORMStatus;
2830
2931 function Logout(AHandle: Cardinal): Boolean;
3032 var
@@ -31,41 +33,36 @@
3133 Req: TRequestOptions;
3234 Res: TResponse;
3335 begin
34- Screen.Cursor := crHourGlass;
35- try
36- ZeroMemory(@Req,SizeOf(TRequestOptions));
37- ZeroMemory(@Res,SizeOf(TResponse));
36+ ZeroMemory(@Req,SizeOf(TRequestOptions));
37+ ZeroMemory(@Res,SizeOf(TResponse));
3838
39- Req.AutoClearSSLState := True;
39+ Req.AutoClearSSLState := True;
4040
41- Req.InternetOpenParams.Agent := 'MantisBT Monitor';
42- Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
43- Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/logout_page.php');
44- Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
45- Req.InternetConnectParams.Context := AHandle;
41+ Req.InternetOpenParams.Agent := 'MantisBT Monitor';
42+ Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
43+ Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/logout_page.php');
44+ Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
45+ Req.InternetConnectParams.Context := AHandle;
4646
47- Req.HttpOpenRequestParams.Verb := 'GET';
48- Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
47+ Req.HttpOpenRequestParams.Verb := 'GET';
48+ Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
49+ try
50+ Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
51+ Req.HttpOpenRequestParams.Context := AHandle;
52+ Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
53+ Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
54+ Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
55+
56+ Res.Content := TStringStream.Create('',TEncoding.UTF8);
4957 try
50- Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
51- Req.HttpOpenRequestParams.Context := AHandle;
52- Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
53- Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
54- Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
58+ Request(Req,Res);
5559
56- Res.Content := TStringStream.Create('',TEncoding.UTF8);
57- try
58- Request(Req,Res);
59-
60- Result := Pos('<form id="login-form"',TStringStream(Res.Content).DataString) > 0;
61- finally
62- Res.Content.Free;
63- end;
60+ Result := Pos('<form id="login-form"',TStringStream(Res.Content).DataString) > 0;
6461 finally
65- Req.HttpOpenRequestParams.AcceptTypes.Free;
62+ Res.Content.Free;
6663 end;
6764 finally
68- Screen.Cursor := crDefault;
65+ Req.HttpOpenRequestParams.AcceptTypes.Free;
6966 end;
7067 end;
7168
@@ -208,46 +205,41 @@
208205 Req: TRequestOptions;
209206 Res: TResponse;
210207 begin
211- Screen.Cursor := crHourGlass;
212- try
213- ZeroMemory(@Req,SizeOf(TRequestOptions));
214- ZeroMemory(@Res,SizeOf(TResponse));
215- ZeroMemory(@AUserInfo,SizeOf(TUserInfo));
208+ ZeroMemory(@Req,SizeOf(TRequestOptions));
209+ ZeroMemory(@Res,SizeOf(TResponse));
210+ ZeroMemory(@AUserInfo,SizeOf(TUserInfo));
216211
217- Req.AutoClearSSLState := True;
212+ Req.AutoClearSSLState := True;
218213
219- Req.InternetOpenParams.Agent := 'MantisBT Monitor';
220- Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
221- Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/account_page.php');
222- Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
223- Req.InternetConnectParams.Context := AHandle;
214+ Req.InternetOpenParams.Agent := 'MantisBT Monitor';
215+ Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
216+ Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/account_page.php');
217+ Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
218+ Req.InternetConnectParams.Context := AHandle;
224219
225- Req.HttpOpenRequestParams.Verb := 'GET';
226- Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
220+ Req.HttpOpenRequestParams.Verb := 'GET';
221+ Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
222+ try
223+ Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
224+ Req.HttpOpenRequestParams.Context := AHandle;
225+ Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
226+ Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
227+ Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
228+
229+ Res.Content := TStringStream.Create('',TEncoding.UTF8);
227230 try
228- Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
229- Req.HttpOpenRequestParams.Context := AHandle;
230- Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
231- Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
232- Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
231+ Request(Req,Res);
233232
234- Res.Content := TStringStream.Create('',TEncoding.UTF8);
235- try
236- Request(Req,Res);
237-
238- Result := ParseGetUserInfoResult(TStringStream(Res.Content).DataString,AUserInfo);
239- finally
240- Res.Content.Free;
241- end;
233+ Result := ParseGetUserInfoResult(TStringStream(Res.Content).DataString,AUserInfo);
242234 finally
243- Req.HttpOpenRequestParams.AcceptTypes.Free;
235+ Res.Content.Free;
244236 end;
245-
246- if Result then
247- Result := GetUserId(AHandle,AUserInfo.Id);
248237 finally
249- Screen.Cursor := crDefault;
238+ Req.HttpOpenRequestParams.AcceptTypes.Free;
250239 end;
240+
241+ if Result then
242+ Result := GetUserId(AHandle,AUserInfo.Id);
251243 end;
252244
253245 function Login(AHandle: Cardinal; AUserName: String; APassword: String; out AUserInfo: TUserInfo): Boolean;
@@ -255,63 +247,58 @@
255247 Req: TRequestOptions;
256248 Res: TResponse;
257249 begin
258- Screen.Cursor := crHourGlass;
250+ ZeroMemory(@Req,SizeOf(TRequestOptions));
251+ ZeroMemory(@Res,SizeOf(TResponse));
252+ ZeroMemory(@AUserInfo,SizeOf(TUserInfo));
253+
254+ Req.AutoClearSSLState := True;
255+
256+ Req.Content := TStringStream.Create(Format('return=index.php&username=%s&password=%s&perm_login=on',[AUserName,APassword]));
259257 try
260- ZeroMemory(@Req,SizeOf(TRequestOptions));
261- ZeroMemory(@Res,SizeOf(TResponse));
262- ZeroMemory(@AUserInfo,SizeOf(TUserInfo));
258+ Req.InternetOpenParams.Agent := 'MantisBT Monitor';
259+ Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
260+ Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/login.php');
261+ Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
262+ Req.InternetConnectParams.Context := AHandle;
263263
264- Req.AutoClearSSLState := True;
265-
266- Req.Content := TStringStream.Create(Format('return=index.php&username=%s&password=%s&perm_login=on',[AUserName,APassword]));
264+ Req.HttpOpenRequestParams.Verb := 'POST';
265+ Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
267266 try
268- Req.InternetOpenParams.Agent := 'MantisBT Monitor';
269- Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
270- Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/login.php');
271- Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
272- Req.InternetConnectParams.Context := AHandle;
267+ Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
268+ Req.HttpOpenRequestParams.Context := AHandle;
269+ Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
270+ Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
271+ Req.HttpOpenRequestParams.Headers := TStringList.Create;
272+ try
273+ Req.HttpOpenRequestParams.Headers.Add('Content-Type: application/x-www-form-urlencoded');
274+ Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
273275
274- Req.HttpOpenRequestParams.Verb := 'POST';
275- Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
276- try
277- Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
278- Req.HttpOpenRequestParams.Context := AHandle;
279- Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
280- Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
281- Req.HttpOpenRequestParams.Headers := TStringList.Create;
276+ Res.Content := TStringStream.Create('',TEncoding.UTF8);
282277 try
283- Req.HttpOpenRequestParams.Headers.Add('Content-Type: application/x-www-form-urlencoded');
284- Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
278+ Request(Req,Res);
285279
286- Res.Content := TStringStream.Create('',TEncoding.UTF8);
287- try
288- Request(Req,Res);
289-
290- Result := RegExMatch(TStringStream(Res.Content).DataString
291- ,'<a href="\/mantis\/account_page\.php">\s*([a-z]+)\s*\(\s*([^ ][\w\W ]+[^ ])\s*\)\s*<\/a>'
292- ,False
293- ,[]);
294- if Result then
295- Result := GetUserInfo(AHandle,AUserInfo);
296- finally
297- Res.Content.Free;
298- end;
280+ Result := RegExMatch(TStringStream(Res.Content).DataString
281+ ,'<a href="\/mantis\/account_page\.php">\s*([a-z]+)\s*\(\s*([^ ][\w\W ]+[^ ])\s*\)\s*<\/a>'
282+ ,False
283+ ,[]);
284+ if Result then
285+ Result := GetUserInfo(AHandle,AUserInfo);
299286 finally
300- Req.HttpOpenRequestParams.Headers.Free;
287+ Res.Content.Free;
301288 end;
302289 finally
303- Req.HttpOpenRequestParams.AcceptTypes.Free;
290+ Req.HttpOpenRequestParams.Headers.Free;
304291 end;
305292 finally
306- Req.Content.Free;
293+ Req.HttpOpenRequestParams.AcceptTypes.Free;
307294 end;
308295 finally
309- Screen.Cursor := crDefault;
296+ Req.Content.Free;
310297 end;
311298 end;
312299
313300 {$WARN SYMBOL_PLATFORM OFF}
314-function UpdateComment(AHandle: Cardinal; ACommentId: Cardinal; AComment: String; AUpdateToken: String): Boolean;
301+function UpdateComment(AHandle: Cardinal; AFormToBlock: TForm; ACommentId: Cardinal; AComment: String; AUpdateToken: String): Boolean;
315302 var
316303 Req: TRequestOptions;
317304 Res: TResponse;
@@ -318,8 +305,10 @@
318305 HTMLDocument: IHTMLDocument;
319306 HTMLElement: IHTMLElement;
320307 begin
321- Screen.Cursor := crHourGlass;
308+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
322309 try
310+ UpdateStatusForm(FB,'Por favor aguarde enquanto o comentário está sendo atualizado...');
311+
323312 ZeroMemory(@Req,SizeOf(TRequestOptions));
324313 ZeroMemory(@Res,SizeOf(TResponse));
325314
@@ -391,7 +380,7 @@
391380 Req.Content.Free;
392381 end;
393382 finally
394- Screen.Cursor := crDefault;
383+ HideStatusForm(FB);
395384 end;
396385 end;
397386 {$WARN SYMBOL_PLATFORM ON}
@@ -408,66 +397,61 @@
408397 begin
409398 AMantisConfigs := Default(TMantisConfigs);
410399
411- Screen.Cursor := crHourGlass;
412- try
413- ZeroMemory(@Req,SizeOf(TRequestOptions));
414- ZeroMemory(@Res,SizeOf(TResponse));
400+ ZeroMemory(@Req,SizeOf(TRequestOptions));
401+ ZeroMemory(@Res,SizeOf(TResponse));
415402
416- Req.AutoClearSSLState := True;
403+ Req.AutoClearSSLState := True;
417404
418- Req.InternetOpenParams.Agent := 'MantisBT Monitor';
419- Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
420- Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
421- Req.InternetConnectParams.Context := AHandle;
405+ Req.InternetOpenParams.Agent := 'MantisBT Monitor';
406+ Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
407+ Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
408+ Req.InternetConnectParams.Context := AHandle;
422409
423- Req.HttpOpenRequestParams.Verb := 'GET';
424- Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
410+ Req.HttpOpenRequestParams.Verb := 'GET';
411+ Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
412+ try
413+ Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
414+ Req.HttpOpenRequestParams.Context := AHandle;
415+ Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
416+ Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
417+ Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
418+
419+ Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/mbtm/MantisConfigs.php');
420+ Res.Content := TStringStream.Create('',TEncoding.UTF8);
425421 try
426- Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
427- Req.HttpOpenRequestParams.Context := AHandle;
428- Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
429- Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
430- Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
422+ Request(Req,Res);
431423
432- Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/mbtm/MantisConfigs.php');
433- Res.Content := TStringStream.Create('',TEncoding.UTF8);
424+ MantisConfigs := TJSONObject.ParseJSONValue((Res.Content as TStringStream).DataString) as TJSONObject;
434425 try
435- Request(Req,Res);
426+ JSONArray := MantisConfigs.GetValue<TJSONArray>('statuses');
436427
437- MantisConfigs := TJSONObject.ParseJSONValue((Res.Content as TStringStream).DataString) as TJSONObject;
438- try
439- JSONArray := MantisConfigs.GetValue<TJSONArray>('statuses');
428+ for JSONValue in JSONArray do
429+ begin
430+ Status.Id := JSONValue.GetValue<Integer>('id');
431+ Status.Description := JSONValue.GetValue<String>('description');
432+ Status.Color := JSONValue.GetValue<Integer>('color');
433+ Status.IsDefault := JSONValue.GetValue<Boolean>('default');
434+ // Nova forma de incrementar um array, a partir do Delphi XE7
435+ // https://docwiki.embarcadero.com/RADStudio/XE7/en/What%27s_New_in_Delphi_and_C%2B%2BBuilder_XE7#String-Like_Operations_Supported_on_Dynamic_Arrays
436+ AMantisConfigs.Statuses := AMantisConfigs.Statuses + [Status];
437+ end;
440438
441- for JSONValue in JSONArray do
442- begin
443- Status.Id := JSONValue.GetValue<Integer>('id');
444- Status.Description := JSONValue.GetValue<String>('description');
445- Status.Color := JSONValue.GetValue<Integer>('color');
446- Status.IsDefault := JSONValue.GetValue<Boolean>('default');
447- // Nova forma de incrementar um array, a partir do Delphi XE7
448- // https://docwiki.embarcadero.com/RADStudio/XE7/en/What%27s_New_in_Delphi_and_C%2B%2BBuilder_XE7#String-Like_Operations_Supported_on_Dynamic_Arrays
449- AMantisConfigs.Statuses := AMantisConfigs.Statuses + [Status];
450- end;
439+ JSONArray := MantisConfigs.GetValue<TJSONArray>('priorities');
451440
452- JSONArray := MantisConfigs.GetValue<TJSONArray>('priorities');
453-
454- for JSONValue in JSONArray do
455- begin
456- Priority.Id := JSONValue.GetValue<Integer>('id');
457- Priority.Description := JSONValue.GetValue<String>('description');
458- AMantisConfigs.Priorities := AMantisConfigs.Priorities + [Priority];
459- end;
460- finally
461- MantisConfigs.Free;
441+ for JSONValue in JSONArray do
442+ begin
443+ Priority.Id := JSONValue.GetValue<Integer>('id');
444+ Priority.Description := JSONValue.GetValue<String>('description');
445+ AMantisConfigs.Priorities := AMantisConfigs.Priorities + [Priority];
462446 end;
463447 finally
464- Res.Content.Free;
448+ MantisConfigs.Free;
465449 end;
466450 finally
467- Req.HttpOpenRequestParams.AcceptTypes.Free;
451+ Res.Content.Free;
468452 end;
469453 finally
470- Screen.Cursor := crDefault;
454+ Req.HttpOpenRequestParams.AcceptTypes.Free;
471455 end;
472456 end;
473457
@@ -1010,7 +994,6 @@
1010994 var Status: TStatus := ATask.Status;
1011995
1012996 Status.Description := HTMLElement.InnerText;
1013-// ParseStatusColorAndId(((HTMLElement as IHTMLDOMNode).FirstChild as IHTMLElement)._ClassName,Status);
1014997 ParseStatusColorAndId(FirstChildElement(HTMLElement)._className,Status);
1015998 Status.IsDefault := DefaultStatusId = Status.Id;
1016999
@@ -1042,6 +1025,24 @@
10421025 ATask.AdditionalInformation := HTMLElement.InnerHtml;
10431026 end;
10441027 end;
1028+ // Obtendo tokens e outras informações necessárias para realização de ações
1029+ // especiais na tarefa
1030+ HTMLElementCollection := (HTMLDocument as IHTMLDocument3).GetElementsByTagName('input') as IHTMLElementCollection;
1031+
1032+ if HTMLElementCollection.length > 0 then
1033+ begin
1034+ var HTMLInputElement: IHTMLInputElement;
1035+
1036+ for var i: Word := 0 to Pred(HTMLElementCollection.length) do
1037+ begin
1038+ HTMLInputElement := (HTMLElementCollection as IHTMLElementCollection4).item(i) as IHTMLInputElement;
1039+ // Os nomes dos inputs são únicos na página de exibição da tarefa
1040+ if HTMLInputElement.name = 'bug_update_token' then
1041+ ATask.AssignToToken := HTMLInputElement.Value
1042+ else if HTMLInputElement.Name = 'last_updated' then
1043+ ATask.AssignToLastUpdated := HTMLInputElement.Value;
1044+ end;
1045+ end;
10451046 // Obtendo todos os <input> contidos no <form> com id "bugnoteadd" e
10461047 // varrendo-os em busca daqueles que tem nomes específicos a fim de obter
10471048 // seus valores
@@ -1061,7 +1062,6 @@
10611062 ATask.MaxFileSize := StrToInt(HTMLInputElement.Value);
10621063 end;
10631064 end;
1064-
10651065 // Retorna todos os <select> e varre-os buscando aquele que contém a lista
10661066 // suspensa de possíveis mudanças de status
10671067 HTMLElementCollection := (HTMLDocument as IHTMLDocument3).GetElementsByTagName('select');
@@ -1372,13 +1372,15 @@
13721372 end;
13731373 {$WARN SYMBOL_PLATFORM ON}
13741374
1375-function TaskDetails(AHandle: Cardinal; var ATask: TTask): Boolean;
1375+function TaskDetails(AHandle: Cardinal; AFormToBlock: TForm; var ATask: TTask): Boolean;
13761376 var
13771377 Req: TRequestOptions;
13781378 Res: TResponse;
13791379 begin
1380- Screen.Cursor := crHourGlass;
1380+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
13811381 try
1382+ UpdateStatusForm(FB,'Por favor aguarde enquanto os detalhes da tarefa são obtidos...');
1383+
13821384 ZeroMemory(@Req,SizeOf(TRequestOptions));
13831385 ZeroMemory(@Res,SizeOf(TResponse));
13841386
@@ -1411,7 +1413,7 @@
14111413 Req.HttpOpenRequestParams.AcceptTypes.Free;
14121414 end;
14131415 finally
1414- Screen.Cursor := crDefault;
1416+ HideStatusForm(FB);
14151417 end;
14161418 end;
14171419
@@ -1464,7 +1466,7 @@
14641466 ATasks[i].Id := StrToInt(Trim(HTMLElement.InnerText));
14651467
14661468 if AFullInfo then
1467- TaskDetails(AHandle,ATasks[i])
1469+ TaskDetails(AHandle,nil,ATasks[i])
14681470 else
14691471 begin
14701472 // Primeiro <i> dentro da primeira coluna
@@ -1512,13 +1514,15 @@
15121514 end;
15131515 {$WARN SYMBOL_PLATFORM ON}
15141516
1515-function AssignedTasks(AHandle: Cardinal; out ATasks: TTasks; AFullInfo: Boolean = False): Boolean;
1517+function AssignedTasks(AHandle: Cardinal; AFormToBlock: TForm; out ATasks: TTasks; AFullInfo: Boolean = False): Boolean;
15161518 var
15171519 Req: TRequestOptions;
15181520 Res: TResponse;
15191521 begin
1520- Screen.Cursor := crHourGlass;
1522+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
15211523 try
1524+ UpdateStatusForm(FB,'Por favor aguarde enquanto todas as suas tarefas são obtidas...');
1525+
15221526 ZeroMemory(@Req,SizeOf(TRequestOptions));
15231527 ZeroMemory(@Res,SizeOf(TResponse));
15241528
@@ -1551,17 +1555,19 @@
15511555 Req.HttpOpenRequestParams.AcceptTypes.Free;
15521556 end;
15531557 finally
1554- Screen.Cursor := crDefault;
1558+ HideStatusForm(FB);
15551559 end;
15561560 end;
15571561
1558-function GetAttachmentData(AHandle: Cardinal; AId: Cardinal; out AData: TMemoryStream): Boolean;
1562+function GetAttachmentData(AHandle: Cardinal; AFormToBlock: TForm; AId: Cardinal; out AData: TMemoryStream): Boolean;
15591563 var
15601564 Req: TRequestOptions;
15611565 Res: TResponse;
15621566 begin
1563- Screen.Cursor := crHourGlass;
1567+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
15641568 try
1569+ UpdateStatusForm(FB,'Por favor aguarde enquanto os dados do anexo são obtidos...');
1570+
15651571 ZeroMemory(@Req,SizeOf(TRequestOptions));
15661572 ZeroMemory(@Res,SizeOf(TResponse));
15671573
@@ -1597,19 +1603,21 @@
15971603 Req.HttpOpenRequestParams.AcceptTypes.Free;
15981604 end;
15991605 finally
1600- Screen.Cursor := crDefault;
1606+ HideStatusForm(FB);
16011607 end;
16021608 end;
16031609
16041610 {$WARN SYMBOL_PLATFORM OFF}
1605-function GetCommentForEdition(AHandle: Cardinal; ACommentId: Cardinal; out AComment: String; out AUpdateToken: String): Boolean;
1611+function GetCommentForEdition(AHandle: Cardinal; AFormToBlock: TForm; ACommentId: Cardinal; out AComment: String; out AUpdateToken: String): Boolean;
16061612 var
16071613 Req: TRequestOptions;
16081614 Res: TResponse;
16091615 HTMLDocument: IHTMLdocument;
16101616 begin
1611- Screen.Cursor := crHourGlass;
1617+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
16121618 try
1619+ UpdateStatusForm(FB,'Por favor aguarde enquanto o comentário está sendo obtido...');
1620+
16131621 ZeroMemory(@Req,SizeOf(TRequestOptions));
16141622 ZeroMemory(@Res,SizeOf(TResponse));
16151623 AComment := '';
@@ -1662,7 +1670,7 @@
16621670 Req.HttpOpenRequestParams.AcceptTypes.Free;
16631671 end;
16641672 finally
1665- Screen.Cursor := crDefault;
1673+ HideStatusForm(FB);
16661674 end;
16671675 end;
16681676 {$WARN SYMBOL_PLATFORM ON}
@@ -1849,7 +1857,7 @@
18491857 // end;
18501858 end;
18511859
1852-function AddComment(AHandle: Cardinal; ATask: TTask; AComment: String; ACommentIsPrivate: Boolean; AAttachments: array of String; out AError: String): Boolean;
1860+function AddComment(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AComment: String; ACommentHeaderDescription: String; ACommentIsPrivate: Boolean; AAttachments: TArray<String>; out AError: String): Boolean;
18531861 const
18541862 BOUNDARY: RawByteString = 'MantisBTMonitor-2A57FA77-3372-47B1-B365-5C9F38ACF786';
18551863 var
@@ -1864,11 +1872,13 @@
18641872
18651873 Req.AutoClearSSLState := True;
18661874
1875+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
18671876 Req.Content := TMemoryStream.Create;
18681877 try
1878+ UpdateStatusForm(FB,'Por favor aguarde enquanto o comentário está sendo salvo...');
18691879 // Adiciona o cabeçalho padrão de acordo com as configurações atuais, caso
18701880 // já não exista um cabeçalho
1871- AddCommentHeader(AComment);
1881+ AddCommentHeader(AComment,ACommentHeaderDescription);
18721882
18731883 AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bugnote_add_token',RawByteString(ATask.AddCommentToken),BOUNDARY);
18741884 AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_id',RawByteString(ATask.Id.ToString),BOUNDARY);
@@ -1923,6 +1933,7 @@
19231933 end;
19241934 finally
19251935 Req.Content.Free;
1936+ HideStatusForm(FB);
19261937 end;
19271938 end;
19281939
@@ -2023,7 +2034,6 @@
20232034 i: Word;
20242035 begin
20252036 Result := False;
2026- HTMLDocument := coHTMLDocument.Create as IHTMLDocument;
20272037
20282038 HTMLDocument := coHTMLDocument.Create as IHTMLDocument;
20292039 (HTMLDocument as IHTMLDocument2).DesignMode := 'On';
@@ -2048,7 +2058,7 @@
20482058 end;
20492059 end;
20502060
2051-function ChangeStatus(AHandle: Cardinal; ATaskId: Cardinal; ANewStatus: String; AComment: String = ''; ACommentIsPrivate: Boolean = False; ACounter: Word = 0): Boolean;
2061+function ChangeStatus(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; ANewStatus: String; AComment: String = ''; ACommentIsPrivate: Boolean = False; ACounter: Word = 0): Boolean;
20522062 const
20532063 BOUNDARY: RawByteString = 'MantisBTMonitor-1F00CBD1-5117-49A0-84F0-A3A4102DE66E';
20542064 var
@@ -2056,75 +2066,195 @@
20562066 LastUpdated: String;
20572067 NewStatusId: Word;
20582068 begin
2059- NewStatusId := Configurations.MantisConfigs.StatusByName[ANewStatus].Id;
2069+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
2070+ try
2071+ UpdateStatusForm(FB,'Por favor aguarde enquanto a situação da tarefa é alterada...');
20602072
2061- Result := GetChangeStatusParameters(AHandle,ATaskId,NewStatusId,BugUpdateToken,LastUpdated);
2073+ NewStatusId := Configurations.MantisConfigs.StatusByName[ANewStatus].Id;
20622074
2063- if Result then
2064- begin
2065- // Não existe motivo especial para eu usar Default ao invéz de ZeroMemory,
2066- // apenas eu achei que aqui ficava mais elegante usar Default e economizar 2
2067- // linhas de código
2068- var Req: TRequestOptions := Default(TRequestOptions);
2069- var Res: TResponse := Default(TResponse);
2075+ Result := GetChangeStatusParameters(AHandle,ATask.Id,NewStatusId,BugUpdateToken,LastUpdated);
20702076
2071- Req.AutoClearSSLState := True;
2077+ if Result then
2078+ begin
2079+ // Não existe motivo especial para eu usar Default ao invéz de ZeroMemory,
2080+ // apenas eu achei que aqui ficava mais elegante usar Default e economizar 2
2081+ // linhas de código
2082+ var Req: TRequestOptions := Default(TRequestOptions);
2083+ var Res: TResponse := Default(TResponse);
20722084
2073- Req.Content := TMemoryStream.Create;
2074- try
2075- // Adiciona o cabeçalho padrão de acordo com as configurações atuais de
2076- // unidade, caso já não exista um cabeçalho. Um cabeçalho só vai existir
2077- // neste ponto caso ele tenha sido incluído de forma manual em AComment.
2078- // Isso deve acontecer apenas em mudanças de status de aprovação ou
2079- // reprovação
2080- AddCommentHeader(AComment,'<stat>' + ANewStatus + ' (' + ACounter.ToString + ')</stat>');
2085+ Req.AutoClearSSLState := True;
20812086
2082- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_update_token',RawByteString(BugUpdateToken),BOUNDARY);
2083- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_id',RawByteString(ATaskId.ToString),BOUNDARY);
2084- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','status',RawByteString(NewStatusId.ToString),BOUNDARY);
2085- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','last_updated',RawByteString(LastUpdated),BOUNDARY);
2086- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','handler_id',RawByteString(Configurations.UserInfo.Id.ToString),BOUNDARY);
2087+ Req.Content := TMemoryStream.Create;
2088+ try
2089+ // Adiciona o cabeçalho padrão de acordo com as configurações atuais de
2090+ // unidade, caso já não exista um cabeçalho. Um cabeçalho só vai existir
2091+ // neste ponto caso ele tenha sido incluído de forma manual em AComment.
2092+ // Isso deve acontecer apenas em mudanças de status de aprovação ou
2093+ // reprovação
2094+ AddCommentHeader(AComment,'<stat>' + ANewStatus + ' (' + ACounter.ToString + ')</stat>');
20872095
2088- if ACommentIsPrivate then
2089- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','private','on',BOUNDARY);
2096+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_update_token',RawByteString(BugUpdateToken),BOUNDARY);
2097+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_id',RawByteString(ATask.Id.ToString),BOUNDARY);
2098+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','status',RawByteString(NewStatusId.ToString),BOUNDARY);
2099+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','last_updated',RawByteString(LastUpdated),BOUNDARY);
2100+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','handler_id',RawByteString(Configurations.UserInfo.Id.ToString),BOUNDARY);
20902101
2091- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bugnote_text',UTF8Encode(AComment),BOUNDARY);
2092- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','action_type','change_status',BOUNDARY);
2102+ if ACommentIsPrivate then
2103+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','private','on',BOUNDARY);
20932104
2094- Req.InternetOpenParams.Agent := 'MantisBT Monitor';
2095- Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
2096- Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/bug_update.php');
2097- Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
2098- Req.InternetConnectParams.Context := AHandle;
2099- Req.HttpOpenRequestParams.Verb := 'POST';
2100- Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
2105+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bugnote_text',UTF8Encode(AComment),BOUNDARY);
2106+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','action_type','change_status',BOUNDARY);
21012107
2102- try
2103- Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
2104- Req.HttpOpenRequestParams.Context := AHandle;
2105- Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
2106- Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
2107- Req.HttpOpenRequestParams.Headers := TStringList.Create;
2108+ Req.InternetOpenParams.Agent := 'MantisBT Monitor';
2109+ Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
2110+ Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/bug_update.php');
2111+ Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
2112+ Req.InternetConnectParams.Context := AHandle;
2113+ Req.HttpOpenRequestParams.Verb := 'POST';
2114+ Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
2115+
21082116 try
2109- Req.HttpOpenRequestParams.Headers.Add('Content-Type: multipart/form-data; boundary=' + String(BOUNDARY));
2110- Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
2117+ Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
2118+ Req.HttpOpenRequestParams.Context := AHandle;
2119+ Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
2120+ Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
2121+ Req.HttpOpenRequestParams.Headers := TStringList.Create;
2122+ try
2123+ Req.HttpOpenRequestParams.Headers.Add('Content-Type: multipart/form-data; boundary=' + String(BOUNDARY));
2124+ Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
21112125
2112- Res.Content := TStringStream.Create('');
2113- try
2114- Request(Req,Res);
2115- Result := ParseChangeStatusResponse(TStringStream(Res.Content).DataString,NewStatusId);
2126+ Res.Content := TStringStream.Create('');
2127+ try
2128+ Request(Req,Res);
2129+ Result := ParseChangeStatusResponse(TStringStream(Res.Content).DataString,NewStatusId);
2130+ finally
2131+ Res.Content.Free;
2132+ end;
21162133 finally
2117- Res.Content.Free;
2134+ Req.HttpOpenRequestParams.Headers.Free;
21182135 end;
21192136 finally
2120- Req.HttpOpenRequestParams.Headers.Free;
2137+ Req.HttpOpenRequestParams.AcceptTypes.Free;
21212138 end;
21222139 finally
2123- Req.HttpOpenRequestParams.AcceptTypes.Free;
2140+ Req.Content.Free;
21242141 end;
2142+ end;
2143+ finally
2144+ HideStatusForm(FB);
2145+ end;
2146+end;
2147+
2148+function ParseForwardToTestOrHomologationResponse(ADocument: String): Boolean;
2149+var
2150+ HTMLDocument: IHTMLDocument;
2151+ HTMLElementCollection: IHTMLElementCollection;
2152+ HTMLElement: IHTMLElement;
2153+ i: Word;
2154+begin
2155+ Result := False;
2156+
2157+ HTMLDocument := coHTMLDocument.Create as IHTMLDocument;
2158+ (HTMLDocument as IHTMLDocument2).DesignMode := 'On';
2159+ (HTMLDocument as IHTMLDocument2).charset := 'utf-8';
2160+ {$WARN SYMBOL_PLATFORM OFF}
2161+ (HTMLDocument as IHTMLDocument2Disp).Write(ADocument);
2162+ {$WARN SYMBOL_PLATFORM ON}
2163+ (HTMLDocument as IHTMLDocument2).Close;
2164+
2165+// with tstringlist.Create do
2166+// try
2167+// Text := ADocument;
2168+// SaveToFile('d:\carlos.txt');
2169+// finally
2170+// Free;
2171+// end;
2172+
2173+ HTMLElementCollection := (HTMLDocument as IHTMLDocument3).GetElementsByTagName('td');
2174+
2175+ if HTMLElementCollection.Length > 0 then
2176+ for i := 0 to Pred(HTMLElementCollection.Length) do
2177+ begin
2178+ HTMLElement := (HTMLElementCollection as IHTMLElementCollection4).item(i) as IHTMLElement;
2179+
2180+ if HTMLElement._className = 'bug-assigned-to' then
2181+ begin
2182+ Result := HTMLElement.innerText = 'Gerência de Configuração';
2183+ Break;
2184+ end;
2185+ end;
2186+end;
2187+
2188+function ForwardToTestOrHomologation(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AHomologation: Boolean; AComment: String; ACommentIsPrivate: Boolean; AAttachments: TArray<String>; out ACommentError: String): Boolean;
2189+const
2190+ BOUNDARY: RawByteString = 'MantisBTMonitor-B2AEBE26-2316-4BA5-BEA2-BB98E782EC77';
2191+begin
2192+ var Req: TRequestOptions := Default(TRequestOptions);
2193+ var Res: TResponse := Default(TResponse);
2194+
2195+ Req.AutoClearSSLState := True;
2196+
2197+ var FB: TKRKFormBlender := ShowStatusForm(AFormToBlock);
2198+ Req.Content := TMemoryStream.Create;
2199+ try
2200+ if AHomologation then
2201+ UpdateStatusForm(FB,'Por favor aguarde enquanto a tarefa está sendo enviada para Homologação...')
2202+ else
2203+ UpdateStatusForm(FB,'Por favor aguarde enquanto a tarefa está sendo enviada para Testes...');
2204+
2205+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_update_token',RawByteString(ATask.AssignToToken),BOUNDARY);
2206+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','last_updated',RawByteString(ATask.AssignToLastUpdated),BOUNDARY);
2207+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','action_type','assign',BOUNDARY);
2208+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','handler_id','165',BOUNDARY); // Gerência de Configuração
2209+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_id',RawByteString(ATask.Id.ToString),BOUNDARY);
2210+
2211+ Req.InternetOpenParams.Agent := 'MantisBT Monitor';
2212+ Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
2213+ Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/bug_update.php');
2214+ Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
2215+ Req.InternetConnectParams.Context := AHandle;
2216+ Req.HttpOpenRequestParams.Verb := 'POST';
2217+ Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
2218+
2219+ try
2220+ Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
2221+ Req.HttpOpenRequestParams.Context := AHandle;
2222+ Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
2223+ Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
2224+ Req.HttpOpenRequestParams.Headers := TStringList.Create;
2225+ try
2226+ Req.HttpOpenRequestParams.Headers.Add('Content-Type: multipart/form-data; boundary=' + String(BOUNDARY));
2227+ Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
2228+
2229+ Res.Content := TStringStream.Create('');
2230+ try
2231+ Request(Req,Res);
2232+ // Eu não sei porque, mas eu tive de usar UTF8ToString aqui porque o
2233+ // resultado vinha como se tivesse sido convertido erradamente de
2234+ // UTF-8 para ANSI, aquilo que mostra dois caracteres por caractere
2235+ // acentuado. De qualquer forma, fazendo uso da função, tudo ficou
2236+ // correto
2237+ Result := ParseForwardToTestOrHomologationResponse(UTF8ToString(RawByteString(TStringStream(Res.Content).DataString)));
2238+
2239+ if Result then
2240+ begin
2241+ if AHomologation then
2242+ AddComment(AHandle,nil,ATask,AComment,'<fwho></fwho>',ACommentIsPrivate,AAttachments,ACommentError)
2243+ else
2244+ AddComment(AHandle,nil,ATask,AComment,'<fwte></fwte>',ACommentIsPrivate,AAttachments,ACommentError);
2245+ end;
2246+ finally
2247+ Res.Content.Free;
2248+ end;
2249+ finally
2250+ Req.HttpOpenRequestParams.Headers.Free;
2251+ end;
21252252 finally
2126- Req.Content.Free;
2253+ Req.HttpOpenRequestParams.AcceptTypes.Free;
21272254 end;
2255+ finally
2256+ Req.Content.Free;
2257+ HideStatusForm(FB);
21282258 end;
21292259 end;
21302260
--- trunk/client/src/lib/UTypes.pas (revision 80)
+++ trunk/client/src/lib/UTypes.pas (revision 81)
@@ -214,6 +214,8 @@
214214 FRelatedTasks: TRelatedTasks;
215215 FComments: TComments;
216216 FHistory: THistory;
217+ FAssignToToken: String;
218+ FAssignToLastUpdated: String;
217219
218220 function GetPreviousStatus: TPreviousStatus;
219221 function GetPreviousResponsible: TPreviousResponsible;
@@ -253,6 +255,8 @@
253255 property RelatedTasks: TRelatedTasks read FRelatedTasks write FRelatedTasks;
254256 property Comments: TComments read FComments write FComments;
255257 property History: THistory read FHistory write FHistory;
258+ property AssignToToken: String read FAssignToToken write FAssignToToken;
259+ property AssignToLastUpdated: String read FAssignToLastUpdated write FAssignToLastUpdated;
256260 property CommentById[ACommentId: Cardinal]: TComment read GetCommentById;
257261 { Estatísticas da tarefa }
258262 property AttachmentsCount: Word read GetAttachmentsCount;
--- trunk/client/src/UDamoPrincipal.pas (revision 80)
+++ trunk/client/src/UDamoPrincipal.pas (revision 81)
@@ -3,7 +3,7 @@
33 interface
44
55 uses
6- SysUtils, Classes, ImgList, Controls, UPngImageList, ExtCtrls, ActnList,
6+ SysUtils, Classes, ImgList, Forms, Controls, UPngImageList, ExtCtrls, ActnList,
77 XPStyleActnCtrls, ActnMan, Menus, Windows, Contnrs, SyncObjs,
88 Messages, System.ImageList, System.Actions, Vcl.PlatformDefaultStyleActnCtrls,
99 Graphics, Vcl.StdStyleActnCtrls, UScrapFunctions, UTypes;
@@ -21,6 +21,7 @@
2121 FTimeOut: TEvent;
2222 FCheckInterval: Byte;
2323 FTasks: TTasks;
24+ FFormToBlock: TForm;
2425 procedure TriggerGetTasks;
2526 procedure TriggerBeforeGetTasks;
2627 protected
@@ -31,7 +32,7 @@
3132
3233 procedure Pause;
3334 procedure Restart;
34- procedure ForceTimeOut;
35+ procedure ForceTimeOut(AFormToBlock: TForm);
3536 property OnGetTasks: TGetTasks read FOnGetTasks write FOnGetTasks;
3637 property OnBeforeGetTasks: TBeforeGetTasks read FOnBeforeGetTasks write FOnBeforeGetTasks;
3738 end;
@@ -94,7 +95,7 @@
9495 constructor Create(AOwner: TComponent); override;
9596 destructor Destroy; override;
9697
97- procedure Refresh;
98+ procedure Refresh(AFormToBlock: TForm = nil);
9899
99100 property SplashTimeOut: Cardinal read FSplashTimeOut write FSplashTimeOut;
100101 property Initializing: Boolean read FInitializing;
@@ -105,7 +106,7 @@
105106 {$R *.dfm}
106107
107108 uses
108- UFormSplash, UFormGeneralConfiguration, Forms, UConfigurations,
109+ UFormSplash, UFormGeneralConfiguration, UConfigurations,
109110 ActnMenus, UFormTask, ActiveX, UFunctions;
110111
111112 const
@@ -177,10 +178,10 @@
177178 AddMyTasksToPopUpMenu;
178179 end;
179180
180-procedure TDamoPrincipal.Refresh;
181+procedure TDamoPrincipal.Refresh(AFormToBlock: TForm = nil);
181182 begin
182183 // Interrompe o tempo de espera da thread, o que a força a executar sua tarefa
183- FTasksChecking.ForceTimeOut;
184+ FTasksChecking.ForceTimeOut(AFormToBlock);
184185 end;
185186
186187 procedure TDamoPrincipal.ClearPopUpMenu;
@@ -453,7 +454,8 @@
453454 wrSignaled: begin
454455 Synchronize(TriggerBeforeGetTasks);
455456
456- AssignedTasks(Application.Handle,FTasks);
457+ AssignedTasks(Application.Handle,FFormToBlock,FTasks);
458+ FFormToBlock := nil;
457459
458460 Synchronize(TriggerGetTasks);
459461
@@ -466,10 +468,13 @@
466468 end;
467469 end;
468470
469-procedure TTasksChecking.ForceTimeOut;
471+procedure TTasksChecking.ForceTimeOut(AFormToBlock: TForm);
470472 begin
471473 if Started and Assigned(FTimeOut) then
474+ begin
472475 FTimeOut.SetEvent;
476+ FFormToBlock := AFormToBlock;
477+ end;
473478 end;
474479
475480 // Eu não sei se o que eu fiz no Destrutor está correto, mas funciona. A minha
--- trunk/client/src/UDamoTask.pas (revision 80)
+++ trunk/client/src/UDamoTask.pas (revision 81)
@@ -212,7 +212,7 @@
212212 begin
213213 var AttachmentData: TMemoryStream;
214214
215- if GetAttachmentData(Application.Handle,AAttachmentId,AttachmentData) then
215+ if GetAttachmentData(Application.Handle,TForm(Owner),AAttachmentId,AttachmentData) then
216216 try
217217 SaveAttachmentDataToFile(AttachmentData,SADIAttachment.FileName,AOpen);
218218 finally
@@ -228,11 +228,11 @@
228228 CommentToken: String;
229229 Dummy2: TArray<String>;
230230 begin
231- if TFormManageNote.ShowMeModal(Self,FTask,ACommentId,Comment,Dummy1,Dummy2,CommentToken) = mrOk then
231+ if TFormManageNote.ShowMeModal(Self,ACommentId,Comment,Dummy1,Dummy2,CommentToken) = mrOk then
232232 begin
233233 CommentBackupCreate(ACommentId,Comment);
234234
235- if UpdateComment(Application.Handle,ACommentId,Comment,CommentToken) then
235+ if UpdateComment(Application.Handle,TForm(Owner),ACommentId,Comment,CommentToken) then
236236 begin
237237 CommentBackupDelete(ACommentId);
238238 Application.MessageBox('Seu comentário foi salvo com sucesso','Comentário salvo com sucesso',MB_ICONINFORMATION);
@@ -247,13 +247,15 @@
247247 var
248248 Comment: String;
249249 CommentIsPrivate: Boolean;
250+ Dummy: TArray<String>;
250251 begin
251- if TFormManageNote.ShowMeModal(Self.Owner,TSpecialMode.Execute,FTask.Id,Comment,CommentIsPrivate) = mrOk then
252+ if TFormManageNote.ShowMeModal(Self,TSpecialMode.Execute,FTask.Id,Comment,CommentIsPrivate,Dummy) = mrOk then
252253 begin
253254 CommentBackupCreate(0,Comment);
254255
255256 if ChangeStatus(Application.Handle
256- ,FTask.Id
257+ ,TForm(Owner)
258+ ,FTask
257259 ,STATUS_IN_PROGRESS
258260 ,Comment
259261 ,CommentIsPrivate
@@ -315,13 +317,15 @@
315317 var
316318 Comment: String;
317319 CommentIsPrivate: Boolean;
320+ Dummy: TArray<String>;
318321 begin
319- if TFormManageNote.ShowMeModal(Self.Owner,TSpecialMode.Impede,FTask.Id,Comment,CommentIsPrivate) = mrOk then
322+ if TFormManageNote.ShowMeModal(Self,TSpecialMode.Impede,FTask.Id,Comment,CommentIsPrivate,Dummy) = mrOk then
320323 begin
321324 CommentBackupCreate(0,Comment);
322325
323326 if ChangeStatus(Application.Handle
324- ,FTask.Id
327+ ,TForm(Owner)
328+ ,FTask
325329 ,STATUS_IMPEDIMENT
326330 ,Comment
327331 ,CommentIsPrivate
@@ -346,13 +350,15 @@
346350 var
347351 Comment: String;
348352 CommentIsPrivate: Boolean;
353+ Dummy: TArray<String>;
349354 begin
350- if TFormManageNote.ShowMeModal(Self.Owner,TSpecialMode.Reject,FTask.Id,Comment,CommentIsPrivate) = mrOk then
355+ if TFormManageNote.ShowMeModal(Self,TSpecialMode.Reject,FTask.Id,Comment,CommentIsPrivate,Dummy) = mrOk then
351356 begin
352357 CommentBackupCreate(0,Comment);
353358
354359 if ChangeStatus(Application.Handle
355- ,FTask.Id
360+ ,TForm(Owner)
361+ ,FTask
356362 ,STATUS_REJECTED
357363 ,Comment
358364 ,CommentIsPrivate
@@ -379,6 +385,10 @@
379385 end;
380386
381387 procedure TDamoTask.SendToTest;
388+var
389+ Comment: String;
390+ CommentIsPrivate: Boolean;
391+ Attachments: TArray<String>;
382392 begin
383393 //rejeição, impedimento e execução estão funcionando e contando a quantidade de vezes que eles aparecem
384394 //se precisar de mais alguma mudança de estado simples, copie de um desses
@@ -387,6 +397,40 @@
387397 //testes, pois tem um tag especial ([ufs-ii][T] e [UFS-II][H]). Voce vai ter que
388398 //criar um tag especial pra isso, tal como existem os tags especiais pra rejeição
389399 //e aprovação
400+ if TFormManageNote.ShowMeModal(Self,TSpecialMode.SendToTest,FTask.Id,Comment,CommentIsPrivate,Attachments) = mrOk then
401+ begin
402+ CommentBackupCreate(0,Comment);
403+
404+ var CommentError: String;
405+
406+ if ForwardToTestOrHomologation(Application.Handle
407+ ,TForm(Owner)
408+ ,FTask
409+ ,False
410+ ,Comment
411+ ,CommentIsPrivate
412+ ,Attachments
413+ ,CommentError) then
414+ begin
415+ CommentBackupDelete(0);
416+
417+ if Trim(CommentError) = '' then
418+ Application.MessageBox('Tarefa enviada para Testes com sucesso!','Encaminhamento bem sucedido',MB_ICONINFORMATION)
419+ else
420+ begin
421+ var ErrorId: String := Copy(CommentError,1,Pos('|',CommentError) - 1);
422+ var ErrorDescription: String := Copy(CommentError,Pos('|',CommentError) + 1, Length(CommentError));
423+
424+ Application.MessageBox(PChar('A tarefa foi enviada para Testes com suc'+
425+ 'esso contudo não foi possível adicionar o comentário padrão de encami'+
426+ 'nhamento. Os motivos são:'#13#10#13#10 + ErrorId + #13#10 + ErrorDescription),'Encaminhamento bem sucedido',MB_ICONWARNING);
427+ end;
428+ end
429+ else
430+ Application.MessageBox('Não foi possível enviar a tarefa para Testes. Tente novamente','Erro ao encaminhar a tarefa',MB_ICONERROR);
431+
432+ Refresh;
433+ end;
390434 end;
391435
392436 procedure TDamoTask.NewComment;
@@ -396,13 +440,13 @@
396440 Files: TArray<String>;
397441 Dummy: String;
398442 begin
399- if TFormManageNote.ShowMeModal(Self,FTask,0,Comment,CommentIsPrivate,Files,Dummy) = mrOk then
443+ if TFormManageNote.ShowMeModal(Self,0,Comment,CommentIsPrivate,Files,Dummy) = mrOk then
400444 begin
401445 var Error: String;
402446
403447 CommentBackupCreate(0,Comment);
404448
405- if AddComment(Application.Handle,FTask,Comment,CommentIsPrivate,Files,Error) then
449+ if AddComment(Application.Handle,TForm(Owner),FTask,Comment,'',CommentIsPrivate,Files,Error) then
406450 begin
407451 CommentBackupDelete(0);
408452 Application.MessageBox('Seu comentário foi inserido com sucesso. Caso você tenha adicionado anexos, eles também foram salvos','Comentário inserido com sucesso',MB_ICONINFORMATION);
@@ -425,11 +469,11 @@
425469 Dummy2: Boolean;
426470 Dummy3: String;
427471 begin
428- if TFormManageNote.ShowMeModal(Self,FTask,0,Dummy1,Dummy2,Files,Dummy3,True) = mrOk then
472+ if TFormManageNote.ShowMeModal(Self,0,Dummy1,Dummy2,Files,Dummy3,True) = mrOk then
429473 begin
430474 var Error: String;
431475
432- if AddComment(Application.Handle,FTask,Dummy1,Dummy2,Files,Error) then
476+ if AddComment(Application.Handle,TForm(Owner),FTask,Dummy1,'',Dummy2,Files,Error) then
433477 begin
434478 Application.MessageBox('Arquivos anexados com sucesso!','Arquivos anexados com sucesso!',MB_ICONINFORMATION);
435479 Refresh;
@@ -455,7 +499,7 @@
455499
456500 procedure TDamoTask.Refresh;
457501 begin
458- TFormTask(Owner).InitializeFormTask(FTask);
502+ TFormTask(Owner).InitializeFormTask(FTask,True);
459503 // InitializeFormTask chama LoadTaskHeader, que configura o Caption como
460504 // "Tarefa Mantis #XXXXXX", mas o Caption deve ser "Tarefa Mantis #XXXXXX -
461505 // MantisBT Monitor". Quando o form de tarefas é aberto, essa modificação é
@@ -466,7 +510,7 @@
466510 TFormTask(Owner).ConfigureCaption;
467511 // Força a rechecagem de todas as tarefas que montam o menu de contexto de
468512 // tarefas
469- FDamoPrincipal.Refresh;
513+ FDamoPrincipal.Refresh(TForm(Owner));
470514 end;
471515
472516 end.
--- trunk/client/src/UFormManageNote.pas (revision 80)
+++ trunk/client/src/UFormManageNote.pas (revision 81)
@@ -10,7 +10,7 @@
1010 UTypes, UDamoTask;
1111
1212 type
13- TSpecialMode = (None,Reject,Impede,Execute);
13+ TSpecialMode = (None,Reject,Impede,Execute,SendToTest,SendToHomologation);
1414
1515 TFormManageNote = class(TFormBasicDialog)
1616 PACO: TPageControl;
@@ -55,8 +55,8 @@
5555 procedure ValidateSave; override;
5656 public
5757 { Public declarations }
58- class function ShowMeModal(ADamoTask: TDamoTask; ATask: TTask; ACommentId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>; out AUpdateToken: String; AAttacmentshOnly: Boolean = False): TModalResult; reintroduce; overload;
59- class function ShowMeModal(AOwner: TComponent; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String; out APrivate: Boolean): TModalResult; reintroduce; overload;
58+ class function ShowMeModal(ADamoTask: TDamoTask; ACommentId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>; out AUpdateToken: String; AAttacmentshOnly: Boolean = False): TModalResult; reintroduce; overload;
59+ class function ShowMeModal(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>): TModalResult; reintroduce; overload;
6060 end;
6161
6262 implementation
@@ -122,7 +122,7 @@
122122
123123 function TFormManageNote.AttachmentsTabIsVisible: Boolean;
124124 begin
125- Result := (((not FUpdating) and (FSpecialMode = TSpecialMode.None)) or (FTask.CommentById[FCommentId].AttachmentsCount > 0)) and (not CHBXPrivate.Checked);
125+ Result := (((not FUpdating) and (FSpecialMode in [TSpecialMode.None,TSpecialMode.SendToTest,TSpecialMode.SendToHomologation])) or (FTask.CommentById[FCommentId].AttachmentsCount > 0)) and (not CHBXPrivate.Checked);
126126 end;
127127
128128 procedure TFormManageNote.CHBXPrivateClick(Sender: TObject);
@@ -303,10 +303,11 @@
303303 end;
304304 end;
305305
306-class function TFormManageNote.ShowMeModal(AOwner: TComponent; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String; out APrivate: Boolean): TModalResult;
306+class function TFormManageNote.ShowMeModal(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>): TModalResult;
307307 begin
308- with Self.Create(AOwner) do
308+ with Self.Create(ADamoTask.Owner) do
309309 begin
310+ FDamoTask := ADamoTask;
310311 AComment := '';
311312 Aprivate := False;
312313
@@ -322,6 +323,8 @@
322323 TSpecialMode.Reject: LABECaption.Caption := 'Rejeitando a tarefa #' + ATaskId.ToString;
323324 TSpecialMode.Impede: LABECaption.Caption := 'Impedindo a tarefa #' + ATaskId.ToString;
324325 TSpecialMode.Execute: LABECaption.Caption := 'Executando a tarefa #' + ATaskId.ToString;
326+ TSpecialMode.SendToTest: LABECaption.Caption := 'Enviando a tarefa #' + ATaskId.ToString + ' para Testes';
327+ TSpecialMode.SendToHomologation: LABECaption.Caption := 'Enviando a tarefa #' + ATaskId.ToString + ' para Homologação';
325328 end;
326329
327330 // Caso exista um backup, pergunta se quer carregar.
@@ -331,10 +334,11 @@
331334 Result := ShowModal;
332335 AComment := FComment;
333336 Aprivate := CHBXPrivate.Checked;
337+ AAttachments := FAttachments;
334338 end;
335339 end;
336340
337-class function TFormManageNote.ShowMeModal(ADamoTask: TDamoTask; ATask: TTask; ACommentId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>; out AUpdateToken: String; AAttacmentshOnly: Boolean = False): TModalResult;
341+class function TFormManageNote.ShowMeModal(ADamoTask: TDamoTask; ACommentId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>; out AUpdateToken: String; AAttacmentshOnly: Boolean = False): TModalResult;
338342 begin
339343 Result := mrAbort; // Se tudo der errado...
340344
@@ -341,7 +345,7 @@
341345 with Self.Create(ADamoTask.Owner) do
342346 begin
343347 FDamoTask := ADamoTask;
344- FTask := ATask;
348+ FTask := ADamoTask.Task;
345349 FCommentId := ACommentId;
346350 AComment := '';
347351 APrivate := False;
@@ -360,14 +364,14 @@
360364 Caption := 'Gerenciador de anotações e anexos - ' + Application.Title;
361365
362366 if FUpdating then
363- LABECaption.Caption := 'Alterando a anotação ~' + FCommentId.ToString + ' da tarefa #' + ATask.Id.ToString
367+ LABECaption.Caption := 'Alterando a anotação ~' + FCommentId.ToString + ' da tarefa #' + ADamoTask.Task.Id.ToString
364368 else
365- LABECaption.Caption := 'Redigindo uma nova anotação para a tarefa #' + ATask.Id.ToString;
369+ LABECaption.Caption := 'Redigindo uma nova anotação para a tarefa #' + ADamoTask.Task.Id.ToString;
366370
367371 // FAttachmentsOnly é true apenas se de fato isso for possível, logo, aqui
368372 // reconfiguramos a tela
369373 if FAttachmentsOnly then
370- LABECaption.Caption := 'Adicionando anexos à tarefa #' + ATask.Id.ToString;
374+ LABECaption.Caption := 'Adicionando anexos à tarefa #' + ADamoTask.Task.Id.ToString;
371375
372376 // Se estamos tentando editar um comentário..
373377 if FUpdating then
@@ -375,7 +379,7 @@
375379 // É obrigatório sempre executar esta função, pois mesmo que não usemos os
376380 // comentário original, ainda precisaremos do UpdateToken. Caso a função
377381 // não seja bem sucedida, terminamos o form com uma mensagem de erro
378- if not GetCommentForEdition(Handle,FCommentId,FComment,AUpdateToken) then
382+ if not GetCommentForEdition(Handle,nil,FCommentId,FComment,AUpdateToken) then
379383 begin
380384 Application.MessageBox('Não foi possível obter um comentário para edição. Por favor, tente novamente!','Erro ao obter um comentário',MB_ICONERROR);
381385 Close;
--- trunk/client/src/UFormTask.pas (revision 80)
+++ trunk/client/src/UFormTask.pas (revision 81)
@@ -101,6 +101,7 @@
101101 procedure ACTNSendToTestExecute(Sender: TObject);
102102 procedure ACTNSendToHomologationExecute(Sender: TObject);
103103 procedure ACTNImpeachmentExecute(Sender: TObject);
104+ procedure AMANUpdate(Action: TBasicAction; var Handled: Boolean);
104105 private
105106 { Private declarations }
106107 FDamoTask: TDamoTask;
@@ -138,7 +139,7 @@
138139 class function ShowMe(ADamoPrincipal: TDamoPrincipal; var ATask: TTask; ACommentId: Cardinal = 0; AModal: Boolean = False): TModalResult; overload;
139140 class function ShowMe(ADamoPrincipal: TDamoPrincipal; ATaskId: Cardinal; ACommentId: Cardinal = 0; AModal: Boolean = False): TModalResult; overload;
140141
141- procedure InitializeFormTask(var ATask: TTask);
142+ procedure InitializeFormTask(var ATask: TTask; AShowStatusForm: Boolean);
142143 end;
143144
144145 implementation
@@ -192,6 +193,18 @@
192193 FDamoTask.SendToTest;
193194 end;
194195
196+procedure TFormTask.AMANUpdate(Action: TBasicAction; var Handled: Boolean);
197+begin
198+ inherited;
199+ // Oculta ou mostra o separador dependendo da existência de ações visíveis
200+ // antes dele. Isso evita que se tenha um separador órfão no início da barra
201+ // de ferramentas
202+ AMAN.ActionBars[0].Items[7].Visible := ACTNExecute.Visible or ACTNTest.Visible
203+ or ACTNHomologate.Visible or ACTNSendToTest.Visible
204+ or ACTNSendToHomologation.Visible or ACTNApprove.Visible
205+ or ACTNDisapprove.Visible;
206+end;
207+
195208 constructor TFormTask.Create(ADamoPrincipal: TDamoPrincipal; AOwner: TComponent; ATaskId: Cardinal; ACommentId: Cardinal = 0);
196209 begin
197210 FDamoPrincipal := ADamoPrincipal;
@@ -459,11 +472,14 @@
459472 {$WARN SYMBOL_PLATFORM ON}
460473 end;
461474
462-procedure TFormTask.InitializeFormTask(var ATask: TTask);
475+procedure TFormTask.InitializeFormTask(var ATask: TTask; AShowStatusForm: Boolean);
463476 begin
464477 ATask.Clear;
465478
466- TaskDetails(Application.Handle,ATask);
479+ if AShowStatusForm then
480+ TaskDetails(Application.Handle,Self,ATask)
481+ else
482+ TaskDetails(Application.Handle,nil,ATask);
467483
468484 FDamoTask.Task := ATask;
469485
@@ -628,7 +644,7 @@
628644 begin
629645 AutoCaption := True;
630646
631- InitializeFormTask(ATask);
647+ InitializeFormTask(ATask,False);
632648
633649 // TaskDetails(Application.Handle,ATask);
634650 //
@@ -759,6 +775,9 @@
759775 // acordo com regras específicas
760776 ACTNSendToTest.Hide;
761777 ACTNSendToHomologation.Hide;
778+ { TODO : Se o botão de aprovação referenciado abeixo for usado também na
779+ aprovação de homologação, esta ação altera o status para homologado. Leve isso
780+ em conta }
762781 ACTNApprove.Hide;
763782 // Exibindo ou ocultando ações de acordo com diversos critérios para cada
764783 // perfil de usuário
@@ -771,7 +790,7 @@
771790 ACTNDisapprove.Hide;
772791 // Exibindo ou ocultando (mantendo ocultas) ações que dependem de status
773792 // epecificos
774- ACTNSendToTest.Visible := FDamoTask.Task.Status.Id = Configurations.MantisConfigs.StatusByName['em execução'].Id;
793+ ACTNSendToTest.Visible := (FDamoTask.Task.Status.Id = Configurations.MantisConfigs.StatusByName['em execução'].Id) and (FDamoTask.Task.Responsible = Configurations.UserInfo.RealName);
775794 ACTNSendToHomologation.Visible := ACTNSendToTest.Visible;
776795 end;
777796 pTester: begin
Show on old repository browser