• R/O
  • SSH
  • HTTPS

mantisbtmonitor: Commit


Commit MetaInfo

Revision88 (tree)
Time2022-08-05 05:45:12
Authorderekwildstar

Log Message

Criada uma interposer para facilitar o acesso aos itens de um TComboBox
Alterada a função ChangeStatus
Adicionada a função AddAttachment
Adicionada a função GetChangeStatusParameters
Utilização efetiva de AddTextMultipartFormData
Utilização efetiva de uma constante para o boundary em requisições POST
Novo tipo THandler criado
Criadas versões especiais de TFormManageNote.ShowMeModal para facilitar a execução desta função em rotinas que não utilizam todos os seus parâmetros
Todos os comentários de encaminhamento agora são públicos
Criada a enumeração TForwardingModes
Alterada a tela de criação de comentários para ser possível também alterar a atribuição da tarefa
Removido o campo privado FTask de TFormManageNote, visto que a tarefa pode ser obtida a partir de FDamoTask
Criada a função TFormManageNote.ConfigureOtherElements para configurar elementos de tela que não são nem da aba de comentários e nem da aba de anexos
A ação de execução só é exibida se a tarefa estiver atribuída a mim mesmo

Change Summary

Incremental Difference

--- trunk/client/prj/MantisBTMonitor.dproj (revision 87)
+++ trunk/client/prj/MantisBTMonitor.dproj (revision 88)
@@ -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.864;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.4;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,8 +126,8 @@
126126 <DCC_DebugInformation>2</DCC_DebugInformation>
127127 <DCC_SymbolReferenceInfo>2</DCC_SymbolReferenceInfo>
128128 <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
129- <VerInfo_Build>864</VerInfo_Build>
130129 <DCC_MapFile>3</DCC_MapFile>
130+ <VerInfo_Build>4</VerInfo_Build>
131131 </PropertyGroup>
132132 <ItemGroup>
133133 <DelphiCompile Include="$(MainSource)">
--- trunk/client/src/lib/UInterposersAndHelpers.pas (revision 87)
+++ trunk/client/src/lib/UInterposersAndHelpers.pas (revision 88)
@@ -4,7 +4,7 @@
44
55 uses
66 SHDocVw, Winapi.Windows, Winapi.Messages, System.Classes, Vcl.ComCtrls,
7- Winapi.ShellAPI, Vcl.ActnList;
7+ Winapi.ShellAPI, Vcl.ActnList, Vcl.StdCtrls;
88
99 type
1010 // Se for útil, colcar no Krakatoa
@@ -78,6 +78,12 @@
7878 //procedure Show(ATag: Word); overload;
7979 end;
8080
81+ TComboBox = class(Vcl.StdCtrls.TComboBox)
82+ public
83+ function SelectionAsCardinal: Cardinal;
84+ function SelectionAsObject: TObject;
85+ end;
86+
8187 implementation
8288
8389 uses
@@ -275,6 +281,22 @@
275281 Visible := False;
276282 end;
277283
284+{ TComboBox }
285+
286+function TComboBox.SelectionAsCardinal: Cardinal;
287+begin
288+ Result := Cardinal(SelectionAsObject);
289+end;
290+
291+function TComboBox.SelectionAsObject: TObject;
292+begin
293+ Result := nil;
294+
295+ if ItemIndex > -1 then
296+ Result := Items.Objects[ItemIndex];
297+end;
298+
299+
278300 //procedure TAction.Show;
279301 //begin
280302 // Visible := True;
--- trunk/client/src/lib/UScrapFunctions.pas (revision 87)
+++ trunk/client/src/lib/UScrapFunctions.pas (revision 88)
@@ -16,7 +16,11 @@
1616 function PrepareCommentForJavaScriptString(AComment: String): String; deprecated 'Não acho que vou usar isso no futuro, mas mantenha por ora';
1717 function UpdateComment(AHandle: Cardinal; AFormToBlock: TForm; ACommentId: Cardinal; AComment: String; AUpdateToken: String): Boolean;
1818 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;
19+//: A função AddAttachment é uma especialização da função AddComment, usada para
20+//: anexar apenas arquivos a uma tarefa.
21+function AddAttachment(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AAttachments: TArray<String>; out AError: String): Boolean;
22+function GetChangeStatusParameters(AHandle: Cardinal; ATaskId: Cardinal; ANewStatusId: Word; out ABugUpdateToken: String; out ALastUpdated: String; out AHandlers: TArray<THandler>): Boolean;
23+function ChangeStatus(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; ANewStatus: String; ANewStatusId: Word; ABugUpdateToken: String; ALastUpdated: String; AComment: String; ACommentIsPrivate: Boolean; ACounter: Word; AHandlerId: Cardinal = 0): Boolean;
2024 function ForwardToTestOrHomologation(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AHomologation: Boolean; AComment: String; ACommentIsPrivate: Boolean; AAttachments: TArray<String>; out ACommentError: String): Boolean;
2125
2226 implementation
@@ -28,6 +32,73 @@
2832 KRK.Internet.MSHTML.Utilities, ActiveX, KRK.Rtl.Common.FileUtils, UFunctions,
2933 KRK.Vcl.Forms.FormBlender, UFORMStatus;
3034
35+procedure WriteStream(AStream: TStream; AValue: RawByteString);
36+var
37+ i: Cardinal;
38+begin
39+ for i := 1 to Length(AValue) do
40+ AStream.Write(AValue[i],1);
41+end;
42+
43+// Antes de chamar estes procedures pela primeira vez, garanta que o stream está
44+// na posição correta (position = 0). Chamadas subsequentes não precisam lidar
45+// com posicionamentos
46+procedure AddTextMultiPartFormData(ARequestStream: TMemoryStream; AContentDisposition: RawByteString; AFieldName: RawByteString; AContent: RawByteString; ABoundary: RawByteString; AContentType: RawByteString = ''; ALastPart: Boolean = False);
47+var
48+ Aux: RawByteString;
49+begin
50+ // Monta o cabeçalho da parte, juntamente com seu conteúdo e escreve no stream
51+ Aux := '--' + ABoundary + #13#10
52+ + 'Content-Disposition: ' + AContentDisposition + '; name="' + AFieldName + '"'#13#10;
53+
54+ if AContentType <> '' then
55+ Aux := Aux + 'Content-Type: ' + AContentType + #13#10;
56+
57+ Aux := Aux + #13#10;
58+ Aux := Aux + AContent + #13#10;
59+
60+ WriteStream(ARequestStream,Aux);
61+
62+ // Caso esta seja a última parte, grava no stream o boundary finalizador
63+ if ALastPart then
64+ begin
65+ Aux := '--' + ABoundary + '--';
66+ WriteStream(ARequestStream,Aux);
67+ end;
68+end;
69+
70+procedure AddFileMultiPartFormData(ARequestStream: TMemoryStream; AContentDisposition: RawByteString; AFieldName: RawByteString; AFileName: TFileName; ABoundary: RawByteString; ALastPart: Boolean = False);
71+var
72+ Aux: RawByteString;
73+ FileStream: TFileStream;
74+begin
75+ if not FileExists(AFileName) then
76+ raise Exception.Create('Arquivo inexistente!');
77+
78+ // Monta o cabeçalho da parte e escreve no stream
79+ Aux := '--' + ABoundary + #13#10
80+ + 'Content-Disposition: ' + AContentDisposition + '; name="' + AFieldName + '"; filename="' + RawByteString(ExtractFileName(AFileName)) + '"'#13#10
81+ + 'Content-Type: ' + GetFileMIMEType(AFileName) + #13#10#13#10;
82+
83+ WriteStream(ARequestStream,Aux);
84+
85+ // Copia os bytes do arquivo, escrevendo os no stream
86+ FileStream := TFileStream.Create(AFileName,fmOpenRead);
87+ try
88+ ARequestStream.CopyFrom(FileStream,FileStream.Size);
89+ WriteStream(ARequestStream,#13#10);
90+ finally
91+ FileStream.Free;
92+ end;
93+
94+ // Caso esta seja a última parte, grava no stream o boundary finalizador
95+ if ALastPart then
96+ begin
97+ Aux := '--' + ABoundary + '--';
98+ WriteStream(ARequestStream,Aux);
99+ end;
100+end;
101+
31102 function Logout(AHandle: Cardinal): Boolean;
32103 var
33104 Req: TRequestOptions;
@@ -315,6 +386,8 @@
315386
316387 {$WARN SYMBOL_PLATFORM OFF}
317388 function UpdateComment(AHandle: Cardinal; AFormToBlock: TForm; ACommentId: Cardinal; AComment: String; AUpdateToken: String): Boolean;
389+const
390+ BOUNDARY: RawByteString = 'MBTM-E1B5DD30-CEC1-457E-B83B-486A1D00D8AD';
318391 var
319392 Req: TRequestOptions;
320393 Res: TResponse;
@@ -330,7 +403,8 @@
330403
331404 Req.AutoClearSSLState := True;
332405
333- Req.Content := TStringStream.Create('',TEncoding.UTF8);
406+ //Req.Content := TStringStream.Create('',TEncoding.UTF8);
407+ Req.Content := TMemoryStream.Create;
334408 try
335409 // Adiciona o cabeçalho padrão de acordo com as configurações atuais, caso
336410 // já não exista um cabeçalho
@@ -351,22 +425,15 @@
351425 Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
352426 Req.HttpOpenRequestParams.Headers := TStringList.Create;
353427 try
354- Req.HttpOpenRequestParams.Headers.Add('content-type: multipart/form-data; boundary=MBTM');
428+ Req.HttpOpenRequestParams.Headers.Add('content-type: multipart/form-data; boundary=' + String(BOUNDARY));
355429 Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
356430
357431 Res.Content := TStringStream.Create('',TEncoding.UTF8);
358432 try
359433 // Montando o conteúdo da requisição
360- (Req.Content as TStringStream).WriteString('--MBTM'#13#10);
361- (Req.Content as TStringStream).WriteString('content-disposition: form-data; name="bugnote_update_token"'#13#10#13#10);
362- (Req.Content as TStringStream).WriteString(AUpdateToken + #13#10);
363- (Req.Content as TStringStream).WriteString('--MBTM'#13#10);
364- (Req.Content as TStringStream).WriteString('content-disposition: form-data; name="bugnote_id"'#13#10#13#10);
365- (Req.Content as TStringStream).WriteString(ACommentId.ToString + #13#10);
366- (Req.Content as TStringStream).WriteString('--MBTM'#13#10);
367- (Req.Content as TStringStream).WriteString('content-disposition: form-data; name="bugnote_text"'#13#10#13#10);
368- (Req.Content as TStringStream).WriteString(AComment + #13#10);
369- (Req.Content as TStringStream).WriteString('--MBTM--');
434+ AddTextMultipartFormData(TMemoryStream(Req.Content),'form-data','bugnote_update_token',RawByteString(AUpdateToken),BOUNDARY);
435+ AddTextMultipartFormData(TMemoryStream(Req.Content),'form-data','bugnote_id',RawByteString(ACommentId.ToString),BOUNDARY);
436+ AddTextMultipartFormData(TMemoryStream(Req.Content),'form-data','bugnote_text',UTF8Encode(AComment),BOUNDARY,'',True);
370437
371438 Request(Req,Res);
372439
@@ -1729,73 +1796,6 @@
17291796 end;
17301797 {$WARN SYMBOL_PLATFORM ON}
17311798
1732-procedure WriteStream(AStream: TStream; AValue: RawByteString);
1733-var
1734- i: Cardinal;
1735-begin
1736- for i := 1 to Length(AValue) do
1737- AStream.Write(AValue[i],1);
1738-end;
1739-
1740-// Antes de chamar estes procedures pela primeira vez, garanta que o stream está
1741-// na posição correta (position = 0). Chamadas subsequentes não precisam lidar
1742-// com posicionamentos
1743-procedure AddTextMultiPartFormData(ARequestStream: TMemoryStream; AContentDisposition: RawByteString; AFieldName: RawByteString; AContent: RawByteString; ABoundary: RawByteString; AContentType: RawByteString = ''; ALastPart: Boolean = False);
1744-var
1745- Aux: RawByteString;
1746-begin
1747- // Monta o cabeçalho da parte, juntamente com seu conteúdo e escreve no stream
1748- Aux := '--' + ABoundary + #13#10
1749- + 'Content-Disposition: ' + AContentDisposition + '; name="' + AFieldName + '"'#13#10;
1750-
1751- if AContentType <> '' then
1752- Aux := Aux + 'Content-Type: ' + AContentType + #13#10;
1753-
1754- Aux := Aux + #13#10;
1755- Aux := Aux + AContent + #13#10;
1756-
1757- WriteStream(ARequestStream,Aux);
1758-
1759- // Caso esta seja a última parte, grava no stream o boundary finalizador
1760- if ALastPart then
1761- begin
1762- Aux := '--' + ABoundary + '--';
1763- WriteStream(ARequestStream,Aux);
1764- end;
1765-end;
1766-
1767-procedure AddFileMultiPartFormData(ARequestStream: TMemoryStream; AContentDisposition: RawByteString; AFieldName: RawByteString; AFileName: TFileName; ABoundary: RawByteString; ALastPart: Boolean = False);
1768-var
1769- Aux: RawByteString;
1770- FileStream: TFileStream;
1771-begin
1772- if not FileExists(AFileName) then
1773- raise Exception.Create('Arquivo inexistente!');
1774-
1775- // Monta o cabeçalho da parte e escreve no stream
1776- Aux := '--' + ABoundary + #13#10
1777- + 'Content-Disposition: ' + AContentDisposition + '; name="' + AFieldName + '"; filename="' + RawByteString(ExtractFileName(AFileName)) + '"'#13#10
1778- + 'Content-Type: ' + GetFileMIMEType(AFileName) + #13#10#13#10;
1779-
1780- WriteStream(ARequestStream,Aux);
1781-
1782- // Copia os bytes do arquivo, escrevendo os no stream
1783- FileStream := TFileStream.Create(AFileName,fmOpenRead);
1784- try
1785- ARequestStream.CopyFrom(FileStream,FileStream.Size);
1786- WriteStream(ARequestStream,#13#10);
1787- finally
1788- FileStream.Free;
1789- end;
1790-
1791- // Caso esta seja a última parte, grava no stream o boundary finalizador
1792- if ALastPart then
1793- begin
1794- Aux := '--' + ABoundary + '--';
1795- WriteStream(ARequestStream,Aux);
1796- end;
1797-end;
1798-
17991799 function ParseAddCommentResponse(ADocument: String; out AError: String): Boolean;
18001800 var
18011801 HTMLDocument: IHTMLDocument;
@@ -1875,7 +1875,7 @@
18751875
18761876 function AddComment(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AComment: String; ACommentHeaderDescription: String; ACommentIsPrivate: Boolean; AAttachments: TArray<String>; out AError: String): Boolean;
18771877 const
1878- BOUNDARY: RawByteString = 'MantisBTMonitor-2A57FA77-3372-47B1-B365-5C9F38ACF786';
1878+ BOUNDARY: RawByteString = 'MBTM-2A57FA77-3372-47B1-B365-5C9F38ACF786';
18791879 var
18801880 Req: TRequestOptions;
18811881 Res: TResponse;
@@ -1953,11 +1953,15 @@
19531953 end;
19541954 end;
19551955
1956-function ParseGetChangeStatusParametersResponse(ADocument: String; out ABugUpdateToken: String; out ALastUpdated: String): Boolean;
1956+function AddAttachment(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AAttachments: TArray<String>; out AError: String): Boolean;
1957+begin
1958+ Result := AddComment(AHandle,AFormToBlock,ATask,'','',False,AAttachments,AError);
1959+end;
1960+
1961+function ParseGetChangeStatusParametersResponse(ADocument: String; out ABugUpdateToken: String; out ALastUpdated: String; out AHandlers: TArray<THandler>): Boolean;
19571962 var
19581963 HTMLDocument: IHTMLDocument;
19591964 HTMLElementCollection: IHTMLElementCollection;
1960- HTMLInputElement: IHTMLInputElement;
19611965 begin
19621966 ABugUpdateToken := '';
19631967 ALastUpdated := '';
@@ -1973,6 +1977,9 @@
19731977 HTMLElementCollection := (HTMLDocument as IHTMLDocument3).GetElementsByTagName('input') as IHTMLElementCollection;
19741978
19751979 if HTMLElementCollection.length > 0 then
1980+ begin
1981+ var HTMLInputElement: IHTMLInputElement;
1982+
19761983 for var i: Word := 0 to Pred(HTMLElementCollection.length) do
19771984 begin
19781985 HTMLInputElement := (HTMLElementCollection as IHTMLElementCollection4).item(i) as IHTMLInputElement;
@@ -1983,11 +1990,44 @@
19831990 else if HTMLInputElement.Name = 'last_updated' then
19841991 ALastUpdated := HTMLInputElement.Value;
19851992 end;
1993+ end;
19861994
1995+ HTMLElementCollection := (HTMLDocument as IHTMLDocument3).GetElementsByTagName('select');
1996+
1997+ if HTMLElementCollection.Length > 0 then
1998+ begin
1999+ var HTMLSelectElement: IHTMLSelectElement;
2000+ var Handler: THandler;
2001+
2002+ for var i: Word := 0 to Pred(HTMLElementCollection.Length) do
2003+ begin
2004+ HTMLSelectElement := (HTMLElementCollection as IHTMLElementCollection4).item(i) as IHTMLSelectElement;
2005+
2006+ if HTMLSelectElement.Name = 'handler_id' then
2007+ begin
2008+ var HTMLOptionElement: IHTMLOptionElement;
2009+
2010+ if HTMLSelectElement.Length > 0 then
2011+ // Varre todos os <option>, adicionando suas informações no array
2012+ for var j: Byte := 0 to Pred(HTMLSelectElement.Length) do
2013+ begin
2014+ HTMLOptionElement := HTMLSelectElement.item(j,j) as IHTMLOptionElement;
2015+
2016+ Handler.Id := StrToInt(HTMLOptionElement.Value);
2017+ Handler.RealName := HTMLOptionElement.Text;
2018+ // Nova forma de incrementar um array dinâmico (a partir do XE7)
2019+ AHandlers := AHandlers + [Handler];
2020+ end;
2021+
2022+ Break;
2023+ end;
2024+ end;
2025+ end;
2026+
19872027 Result := (ABugUpdateToken <> '') and (ALastUpdated <> '');
19882028 end;
19892029
1990-function GetChangeStatusParameters(AHandle: Cardinal; ATaskId: Cardinal; ANewStatusId: Word; out ABugUpdateToken: String; out ALastUpdated: String): Boolean;
2030+function GetChangeStatusParameters(AHandle: Cardinal; ATaskId: Cardinal; ANewStatusId: Word; out ABugUpdateToken: String; out ALastUpdated: String; out AHandlers: TArray<THandler>): Boolean;
19912031 var
19922032 Req: TRequestOptions;
19932033 Res: TResponse;
@@ -2017,10 +2057,10 @@
20172057 Req.HttpOpenRequestParams.Headers.Add('Content-Type: application/x-www-form-urlencoded');
20182058 Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
20192059
2020- Res.Content := TStringStream.Create('');
2060+ Res.Content := TStringStream.Create('',TEncoding.UTF8);
20212061 try
20222062 Request(Req,Res);
2023- Result := ParseGetChangeStatusParametersResponse(TStringStream(Res.Content).DataString,ABugUpdateToken,ALastUpdated);
2063+ Result := ParseGetChangeStatusParametersResponse(TStringStream(Res.Content).DataString,ABugUpdateToken,ALastUpdated,AHandlers);
20242064 finally
20252065 Res.Content.Free;
20262066 end;
@@ -2074,87 +2114,76 @@
20742114 end;
20752115 end;
20762116
2077-function ChangeStatus(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; ANewStatus: String; AComment: String = ''; ACommentIsPrivate: Boolean = False; ACounter: Word = 0): Boolean;
2117+function ChangeStatus(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; ANewStatus: String; ANewStatusId: Word; ABugUpdateToken: String; ALastUpdated: String; AComment: String; ACommentIsPrivate: Boolean; ACounter: Word; AHandlerId: Cardinal = 0): Boolean;
20782118 const
2079- BOUNDARY: RawByteString = 'MantisBTMonitor-1F00CBD1-5117-49A0-84F0-A3A4102DE66E';
2080-var
2081- BugUpdateToken: String;
2082- LastUpdated: String;
2083- NewStatusId: Word;
2119+ BOUNDARY: RawByteString = 'MBTM-1F00CBD1-5117-49A0-84F0-A3A4102DE66E';
20842120 begin
20852121 var FB: TKRKFormBlender := ShowStatusFormBlender(AFormToBlock);
20862122 try
20872123 UpdateStatusFormBlender(FB,'Por favor aguarde enquanto a situação da tarefa é alterada...');
20882124
2089- NewStatusId := Configurations.MantisConfigs.StatusByName[ANewStatus].Id;
2125+ // Não existe motivo especial para eu usar Default ao invéz de ZeroMemory,
2126+ // apenas eu achei que aqui ficava mais elegante usar Default e economizar 2
2127+ // linhas de código
2128+ var Req: TRequestOptions := Default(TRequestOptions);
2129+ var Res: TResponse := Default(TResponse);
20902130
2091- Result := GetChangeStatusParameters(AHandle,ATask.Id,NewStatusId,BugUpdateToken,LastUpdated);
2131+ Req.AutoClearSSLState := True;
20922132
2093- if Result then
2094- begin
2095- // Não existe motivo especial para eu usar Default ao invéz de ZeroMemory,
2096- // apenas eu achei que aqui ficava mais elegante usar Default e economizar 2
2097- // linhas de código
2098- var Req: TRequestOptions := Default(TRequestOptions);
2099- var Res: TResponse := Default(TResponse);
2133+ Req.Content := TMemoryStream.Create;
2134+ try
2135+ // Adiciona o cabeçalho padrão de acordo com as configurações atuais de
2136+ // unidade, caso já não exista um cabeçalho. Um cabeçalho só vai existir
2137+ // neste ponto caso ele tenha sido incluído de forma manual em AComment.
2138+ // Isso deve acontecer apenas em mudanças de status de aprovação ou
2139+ // reprovação
2140+ AddCommentHeader(AComment,'<stat>' + ANewStatus + ' (' + ACounter.ToString + ')</stat>');
21002141
2101- Req.AutoClearSSLState := True;
2142+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_update_token',RawByteString(ABugUpdateToken),BOUNDARY);
2143+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_id',RawByteString(ATask.Id.ToString),BOUNDARY);
2144+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','status',RawByteString(ANewStatusId.ToString),BOUNDARY);
2145+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','last_updated',RawByteString(ALastUpdated),BOUNDARY);
2146+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','handler_id',RawByteString(AHandlerId.ToString),BOUNDARY);
21022147
2103- Req.Content := TMemoryStream.Create;
2104- try
2105- // Adiciona o cabeçalho padrão de acordo com as configurações atuais de
2106- // unidade, caso já não exista um cabeçalho. Um cabeçalho só vai existir
2107- // neste ponto caso ele tenha sido incluído de forma manual em AComment.
2108- // Isso deve acontecer apenas em mudanças de status de aprovação ou
2109- // reprovação
2110- AddCommentHeader(AComment,'<stat>' + ANewStatus + ' (' + ACounter.ToString + ')</stat>');
2148+ if ACommentIsPrivate then
2149+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','private','on',BOUNDARY);
21112150
2112- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_update_token',RawByteString(BugUpdateToken),BOUNDARY);
2113- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_id',RawByteString(ATask.Id.ToString),BOUNDARY);
2114- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','status',RawByteString(NewStatusId.ToString),BOUNDARY);
2115- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','last_updated',RawByteString(LastUpdated),BOUNDARY);
2116- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','handler_id',RawByteString(Configurations.UserInfo.Id.ToString),BOUNDARY);
2151+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bugnote_text',UTF8Encode(AComment),BOUNDARY);
2152+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','action_type','change_status',BOUNDARY);
21172153
2118- if ACommentIsPrivate then
2119- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','private','on',BOUNDARY);
2154+ Req.InternetOpenParams.Agent := 'MantisBT Monitor';
2155+ Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
2156+ Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/bug_update.php');
2157+ Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
2158+ Req.InternetConnectParams.Context := AHandle;
2159+ Req.HttpOpenRequestParams.Verb := 'POST';
2160+ Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
21202161
2121- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bugnote_text',UTF8Encode(AComment),BOUNDARY);
2122- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','action_type','change_status',BOUNDARY);
2162+ try
2163+ Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
2164+ Req.HttpOpenRequestParams.Context := AHandle;
2165+ Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
2166+ Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
2167+ Req.HttpOpenRequestParams.Headers := TStringList.Create;
2168+ try
2169+ Req.HttpOpenRequestParams.Headers.Add('Content-Type: multipart/form-data; boundary=' + String(BOUNDARY));
2170+ Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
21232171
2124- Req.InternetOpenParams.Agent := 'MantisBT Monitor';
2125- Req.InternetOpenParams.AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
2126- Req.InternetConnectParams.ServerName := PChar(Configurations.MantisBTBaseUrl + '/mantis/bug_update.php');
2127- Req.InternetConnectParams.Service := INTERNET_SERVICE_HTTP;
2128- Req.InternetConnectParams.Context := AHandle;
2129- Req.HttpOpenRequestParams.Verb := 'POST';
2130- Req.HttpOpenRequestParams.AcceptTypes := TStringList.Create;
2131-
2132- try
2133- Req.HttpOpenRequestParams.AcceptTypes.Add('*/*');
2134- Req.HttpOpenRequestParams.Context := AHandle;
2135- Req.HttpOpenRequestParams.AutoDetectHTTPS := True;
2136- Req.HttpOpenRequestParams.IgnoreInvalidCertificates := True;
2137- Req.HttpOpenRequestParams.Headers := TStringList.Create;
2172+ Res.Content := TStringStream.Create('');
21382173 try
2139- Req.HttpOpenRequestParams.Headers.Add('Content-Type: multipart/form-data; boundary=' + String(BOUNDARY));
2140- Req.HttpSendRequestParams.IgnoreInvalidCertificateCA := True;
2141-
2142- Res.Content := TStringStream.Create('');
2143- try
2144- Request(Req,Res);
2145- Result := ParseChangeStatusResponse(TStringStream(Res.Content).DataString,NewStatusId);
2146- finally
2147- Res.Content.Free;
2148- end;
2174+ Request(Req,Res);
2175+ Result := ParseChangeStatusResponse(TStringStream(Res.Content).DataString,ANewStatusId);
21492176 finally
2150- Req.HttpOpenRequestParams.Headers.Free;
2177+ Res.Content.Free;
21512178 end;
21522179 finally
2153- Req.HttpOpenRequestParams.AcceptTypes.Free;
2180+ Req.HttpOpenRequestParams.Headers.Free;
21542181 end;
21552182 finally
2156- Req.Content.Free;
2183+ Req.HttpOpenRequestParams.AcceptTypes.Free;
21572184 end;
2185+ finally
2186+ Req.Content.Free;
21582187 end;
21592188 finally
21602189 HideStatusFormBlender(FB);
@@ -2203,7 +2232,7 @@
22032232
22042233 function ForwardToTestOrHomologation(AHandle: Cardinal; AFormToBlock: TForm; ATask: TTask; AHomologation: Boolean; AComment: String; ACommentIsPrivate: Boolean; AAttachments: TArray<String>; out ACommentError: String): Boolean;
22052234 const
2206- BOUNDARY: RawByteString = 'MantisBTMonitor-B2AEBE26-2316-4BA5-BEA2-BB98E782EC77';
2235+ BOUNDARY: RawByteString = 'MBTM-B2AEBE26-2316-4BA5-BEA2-BB98E782EC77';
22072236 begin
22082237 var Req: TRequestOptions := Default(TRequestOptions);
22092238 var Res: TResponse := Default(TResponse);
@@ -2221,7 +2250,7 @@
22212250 AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_update_token',RawByteString(ATask.AssignToToken),BOUNDARY);
22222251 AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','last_updated',RawByteString(ATask.AssignToLastUpdated),BOUNDARY);
22232252 AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','action_type','assign',BOUNDARY);
2224- AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','handler_id','165',BOUNDARY); // Gerência de Configuração
2253+ AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','handler_id','165',BOUNDARY); // Gerência de Configuração { TODO : Criar um parâmetro de configuração para isso }
22252254 AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_id',RawByteString(ATask.Id.ToString),BOUNDARY);
22262255
22272256 Req.InternetOpenParams.Agent := 'MantisBT Monitor';
@@ -2258,6 +2287,8 @@
22582287 AddComment(AHandle,nil,ATask,AComment,'<fwho></fwho>',ACommentIsPrivate,AAttachments,ACommentError)
22592288 else
22602289 AddComment(AHandle,nil,ATask,AComment,'<fwte></fwte>',ACommentIsPrivate,AAttachments,ACommentError);
2290+
2291+ { TODO : Aqui pode ser colocada a chamada ao script que adiciona uma entrada ao histórico do mantis usando o plugin do MantisBT Monitor }
22612292 end;
22622293 finally
22632294 Res.Content.Free;
--- trunk/client/src/lib/UTypes.pas (revision 87)
+++ trunk/client/src/lib/UTypes.pas (revision 88)
@@ -270,6 +270,11 @@
270270
271271 TTasks = array of TTask;
272272
273+ THandler = record
274+ id: Cardinal;
275+ RealName: string;
276+ end;
277+
273278 const
274279 { Nomes dos estados de uma tarefa em português (case sensitive) }
275280 STATUS_NEW = 'novo';
--- trunk/client/src/UDamoTask.pas (revision 87)
+++ trunk/client/src/UDamoTask.pas (revision 88)
@@ -224,15 +224,13 @@
224224 procedure TDamoTask.EditComment(ACommentId: Cardinal);
225225 var
226226 Comment: String;
227- Dummy1: Boolean;
228- CommentToken: String;
229- Dummy2: TArray<String>;
227+ UpdateToken: String;
230228 begin
231- if TFormManageNote.ShowMeModal(Self,ACommentId,Comment,Dummy1,Dummy2,CommentToken) = mrOk then
229+ if TFormManageNote.ShowMeForCommentChange(Self,ACommentId,Comment,UpdateToken) = mrOk then
232230 begin
233231 CommentBackupCreate(ACommentId,Comment);
234232
235- if UpdateComment(Application.Handle,TForm(Owner),ACommentId,Comment,CommentToken) then
233+ if UpdateComment(Application.Handle,TForm(Owner),ACommentId,Comment,UpdateToken) then
236234 begin
237235 CommentBackupDelete(ACommentId);
238236 Application.MessageBox('Seu comentário foi salvo com sucesso','Comentário salvo com sucesso',MB_ICONINFORMATION);
@@ -245,30 +243,43 @@
245243
246244 procedure TDamoTask.Execute;
247245 var
246+ NewStatusId: Word;
247+ BugUpdateToken: String;
248+ LastUpdated: String;
248249 Comment: String;
249250 CommentIsPrivate: Boolean;
250- Dummy: TArray<String>;
251+ Handlers: TArray<THandler>;
251252 begin
252- if TFormManageNote.ShowMeModal(Self,TSpecialMode.Execute,FTask.Id,Comment,CommentIsPrivate,Dummy) = mrOk then
253- begin
254- CommentBackupCreate(0,Comment);
253+ NewStatusId := Configurations.MantisConfigs.StatusByName[STATUS_IN_PROGRESS].Id;
255254
256- if ChangeStatus(Application.Handle
257- ,TForm(Owner)
258- ,FTask
259- ,STATUS_IN_PROGRESS
260- ,Comment
261- ,CommentIsPrivate
262- ,Succ(FTask.ExecutionsCount)) then
255+ if not GetChangeStatusParameters(Application.Handle,FTask.Id,NewStatusId,BugUpdateToken,LastUpdated,Handlers) then
256+ Application.MessageBox('Não foi possível obter os parâmetros de mudança de estado. Tente novamente','Erro ao iniciar a tarefa',MB_ICONERROR)
257+ else
258+ if TFormManageNote.ShowMeForTaskExecution(Self,Comment,CommentIsPrivate) = mrOk then
263259 begin
264- CommentBackupDelete(0);
265- Application.MessageBox('Tarefa iniciada com sucesso!','Execução bem sucedida',MB_ICONINFORMATION);
266- end
267- else
268- Application.MessageBox('Não foi possível iniciar a tarefa. Tente novamente','Erro ao iniciar a tarefa',MB_ICONERROR);
260+ CommentBackupCreate(0,Comment);
261+ // ao executar, o usuário é sempre quem executou! portanto aqui se usa
262+ // Configurations.UserInfo.Id.ToString
263+ if ChangeStatus(Application.Handle
264+ ,TForm(Owner)
265+ ,FTask
266+ ,STATUS_IN_PROGRESS
267+ ,NewStatusId
268+ ,BugUpdateToken
269+ ,LastUpdated
270+ ,Comment
271+ ,CommentIsPrivate
272+ ,Succ(FTask.ExecutionsCount)
273+ ,Configurations.UserInfo.Id) then
274+ begin
275+ CommentBackupDelete(0);
276+ Application.MessageBox('Tarefa iniciada com sucesso!','Execução bem sucedida',MB_ICONINFORMATION);
277+ end
278+ else
279+ Application.MessageBox('Não foi possível iniciar a tarefa. Tente novamente','Erro ao iniciar a tarefa',MB_ICONERROR);
269280
270- Refresh;
271- end;
281+ Refresh;
282+ end;
272283 { TODO : Ao colocar uma tarefa em execução é necessário alterar o campo "Unidade
273284 Responsável Pelo Atendimento" de forma que ela seja a unidade da pessoa que
274285 iniciou a ação. Taciano solicitou isso a Kirlian e eu particularmente não
@@ -330,8 +341,6 @@
330341 HKCU\Software\TJPE\MantisBT Monitor e rode o programa monitorando
331342 TFormTask.ConfigureStatusChangeActions }
332343
333-{ TODO 5 : Ao rejeitar uma tarefa, a atribuição dela também muda. Acredito que
334-isso não deva acontecer }
335344
336345
337346
@@ -358,68 +367,94 @@
358367
359368 procedure TDamoTask.Impede;
360369 var
370+ NewStatusId: Word;
371+ BugUpdateToken: String;
372+ LastUpdated: String;
373+ Handlers: TArray<THandler>;
361374 Comment: String;
362375 CommentIsPrivate: Boolean;
363- Dummy: TArray<String>;
376+ HandlerId: Cardinal;
364377 begin
365- if TFormManageNote.ShowMeModal(Self,TSpecialMode.Impede,FTask.Id,Comment,CommentIsPrivate,Dummy) = mrOk then
366- begin
367- CommentBackupCreate(0,Comment);
378+ NewStatusId := Configurations.MantisConfigs.StatusByName[STATUS_IMPEDIMENT].Id;
368379
369- if ChangeStatus(Application.Handle
370- ,TForm(Owner)
371- ,FTask
372- ,STATUS_IMPEDIMENT
373- ,Comment
374- ,CommentIsPrivate
375- ,Succ(FTask.ImpedimentsCount)) then
380+ if not GetChangeStatusParameters(Application.Handle,FTask.Id,NewStatusId,BugUpdateToken,LastUpdated,Handlers) then
381+ Application.MessageBox('Não foi possível obter os parâmetros de mudança de estado. Tente novamente','Erro ao impedir a tarefa',MB_ICONERROR)
382+ else
383+ if TFormManageNote.ShowMeForStatusChange(Self,TSpecialMode.Impede,Handlers,Comment,CommentIsPrivate,HandlerId) = mrOk then
376384 begin
377- CommentBackupDelete(0);
378- Application.MessageBox('Tarefa impedida com sucesso!','Impedimento bem sucedido',MB_ICONINFORMATION);
379- end
380- else
381- Application.MessageBox('Não foi possível impedir a tarefa. Tente novamente','Erro ao impedir a tarefa',MB_ICONERROR);
382- // Acredito que um dos motivos pelos quais o impedimento possa falhar, seja
383- // porque alguém possa ter mudado o status da tarefa antes de nós, fazendo
384- // com que ela fique em um status que não permite um impedimento (por
385- // exemplo, se alguém impediu a tarefa antes de nós). Neste caso, achei mais
386- // coerente, sempre atualizar as informações, independentemente de ter
387- // havido erro ou não
388- Refresh;
389- end;
385+ CommentBackupCreate(0,Comment);
386+
387+ if ChangeStatus(Application.Handle
388+ ,TForm(Owner)
389+ ,FTask
390+ ,STATUS_IMPEDIMENT
391+ ,NewStatusId
392+ ,BugUpdateToken
393+ ,LastUpdated
394+ ,Comment
395+ ,CommentIsPrivate
396+ ,Succ(FTask.ImpedimentsCount)
397+ ,HandlerId) then
398+ begin
399+ CommentBackupDelete(0);
400+ Application.MessageBox('Tarefa impedida com sucesso!','Impedimento bem sucedido',MB_ICONINFORMATION);
401+ end
402+ else
403+ Application.MessageBox('Não foi possível impedir a tarefa. Tente novamente','Erro ao impedir a tarefa',MB_ICONERROR);
404+ // Acredito que um dos motivos pelos quais o impedimento possa falhar, seja
405+ // porque alguém possa ter mudado o status da tarefa antes de nós, fazendo
406+ // com que ela fique em um status que não permite um impedimento (por
407+ // exemplo, se alguém impediu a tarefa antes de nós). Neste caso, achei mais
408+ // coerente, sempre atualizar as informações, independentemente de ter
409+ // havido erro ou não
410+ Refresh;
411+ end;
390412 end;
391413
392414 procedure TDamoTask.Reject;
393415 var
416+ NewStatusId: Word;
417+ BugUpdateToken: String;
418+ LastUpdated: String;
419+ Handlers: TArray<THandler>;
394420 Comment: String;
395421 CommentIsPrivate: Boolean;
396- Dummy: TArray<String>;
422+ HandlerId: Cardinal;
397423 begin
398- if TFormManageNote.ShowMeModal(Self,TSpecialMode.Reject,FTask.Id,Comment,CommentIsPrivate,Dummy) = mrOk then
399- begin
400- CommentBackupCreate(0,Comment);
424+ NewStatusId := Configurations.MantisConfigs.StatusByName[STATUS_REJECTED].Id;
401425
402- if ChangeStatus(Application.Handle
403- ,TForm(Owner)
404- ,FTask
405- ,STATUS_REJECTED
406- ,Comment
407- ,CommentIsPrivate
408- ,Succ(FTask.RejectionsCount)) then
426+ if not GetChangeStatusParameters(Application.Handle,FTask.Id,NewStatusId,BugUpdateToken,LastUpdated,Handlers) then
427+ Application.MessageBox('Não foi possível obter os parâmetros de mudança de estado. Tente novamente','Erro ao rejeitar a tarefa',MB_ICONERROR)
428+ else
429+ if TFormManageNote.ShowMeForStatusChange(Self,TSpecialMode.Reject,Handlers,Comment,CommentIsPrivate,HandlerId) = mrOk then
409430 begin
410- CommentBackupDelete(0);
411- Application.MessageBox('Tarefa rejeitada com sucesso!','Rejeição bem sucedida',MB_ICONINFORMATION);
412- end
413- else
414- Application.MessageBox('Não foi possível rejeitar a tarefa. Tente novamente','Erro ao rejeitar a tarefa',MB_ICONERROR);
415- // Acredito que um dos motivos pelos quais a rejeição possa falhar, seja
416- // porque alguém possa ter mudado o status da tarefa antes de nós, fazendo
417- // com que ela fique em um status que não permite uma rejeição (por exemplo,
418- // se alguém rejeitou a tarefa antes de nós). Neste caso, achei mais
419- // coerente, sempre atualizar as informações, independentemente de ter
420- // havido erro ou não
421- Refresh;
422- end;
431+ CommentBackupCreate(0,Comment);
432+
433+ if ChangeStatus(Application.Handle
434+ ,TForm(Owner)
435+ ,FTask
436+ ,STATUS_REJECTED
437+ ,NewStatusId
438+ ,BugUpdateToken
439+ ,LastUpdated
440+ ,Comment
441+ ,CommentIsPrivate
442+ ,Succ(FTask.RejectionsCount)
443+ ,HandlerId) then
444+ begin
445+ CommentBackupDelete(0);
446+ Application.MessageBox('Tarefa rejeitada com sucesso!','Rejeição bem sucedida',MB_ICONINFORMATION);
447+ end
448+ else
449+ Application.MessageBox('Não foi possível rejeitar a tarefa. Tente novamente','Erro ao rejeitar a tarefa',MB_ICONERROR);
450+ // Acredito que um dos motivos pelos quais a rejeição possa falhar, seja
451+ // porque alguém possa ter mudado o status da tarefa antes de nós, fazendo
452+ // com que ela fique em um status que não permite uma rejeição (por exemplo,
453+ // se alguém rejeitou a tarefa antes de nós). Neste caso, achei mais
454+ // coerente, sempre atualizar as informações, independentemente de ter
455+ // havido erro ou não
456+ Refresh;
457+ end;
423458 end;
424459
425460 procedure TDamoTask.SendToHomologation;
@@ -430,7 +465,6 @@
430465 procedure TDamoTask.SendToTest;
431466 var
432467 Comment: String;
433- CommentIsPrivate: Boolean;
434468 Attachments: TArray<String>;
435469 begin
436470 //rejeição, impedimento e execução estão funcionando e contando a quantidade de vezes que eles aparecem
@@ -440,7 +474,7 @@
440474 //testes, pois tem um tag especial ([ufs-ii][T] e [UFS-II][H]). Voce vai ter que
441475 //criar um tag especial pra isso, tal como existem os tags especiais pra rejeição
442476 //e aprovação
443- if TFormManageNote.ShowMeModal(Self,TSpecialMode.SendToTest,FTask.Id,Comment,CommentIsPrivate,Attachments) = mrOk then
477+ if TFormManageNote.ShowMeForForwarding(Self,TSpecialMode.SendToTest,Comment,Attachments) = mrOk then
444478 begin
445479 CommentBackupCreate(0,Comment);
446480
@@ -451,7 +485,7 @@
451485 ,FTask
452486 ,False
453487 ,Comment
454- ,CommentIsPrivate
488+ ,False // Acredito que todo encaminhamento precise ser público
455489 ,Attachments
456490 ,CommentError) then
457491 begin
@@ -479,17 +513,16 @@
479513 procedure TDamoTask.NewComment;
480514 var
481515 Comment: String;
482- CommentIsPrivate: Boolean;
483- Files: TArray<String>;
484- Dummy: String;
516+ &Private: Boolean; // usando & permite usar nomes de palavras chave como variáveis
517+ Attachments: TArray<String>;
485518 begin
486- if TFormManageNote.ShowMeModal(Self,0,Comment,CommentIsPrivate,Files,Dummy) = mrOk then
519+ if TFormManageNote.ShowMeForCommentAdd(Self,Comment,&Private,Attachments) = mrOk then
487520 begin
488521 var Error: String;
489522
490523 CommentBackupCreate(0,Comment);
491524
492- if AddComment(Application.Handle,TForm(Owner),FTask,Comment,'',CommentIsPrivate,Files,Error) then
525+ if AddComment(Application.Handle,TForm(Owner),FTask,Comment,'',&Private,Attachments,Error) then
493526 begin
494527 CommentBackupDelete(0);
495528 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);
@@ -507,16 +540,13 @@
507540
508541 procedure TDamoTask.UploadAttachments;
509542 var
510- Dummy1: String;
511- Files: TArray<String>;
512- Dummy2: Boolean;
513- Dummy3: String;
543+ Attachments: TArray<String>;
514544 begin
515- if TFormManageNote.ShowMeModal(Self,0,Dummy1,Dummy2,Files,Dummy3,True) = mrOk then
545+ if TFormManageNote.ShowMeForFileUpload(Self,Attachments) = mrOk then
516546 begin
517547 var Error: String;
518548
519- if AddComment(Application.Handle,TForm(Owner),FTask,Dummy1,'',Dummy2,Files,Error) then
549+ if AddAttachment(Application.Handle,TForm(Owner),FTask,Attachments,Error) then
520550 begin
521551 Application.MessageBox('Arquivos anexados com sucesso!','Arquivos anexados com sucesso!',MB_ICONINFORMATION);
522552 Refresh;
--- trunk/client/src/UFormManageNote.pas (revision 87)
+++ trunk/client/src/UFormManageNote.pas (revision 88)
@@ -11,6 +11,7 @@
1111
1212 type
1313 TSpecialMode = (None,Reject,Impede,Execute,SendToTest,SendToHomologation);
14+ TForwardingModes = TSpecialMode.SendToTest..SendToHomologation;
1415
1516 TFormManageNote = class(TFormBasicDialog)
1617 PACO: TPageControl;
@@ -23,6 +24,8 @@
2324 MNUICopyReferenceToFile: TMenuItem;
2425 PANEAttachments: TPanel;
2526 CHBXPrivate: TCheckBox;
27+ CBBXHandler: TComboBox;
28+ LABEHandler: TLabel;
2629 procedure EDBRExecuteScript(Sender: TCustomEdgeBrowser; AResult: HRESULT; const AResultObjectAsJson: string);
2730 procedure EDBRCreateWebViewCompleted(Sender: TCustomEdgeBrowser; AResult: HRESULT);
2831 procedure FormCreate(Sender: TObject);
@@ -37,7 +40,6 @@
3740 private
3841 { Private declarations }
3942 FDamoTask: TDamoTask;
40- FTask: TTask;
4143 FComment: String;
4244 FAttachments: TArray<String>;
4345 FCommentId: Cardinal;
@@ -45,11 +47,13 @@
4547 FAttachmentsOnly: Boolean;
4648 FPostContent: TStringStream;
4749 FSpecialMode: TSpecialMode;
50+ FHandlers: TArray<THandler>;
4851 FFB: TKRKFormBlender;
4952
5053 procedure DoDropFiles(ASender: TObject; const ADropHandle: LRESULT; out AMessageResult: LRESULT);
5154 procedure ConfigureCommentsPage;
5255 procedure ConfigureAttachmentsPage;
56+ procedure ConfigureOtherElements;
5357 procedure AddAttachment(AFileName: String; AFileSize: Cardinal);
5458 function AttachmentsTabIsVisible: Boolean;
5559 procedure LoadTinyMCE;
@@ -59,7 +63,14 @@
5963 public
6064 { Public declarations }
6165 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;
62- class function ShowMeModal(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>): TModalResult; reintroduce; overload;
66+ class function ShowMeModal(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; AHandlers: TArray<THandler>; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>; out AHandlerId: Cardinal): TModalResult; reintroduce; overload;
67+ //: Especializações das funções ShowModal
68+ class function ShowMeForStatusChange(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; AHandlers: TArray<THandler>; out AComment: String; out APrivate: Boolean; out AHandlerId: Cardinal): TModalResult;
69+ class function ShowMeForCommentChange(ADamoTask: TDamoTask; ACommentId: Cardinal; out AComment: String; out AUpdateToken: String): TModalResult;
70+ class function ShowMeForTaskExecution(ADamoTask: TDamoTask; out AComment: String; out APrivate: Boolean): TModalResult;
71+ class function ShowMeForCommentAdd(ADamoTask: TDamoTask; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>): TModalResult;
72+ class function ShowMeForFileUpload(ADamoTask: TDamoTask; out AAttachments: TArray<String>): TModalResult;
73+ class function ShowMeForForwarding(ADamoTask: TDamoTask; AForwardTo: TForwardingModes; out AComment: String; out AAttachments: TArray<String>): TModalResult;
6374 end;
6475
6576 implementation
@@ -125,7 +136,7 @@
125136
126137 function TFormManageNote.AttachmentsTabIsVisible: Boolean;
127138 begin
128- Result := (((not FUpdating) and (FSpecialMode in [TSpecialMode.None,TSpecialMode.SendToTest,TSpecialMode.SendToHomologation])) or (FTask.CommentById[FCommentId].AttachmentsCount > 0)) and (not CHBXPrivate.Checked);
139+ Result := (((not FUpdating) and (FSpecialMode in [TSpecialMode.None,TSpecialMode.SendToTest,TSpecialMode.SendToHomologation])) or (FDamoTask.Task.CommentById[FCommentId].AttachmentsCount > 0)) and (not CHBXPrivate.Checked);
129140 end;
130141
131142 procedure TFormManageNote.CHBXPrivateClick(Sender: TObject);
@@ -155,7 +166,7 @@
155166
156167 LIVIAttachments.Items.BeginUpdate;
157168 try
158- for var Attachment in FTask.CommentById[FCommentId].Attachments do
169+ for var Attachment in FDamoTask.Task.CommentById[FCommentId].Attachments do
159170 AddAttachment(Attachment.FileName,Attachment.FileSize);
160171 finally
161172 LIVIAttachments.Items.EndUpdate;
@@ -169,8 +180,36 @@
169180 TASHComment.TabVisible := False
170181 else
171182 PACO.ActivePage := TASHComment;
183+end;
172184
173- CHBXPrivate.Visible := (not FUpdating) and (not FAttachmentsOnly);
185+procedure TFormManageNote.ConfigureOtherElements;
186+begin
187+ CHBXPrivate.Visible := (not FUpdating) and (not FAttachmentsOnly) and (not (FSpecialMode in [Low(TForwardingModes)..High(TForwardingModes)]));
188+ LABEHandler.Visible := FSpecialMode in [TSpecialMode.Reject,TSpecialMode.Impede];
189+ CBBXHandler.Visible := LABEHandler.Visible;
190+
191+ if CBBXHandler.Visible then
192+ begin
193+ CBBXHandler.Clear;
194+
195+ CBBXHandler.AddItem('< Ninguém >',TObject(0));
196+
197+ for var Handler: THandler in FHandlers do
198+ begin
199+ if Handler.id > 0 then
200+ begin
201+ if Handler.RealName = FDamoTask.Task.Reporter then
202+ CBBXHandler.Items.InsertObject(1,'< Relator (' + Handler.RealName + ') >',TObject(Handler.id));
203+
204+ CBBXHandler.AddItem(Handler.RealName,TObject(Handler.id));
205+ end;
206+ end;
207+
208+ if FDamoTask.Task.Responsible = '' then
209+ CBBXHandler.ItemIndex := 0 // Ninguém
210+ else
211+ CBBXHandler.ItemIndex := CBBXHandler.Items.IndexOf(FDamoTask.Task.Responsible);
212+ end;
174213 end;
175214
176215 procedure TFormManageNote.DoDropFiles(ASender: TObject; const ADropHandle: LRESULT; out AMessageResult: LRESULT);
@@ -282,6 +321,7 @@
282321
283322 ConfigureAttachmentsPage;
284323 ConfigureCommentsPage;
324+ ConfigureOtherElements;
285325 end;
286326
287327 procedure TFormManageNote.HandleTimerMessage(var AMsg: TWMTimer);
@@ -327,7 +367,7 @@
327367 EDBR.Navigate(Configurations.MantisBTBaseUrl + '/mantis/plugin.php?page=MantisBTMonitor/mbtmTinyMCEEditor');
328368 end;
329369
330-class function TFormManageNote.ShowMeModal(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>): TModalResult;
370+class function TFormManageNote.ShowMeModal(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; AHandlers: TArray<THandler>; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>; out AHandlerId: Cardinal): TModalResult;
331371 begin
332372 with Self.Create(ADamoTask.Owner) do
333373 begin
@@ -337,6 +377,7 @@
337377
338378 FComment := '';
339379 FSpecialMode := ASpecialMode;
380+ FHandlers := AHandlers;
340381 FUpdating := False;
341382
342383 AutoCaption := False;
@@ -344,11 +385,11 @@
344385 Caption := 'Gerenciador de anotações - ' + Application.Title;
345386
346387 case ASpecialMode of
347- TSpecialMode.Reject: LABECaption.Caption := 'Rejeitando a tarefa #' + ATaskId.ToString;
348- TSpecialMode.Impede: LABECaption.Caption := 'Impedindo a tarefa #' + ATaskId.ToString;
349- TSpecialMode.Execute: LABECaption.Caption := 'Executando a tarefa #' + ATaskId.ToString;
350- TSpecialMode.SendToTest: LABECaption.Caption := 'Enviando a tarefa #' + ATaskId.ToString + ' para Testes';
351- TSpecialMode.SendToHomologation: LABECaption.Caption := 'Enviando a tarefa #' + ATaskId.ToString + ' para Homologação';
388+ TSpecialMode.Reject: LABECaption.Caption := 'Rejeitando a tarefa #' + FDamoTask.Task.Id.ToString;
389+ TSpecialMode.Impede: LABECaption.Caption := 'Impedindo a tarefa #' + FDamoTask.Task.Id.ToString;
390+ TSpecialMode.Execute: LABECaption.Caption := 'Executando a tarefa #' + FDamoTask.Task.Id.ToString;
391+ TSpecialMode.SendToTest: LABECaption.Caption := 'Enviando a tarefa #' + FDamoTask.Task.Id.ToString + ' para Testes';
392+ TSpecialMode.SendToHomologation: LABECaption.Caption := 'Enviando a tarefa #' + FDamoTask.Task.Id.ToString + ' para Homologação';
352393 end;
353394
354395 // Caso exista um backup, pergunta se quer carregar.
@@ -359,6 +400,7 @@
359400 AComment := FComment;
360401 Aprivate := CHBXPrivate.Checked;
361402 AAttachments := FAttachments;
403+ AHandlerId := CBBXHandler.SelectionAsCardinal;
362404 end;
363405 end;
364406
@@ -369,7 +411,6 @@
369411 with Self.Create(ADamoTask.Owner) do
370412 begin
371413 FDamoTask := ADamoTask;
372- FTask := ADamoTask.Task;
373414 FCommentId := ACommentId;
374415 AComment := '';
375416 APrivate := False;
@@ -447,6 +488,54 @@
447488 end;
448489 end;
449490
491+class function TFormManageNote.ShowMeForCommentAdd(ADamoTask: TDamoTask; out AComment: String; out APrivate: Boolean; out AAttachments: TArray<String>): TModalResult;
492+var
493+ DummyUpdateToken: String;
494+begin
495+ Result := ShowMeModal(ADamoTask,0,AComment,APrivate,AAttachments,DummyUpdateToken);
496+end;
497+
498+class function TFormManageNote.ShowMeForCommentChange(ADamoTask: TDamoTask; ACommentId: Cardinal; out AComment: String; out AUpdateToken: String): TModalResult;
499+var
500+ DummyPrivate: Boolean;
501+ DummyAttachments: TArray<String>;
502+begin
503+ Result := ShowMeModal(ADamoTask,ACommentId,AComment,DummyPrivate,DummyAttachments,AUpdateToken);
504+end;
505+
506+class function TFormManageNote.ShowMeForFileUpload(ADamoTask: TDamoTask; out AAttachments: TArray<String>): TModalResult;
507+var
508+ DummyComment: String;
509+ DummyPrivate: Boolean;
510+ DummyUpdateToken: String;
511+begin
512+ Result := ShowMeModal(ADamoTask,0,DummyComment,DummyPrivate,AAttachments,DummyUpdateToken,True);
513+end;
514+
515+class function TFormManageNote.ShowMeForForwarding(ADamoTask: TDamoTask; AForwardTo: TForwardingModes; out AComment: String; out AAttachments: TArray<String>): TModalResult;
516+var
517+ DummyHandlerId: Cardinal;
518+ DummyPrivate: Boolean;
519+begin
520+ Result := ShowMeModal(ADamoTask,AForwardTo,[],AComment,DummyPrivate,AAttachments,DummyHandlerId);
521+end;
522+
523+class function TFormManageNote.ShowMeForStatusChange(ADamoTask: TDamoTask; ASpecialMode: TSpecialMode; AHandlers: TArray<THandler>; out AComment: String; out APrivate: Boolean; out AHandlerId: Cardinal): TModalResult;
524+var
525+ DummyAttachments: TArray<String>;
526+begin
527+ Result := ShowMeModal(ADamoTask,ASpecialMode,AHandlers,AComment,APrivate,DummyAttachments,AHandlerId)
528+end;
529+
530+class function TFormManageNote.ShowMeForTaskExecution(ADamoTask: TDamoTask; out AComment: String; out APrivate: Boolean): TModalResult;
531+var
532+ DummyHandlers: TArray<THandler>;
533+ DummyAttachments: TArray<String>;
534+ DummyHandlerId: Cardinal;
535+begin
536+ Result := ShowMeModal(ADamoTask,TSpecialMode.Execute,DummyHandlers,AComment,APrivate,DummyAttachments,DummyHandlerId);
537+end;
538+
450539 procedure TFormManageNote.ValidateSave;
451540 begin
452541 // Caso eu não esteja no modo apenas anexos, eu tenho que lidar com o texto no
--- trunk/client/src/UFormTask.pas (revision 87)
+++ trunk/client/src/UFormTask.pas (revision 88)
@@ -792,6 +792,7 @@
792792 // epecificos
793793 ACTNSendToTest.Visible := (FDamoTask.Task.Status.Id = Configurations.MantisConfigs.StatusByName['em execução'].Id) and (FDamoTask.Task.Responsible = Configurations.UserInfo.RealName);
794794 ACTNSendToHomologation.Visible := ACTNSendToTest.Visible;
795+ ACTNExecute.Visible := FDamoTask.Task.Responsible = Configurations.UserInfo.RealName;
795796 end;
796797 pTester: begin
797798 // Ocultado ações que não podem aparecer para este perfil de forma alguma
Show on old repository browser