Revision | 74 (tree) |
---|---|
Time | 2022-01-22 04:57:31 |
Author | ![]() |
Verificação de comentário vazio ao criar um backup de comentário
Trim aplicado na obtenção do nome do usuário e na ação obtidos a partir do histórico
Métodos Approve e Disapprove adicionados (ainda sem código)
Método Reject implementado e testado com sucesso
Em TFormBasicDialog foi sobrescrito o método CreateParams a fim de definir automaticamente o valor de WndParent
Criada uma versão sobrecarregada da função ShowMeModal em TFormManageNote de forma que a tela de edição de comentário possa aparecer para rejeições e impedimentos
Trim aplicado na obtenção de comentário em TFormManageNote
TFormTask.CreateParams ajustado corretamente
@@ -71,7 +71,7 @@ | ||
71 | 71 | begin |
72 | 72 | Configurations.UserInfo := UserInfo; |
73 | 73 | Application.CreateForm(TFormSplash, FormSplash); |
74 | - Application.Run; | |
74 | + Application.Run; | |
75 | 75 | end; |
76 | 76 | end; |
77 | 77 | end. |
@@ -119,7 +119,7 @@ | ||
119 | 119 | <VerInfo_MinorVer>0</VerInfo_MinorVer> |
120 | 120 | <VerInfo_Release>0</VerInfo_Release> |
121 | 121 | <VerInfo_Locale>1033</VerInfo_Locale> |
122 | - <VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.600;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.626;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys> | |
123 | 123 | <Debugger_RunParams>/desenvolvimento</Debugger_RunParams> |
124 | 124 | <VerInfo_AutoGenVersion>false</VerInfo_AutoGenVersion> |
125 | 125 | <VerInfo_AutoIncVersion>true</VerInfo_AutoIncVersion> |
@@ -126,7 +126,7 @@ | ||
126 | 126 | <DCC_DebugInformation>2</DCC_DebugInformation> |
127 | 127 | <DCC_SymbolReferenceInfo>2</DCC_SymbolReferenceInfo> |
128 | 128 | <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe> |
129 | - <VerInfo_Build>600</VerInfo_Build> | |
129 | + <VerInfo_Build>626</VerInfo_Build> | |
130 | 130 | <DCC_MapFile>3</DCC_MapFile> |
131 | 131 | </PropertyGroup> |
132 | 132 | <ItemGroup> |
@@ -24,7 +24,9 @@ | ||
24 | 24 | procedure CommentBackupDelete(ACommentId: Cardinal); |
25 | 25 | function CommentBackupLoad(ACommentId: Cardinal): String; |
26 | 26 | //: Adiciona o tag de cabeçalho de comentário de acordo com o id de unidade |
27 | -//: configurado caso um ainda não exista | |
27 | +//: configurado caso um ainda não exista. Esta função NÃO ADICIONA os cabeçalhos | |
28 | +//: especiais de aprovação/reprovação de tarefas, apenas os cabeçalhos padrão de | |
29 | +//: comentários de acordo com a unidade do usuário | |
28 | 30 | procedure AddCommentHeader(var AComment: String); |
29 | 31 | //: Retorna o comentário padrão de mudança de sitação de uma tarefa |
30 | 32 | function GetDefaultStatusChangeText(const AStatus: String): String; |
@@ -1138,6 +1140,9 @@ | ||
1138 | 1140 | |
1139 | 1141 | procedure CommentBackupCreate(ACommentId: Cardinal; AComment: String); |
1140 | 1142 | begin |
1143 | + if Trim(AComment) = '' then | |
1144 | + Exit; | |
1145 | + | |
1141 | 1146 | if not DirectoryExists(Configurations.TemporaryDirectory) then |
1142 | 1147 | CreateDir(Configurations.TemporaryDirectory); |
1143 | 1148 |
@@ -1164,7 +1169,7 @@ | ||
1164 | 1169 | // Apenas adiciona um cabeçalho de comentário se há a intenção de comentar |
1165 | 1170 | // algo, ou seja, se AComment <> ''. Quando se quer apenas adicionar anexos a |
1166 | 1171 | // uma tarefa isso é feito pelo mesmo script que se usa para adicionar |
1167 | - // comentários, neste caso é possível criar um "comentário" vazio, desde que | |
1172 | + // comentários, neste caso é possível criar um "comentário vazio", desde que | |
1168 | 1173 | // haja ao menos um anexo. Nestas situações de "comentário de anexos", eu |
1169 | 1174 | // convencionei não incluir qualquer cabeçalho. Se no futuro esse comentário |
1170 | 1175 | // for essencial, basta remover a condição a seguir e executar seu bloco de |
@@ -1331,9 +1331,9 @@ | ||
1331 | 1331 | HTMLElement := HTMLElementCollection.item(i,i) as IHTMLElement; |
1332 | 1332 | |
1333 | 1333 | HistoryEntry.Moment := ExtractDateTime(((HTMLElement as IHTMLTableRow).cells.item(0,0) as IHTMLElement).innerText); |
1334 | - HistoryEntry.User := ((HTMLElement as IHTMLTableRow).cells.item(1,1) as IHTMLElement).innerText; | |
1334 | + HistoryEntry.User := Trim(((HTMLElement as IHTMLTableRow).cells.item(1,1) as IHTMLElement).innerText); | |
1335 | 1335 | HistoryEntry.UserId := ParseUserId((FirstChildElement((HTMLElement as IHTMLTableRow).cells.item(1,1) as IHTMLElement) as IHTMLAnchorElement).href); |
1336 | - HistoryEntry.Action := ((HTMLElement as IHTMLTableRow).cells.item(2,2) as IHTMLElement).innerText; | |
1336 | + HistoryEntry.Action := Trim(((HTMLElement as IHTMLTableRow).cells.item(2,2) as IHTMLElement).innerText); | |
1337 | 1337 | HistoryEntry.Data := ((HTMLElement as IHTMLTableRow).cells.item(3,3) as IHTMLElement).innerText; |
1338 | 1338 | // Nova forma de incrementar um array dinâmico (a partir do XE7) |
1339 | 1339 | ATask.History := ATask.History + [HistoryEntry]; |
@@ -1983,7 +1983,14 @@ | ||
1983 | 1983 | Req.Content.Free; |
1984 | 1984 | end; |
1985 | 1985 | end; |
1986 | - | |
1986 | +// Esta função retorna true caso a página carregada após a mudança de status | |
1987 | +// (que é a página da tarefa) contenha um elemento cuja classe é bug-status e | |
1988 | +// cuja outra classe desse mesmo elemento contenha o código do status que se | |
1989 | +// quer mudar. Não fiz nada para capturar um possível erro retornado pelo mantis | |
1990 | +// porque eu simplesmente não consegui gerar tal erro e não sei como ele | |
1991 | +// apareceria na tela para que eu possa parseá-lo, logo, a função ChangeStatus | |
1992 | +// só retornará true, mas caso retorne false eu não exibirei qualquer mensagem | |
1993 | +// de erro específica | |
1987 | 1994 | function ParseChangeStatusResponse(ADocument: String; const ANewStatusId: Word): Boolean; |
1988 | 1995 | var |
1989 | 1996 | HTMLDocument: IHTMLDocument; |
@@ -2038,8 +2045,11 @@ | ||
2038 | 2045 | |
2039 | 2046 | Req.Content := TMemoryStream.Create; |
2040 | 2047 | try |
2041 | - // Adiciona o cabeçalho padrão de acordo com as configurações atuais, caso | |
2042 | - // já não exista um cabeçalho | |
2048 | + // Adiciona o cabeçalho padrão de acordo com as configurações atuais de | |
2049 | + // unidade, caso já não exista um cabeçalho. Um cabeçalho só vai existir | |
2050 | + // neste ponto caso ele tenha sido incluído de forma manual em AComment. | |
2051 | + // Isso deve acontecer apenas em mudanças de status de aprovação ou | |
2052 | + // reprovação | |
2043 | 2053 | AddCommentHeader(AComment); |
2044 | 2054 | |
2045 | 2055 | AddTextMultiPartFormData(TMemoryStream(Req.Content),'form-data','bug_update_token',RawByteString(BugUpdateToken),BOUNDARY); |
@@ -430,15 +430,6 @@ | ||
430 | 430 | |
431 | 431 | { TTask } |
432 | 432 | |
433 | -function TTask.GetExecutionsCount: Word; | |
434 | -begin | |
435 | - Result := 0; | |
436 | - | |
437 | - for var i: Cardinal := 0 to High(History) do | |
438 | - if (History[i].Action = HISTORY_ACTION_STATE) and (History[i].AsStatusChange.ToStatus.Id = Configurations.MantisConfigs.GetStatusByName(STATUS_IN_PROGRESS).Id) then | |
439 | - Inc(Result); | |
440 | -end; | |
441 | - | |
442 | 433 | procedure TTask.Clear(AAllButId: Boolean = True); |
443 | 434 | var |
444 | 435 | Id: Cardinal; |
@@ -556,6 +547,15 @@ | ||
556 | 547 | Inc(Result); |
557 | 548 | end; |
558 | 549 | |
550 | +function TTask.GetExecutionsCount: Word; | |
551 | +begin | |
552 | + Result := 0; | |
553 | + | |
554 | + for var i: Cardinal := 0 to High(History) do | |
555 | + if (History[i].Action = HISTORY_ACTION_STATE) and (History[i].AsStatusChange.ToStatus.Id = Configurations.MantisConfigs.GetStatusByName(STATUS_IN_PROGRESS).Id) then | |
556 | + Inc(Result); | |
557 | +end; | |
558 | + | |
559 | 559 | function TTask.GetRelatedTasksCount: Word; |
560 | 560 | begin |
561 | 561 | Result := Length(FRelatedTasks); |
@@ -10,7 +10,9 @@ | ||
10 | 10 | TProfile = (pUnknown, pDeveloper, pTester, pHomologator); |
11 | 11 | // Na enumeração abaixo eu não usei prefixos porque eu pretendo usar os nomes |
12 | 12 | // dos elementos diretamente para obter os nomes dos tags especiais, a fim de |
13 | - // economizar código | |
13 | + // economizar código. Além disso o uso de prefixos caiu em desuso com a | |
14 | + // possibilidade de se usar o nome do tipo como prefixo, como por exemplo, | |
15 | + // TUnitId.une2 ou TUnitId.uds1, etc. | |
14 | 16 | TUnitId = (None, uds1, uds2, uds3, uds4, uds5, unts, une1, une2, une3, une4, une5, ungc); |
15 | 17 | |
16 | 18 | TConfigurations = class(TRegistry) |
@@ -52,6 +54,7 @@ | ||
52 | 54 | end; |
53 | 55 | |
54 | 56 | const |
57 | + // Não incluir entre <p>...</p>. Apenas o texto puro | |
55 | 58 | STATUS_CHANGE_DEFAULT_COMMENT = 'Status: <b>%s</b>'; |
56 | 59 | |
57 | 60 | var |
@@ -293,6 +293,7 @@ | ||
293 | 293 | AddTask(MenuItem,Task.Id,Task.Project,Task.Status.Color); |
294 | 294 | end; |
295 | 295 | end; |
296 | + | |
296 | 297 | // AObtainedTasks = Tarefas que foram obtidas no momento |
297 | 298 | // ANewTasks = Apenas as tarefas que existem em AObtainedTasks e que não existem em FMyTasks |
298 | 299 | procedure TDamoPrincipal.GetNewTasks(AObtainedTasks: TTasks; out ANewTasks: TTasks); |
@@ -75,7 +75,12 @@ | ||
75 | 75 | procedure Refresh; |
76 | 76 | procedure ParseTaskIdAndCommentId(AUri: String; out ATaskId: Cardinal; out ACommentId: Cardinal); |
77 | 77 | procedure Execute; |
78 | + //: Rejeita uma tarefa de forma genérica, isto é, pode ser usado por | |
79 | + //: qualquer unidade a qualquer momento. Rejeições com carater de reprovação | |
80 | + //: de tarefas sendo testadas são feitas por meio do método Disapprove | |
78 | 81 | procedure Reject; |
82 | + procedure Approve; | |
83 | + procedure Disapprove; | |
79 | 84 | |
80 | 85 | property Task: TTask read FTask write FTask; |
81 | 86 | end; |
@@ -130,6 +135,11 @@ | ||
130 | 135 | UploadAttachments; |
131 | 136 | end; |
132 | 137 | |
138 | +procedure TDamoTask.Approve; | |
139 | +begin | |
140 | + // implementar! | |
141 | +end; | |
142 | + | |
133 | 143 | procedure TDamoTask.CLDSAttachmentsFileSizeGetText(Sender: TField; var Text: string; DisplayText: Boolean); |
134 | 144 | begin |
135 | 145 | Text := FormatFloat('###,###,##0',Sender.AsFloat); |
@@ -156,6 +166,11 @@ | ||
156 | 166 | Text := FormatDateTime('dd/mm/yyyy "às" hh:nn:ss',Sender.AsDateTime); |
157 | 167 | end; |
158 | 168 | |
169 | +procedure TDamoTask.Disapprove; | |
170 | +begin | |
171 | + // Implementar! | |
172 | +end; | |
173 | + | |
159 | 174 | procedure TDamoTask.DownloadAttachment(AAttachmentId: Cardinal; AFileName: String; AOpen: Boolean); |
160 | 175 | begin |
161 | 176 | SADIAttachment.DefaultExt := Copy(ExtractFileExt(AFileName),2,MAX_PATH); |
@@ -199,27 +214,52 @@ | ||
199 | 214 | procedure TDamoTask.Execute; |
200 | 215 | begin |
201 | 216 | // Colocar a tarefa em execução pode acontecer em dois momentos. A primeira |
202 | - // execução seria a "primeira ver em que a tarefa foi posta em execução" e | |
217 | + // execução seria a "primeira vez em que a tarefa foi posta em execução" e | |
203 | 218 | // todas as outras execuções subsequentes, por exemplo, quando se reinicia uma |
204 | 219 | // tarefa que foi rejeitada. Por padrão colocamos o número da execução, assim |
205 | - // é possível saber se está e a primeira execução ou uma execução posterior. | |
220 | + // é possível saber se esta é a primeira execução ou uma execução posterior. | |
206 | 221 | // Todas as execuções tem um cabeçalho e um texto padrão. Eu resolvi |
207 | 222 | // padronizar dessa forma |
208 | - ChangeStatus(Application.Handle,FTask.Id,Configurations.MantisConfigs.StatusByName[STATUS_IN_PROGRESS].Id,GetDefaultStatusChangeText(UpperCase(STATUS_IN_PROGRESS)) + ' (' + Succ(FTask.ExecutionsCount).ToString + ')'); | |
223 | + ChangeStatus(Application.Handle,FTask.Id,Configurations.MantisConfigs.StatusByName[STATUS_IN_PROGRESS].Id,GetDefaultStatusChangeText(AnsiUpperCase(STATUS_IN_PROGRESS)) + ' (' + Succ(FTask.ExecutionsCount).ToString + ')'); | |
209 | 224 | |
210 | 225 | Refresh; |
211 | 226 | end; |
212 | 227 | |
213 | 228 | procedure TDamoTask.Reject; |
229 | +var | |
230 | + Comment: String; | |
214 | 231 | begin |
215 | -//abrir a tela de edição de comentário, como se fosse um comentário novo e ao confirmar o comentário, mudar o status | |
216 | -/// COLOCAR O TEXTO DE REJEIÇÃO ABAIXO DO TEXTO PADRÃO DE MUDANÇA DE STATUS, EM UM NOVO PARÁGRAFO | |
217 | -// COLOCAR UM HR ANTES DO TEXTO DE REJEIÇÃO. FAÇA O MESMO PARA O IMPEDIMENTO E TODOS OS OUTROS ESTADOS QUE PRECISEM DE UM TEXTO | |
218 | -// APENAS COLOCAR O HR SE HOUVER O TEXTO | |
232 | +// implemente a logica abaixo para impedimento e qqr outra mudança de status simples | |
233 | +// verifique como resolver o problema do botão na barra de tarefas sem usar o trick de CreateParams, pois ao usa-lo o form secundário exibido de forma modal é coberto por seu pai | |
234 | + if TFormManageNote.ShowMeModal(Self.Owner,TSpecialMode.Reject,FTask.Id,Comment) = mrOk then | |
235 | + begin | |
236 | + CommentBackupCreate(0,Comment); | |
219 | 237 | |
238 | + var DefaultText: String := '<p>' + GetDefaultStatusChangeText(UpperCase(STATUS_REJECTED)) + ' (' + Succ(FTask.RejectionsCount).ToString + ')</p>'; | |
220 | 239 | |
221 | -// ChangeStatus(Application.Handle,FTask.Id,Configurations.MantisConfigs.StatusByName[STATUS_REJECTED].Id,GetDefaultStatusChangeText(UpperCase(STATUS_REJECTED)) + ' (' + Succ(FTask.RejectionsCount).ToString + ')'); | |
222 | - // Refresh | |
240 | + // Caso o comentário não esteja em branco, adiciona um <hr> a fim de | |
241 | + // separá-lo do texto padrão de mudança de status. Caso o comentário esteja | |
242 | + // em branco, usa somente o texto padrão de mudança de status | |
243 | + if Comment <> '' then | |
244 | + Comment := DefaultText + '<hr>' + Comment | |
245 | + else | |
246 | + Comment := DefaultText; | |
247 | + | |
248 | + if ChangeStatus(Application.Handle,FTask.Id,Configurations.MantisConfigs.StatusByName[STATUS_REJECTED].Id,Comment) then | |
249 | + begin | |
250 | + CommentBackupDelete(0); | |
251 | + Application.MessageBox('Tarefa rejeitada com sucesso!','Rejeição bem sucedida',MB_ICONINFORMATION); | |
252 | + end | |
253 | + else | |
254 | + Application.MessageBox('Não foi possível rejeitar a tarefa. Tente novamente','Erro ao rejeitar a tarefa',MB_ICONERROR); | |
255 | + // Acredito que um dos motivos pelos quais a rejeição possa falhar, seja | |
256 | + // porque alguém possa ter mudado o status da tarefa antes de nós, fazendo | |
257 | + // com que ela fique em um status que não permite uma rejeição (por exemplo, | |
258 | + // se alguém rejeito a tarefa antes de nós). Neste caso, achei mais | |
259 | + // coerente, sempre atualizar as informações, independentemente de ter | |
260 | + // havido erro ou não | |
261 | + Refresh; | |
262 | + end; | |
223 | 263 | end; |
224 | 264 | |
225 | 265 | procedure TDamoTask.NewComment; |
@@ -27,6 +27,7 @@ | ||
27 | 27 | { Private declarations } |
28 | 28 | FAutoCaption: Boolean; |
29 | 29 | protected |
30 | + procedure CreateParams(var Params: TCreateParams); override; | |
30 | 31 | procedure ValidateSave; virtual; |
31 | 32 | procedure ValidateOk; virtual; |
32 | 33 | public |
@@ -53,6 +54,23 @@ | ||
53 | 54 | end; |
54 | 55 | end; |
55 | 56 | |
57 | +procedure TFormBasicDialog.CreateParams(var Params: TCreateParams); | |
58 | +begin | |
59 | + inherited; | |
60 | + // Fazendo isso, este form nunca será colocado atrás do form que o chamou de | |
61 | + // forma modal! Excelente explicação aqui http://www.delphigroups.info/2/17/487031.html | |
62 | + // Por padrão o WndParent é sempre o handle de Application, não importa o | |
63 | + // Owner que se usou para criar o form atual. Não confundir Parent com Owner. | |
64 | + // O Owner é o responsável por destruir o form e o Parent cria uma relação | |
65 | + // hierárquica na ordem-Z aparentemente, por isso quando o Owner é TForm, | |
66 | + // precisamos trocar params.WndParent de forma que ele corresponda ao handle | |
67 | + // do Owner. Quando o Owner não é TForm, dentro da implementação atual, ele só | |
68 | + // poderá ser Application e neste caso não há necessidade de trocar | |
69 | + // params.WndParent pelo handle de seu Owner, porque este handle já vai ser o correto | |
70 | + if Owner is TForm then | |
71 | + params.WndParent := TForm(Owner).Handle; | |
72 | +end; | |
73 | + | |
56 | 74 | procedure TFormBasicDialog.FormClose(Sender: TObject; var Action: TCloseAction); |
57 | 75 | begin |
58 | 76 | Action := caFree; |
@@ -10,6 +10,8 @@ | ||
10 | 10 | UTypes, UDamoTask; |
11 | 11 | |
12 | 12 | type |
13 | + TSpecialMode = (None,Reject,Impede); | |
14 | + | |
13 | 15 | TFormManageNote = class(TFormBasicDialog) |
14 | 16 | PACO: TPageControl; |
15 | 17 | TASHComment: TTabSheet; |
@@ -40,6 +42,7 @@ | ||
40 | 42 | FUpdating: Boolean; |
41 | 43 | FAttachmentsOnly: Boolean; |
42 | 44 | FPostContent: TStringStream; |
45 | + FSpecialMode: TSpecialMode; | |
43 | 46 | |
44 | 47 | procedure DoDropFiles(ASender: TObject; const ADropHandle: LRESULT; out AMessageResult: LRESULT); |
45 | 48 | procedure ConfigureCommentsPage; |
@@ -49,7 +52,8 @@ | ||
49 | 52 | procedure ValidateSave; override; |
50 | 53 | public |
51 | 54 | { Public declarations } |
52 | - class function ShowMeModal(ADamoTask: TDamoTask; ATask: TTask; ACommentId: Cardinal; out AComment: String; out AAttachments: TArray<String>; out AUpdateToken: String; AAttacmentshOnly: Boolean = False): TModalResult; reintroduce; | |
55 | + class function ShowMeModal(ADamoTask: TDamoTask; ATask: TTask; ACommentId: Cardinal; out AComment: String; out AAttachments: TArray<String>; out AUpdateToken: String; AAttacmentshOnly: Boolean = False): TModalResult; reintroduce; overload; | |
56 | + class function ShowMeModal(AOwner: TComponent; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String): TModalResult; reintroduce; overload; | |
53 | 57 | end; |
54 | 58 | |
55 | 59 | implementation |
@@ -114,8 +118,9 @@ | ||
114 | 118 | procedure TFormManageNote.ConfigureAttachmentsPage; |
115 | 119 | begin |
116 | 120 | // A aba de anexos só é visível se estamos no modo de inserção, ou no modo de |
117 | - // edição quando há anexos associados ao comentário | |
118 | - TASHAttachments.TabVisible := (not FUpdating) or (FTask.CommentById[FCommentId].AttachmentsCount > 0); | |
121 | + // edição quando há anexos associados ao comentário ou caso estejamos | |
122 | + // executando algum modo especial | |
123 | + TASHAttachments.TabVisible := ((not FUpdating) and (FSpecialMode = TSpecialMode.None)) or (FTask.CommentById[FCommentId].AttachmentsCount > 0); | |
119 | 124 | // Caso a aba de anexos esteja visível e estivermos no modo de edição, |
120 | 125 | // precisamos carregar os anexos no ListView, que, neste caso, não aceitará |
121 | 126 | // mais anexos, servido apenas para que possamos copiar referências a eles |
@@ -280,6 +285,34 @@ | ||
280 | 285 | end; |
281 | 286 | end; |
282 | 287 | |
288 | +class function TFormManageNote.ShowMeModal(AOwner: TComponent; ASpecialMode: TSpecialMode; ATaskId: Cardinal; out AComment: String): TModalResult; | |
289 | +begin | |
290 | + with Self.Create(AOwner) do | |
291 | + begin | |
292 | + AComment := ''; | |
293 | + | |
294 | + FComment := ''; | |
295 | + FSpecialMode := ASpecialMode; | |
296 | + FUpdating := False; | |
297 | + | |
298 | + AutoCaption := False; | |
299 | + | |
300 | + Caption := 'Gerenciador de anotações - ' + Application.Title; | |
301 | + | |
302 | + case ASpecialMode of | |
303 | + TSpecialMode.Reject: LABECaption.Caption := 'Rejeitando a tarefa #' + ATaskId.ToString; | |
304 | + TSpecialMode.Impede: LABECaption.Caption := 'Colocando em impedindo a tarefa #' + ATaskId.ToString; | |
305 | + end; | |
306 | + | |
307 | + // Caso exista um backup, pergunta se quer carregar. | |
308 | + if CommentBackupExists(0) and (Application.MessageBox('Existe um backup do texto de um comentário que estava sendo redigido, deseja carregá-lo?','Deseja carregar o backup?',MB_ICONQUESTION or MB_YESNO) = IDYES) then | |
309 | + FComment := CommentBackupLoad(0); | |
310 | + | |
311 | + Result := ShowModal; | |
312 | + AComment := FComment; | |
313 | + end; | |
314 | +end; | |
315 | + | |
283 | 316 | class function TFormManageNote.ShowMeModal(ADamoTask: TDamoTask; ATask: TTask; ACommentId: Cardinal; out AComment: String; out AAttachments: TArray<String>; out AUpdateToken: String; AAttacmentshOnly: Boolean = False): TModalResult; |
284 | 317 | begin |
285 | 318 | Result := mrAbort; // Se tudo der errado... |
@@ -293,6 +326,7 @@ | ||
293 | 326 | AUpdateToken := ''; |
294 | 327 | |
295 | 328 | FComment := ''; |
329 | + FSpecialMode := TSpecialMode.None; | |
296 | 330 | FUpdating := FCommentId > 0; |
297 | 331 | // O modo de edição tem precedência sobre o modo "apenas anexos". Caso |
298 | 332 | // estejamos no modo de edição e AAttacmentshOnly seja true, isso configura |
@@ -330,7 +364,7 @@ | ||
330 | 364 | begin |
331 | 365 | FComment := CommentBackupLoad(FCommentId); |
332 | 366 | Result := ShowModal; |
333 | - AComment := FComment; | |
367 | + AComment := Trim(FComment); | |
334 | 368 | end |
335 | 369 | // Caso não existe um backup ou o usuário optou por não carregar um, |
336 | 370 | // simplesmente abre o form com o comentário obtido do Mantis |
@@ -337,7 +371,7 @@ | ||
337 | 371 | else |
338 | 372 | begin |
339 | 373 | Result := ShowModal; |
340 | - AComment := FComment; | |
374 | + AComment := Trim(FComment); | |
341 | 375 | end; |
342 | 376 | end |
343 | 377 | // Se não estamos tentando editar um comentário, entraremos no modo de |
@@ -354,7 +388,7 @@ | ||
354 | 388 | // livrar deles ao final |
355 | 389 | |
356 | 390 | Result := ShowModal; |
357 | - AComment := FComment; | |
391 | + AComment := Trim(FComment); | |
358 | 392 | AAttachments := FAttachments; |
359 | 393 | end; |
360 | 394 | end; |
@@ -190,11 +190,22 @@ | ||
190 | 190 | FDamoTask.Name := '_' + ATaskId.ToString; |
191 | 191 | end; |
192 | 192 | |
193 | +//resolvendo o problema de showmodal em forms secundários que tem botão na barra | |
194 | +// de tarefas | |
195 | +//http://www.delphigroups.info/2/17/487031.html | |
193 | 196 | procedure TFormTask.CreateParams(var Params: TCreateParams); |
194 | 197 | begin |
198 | + // Em TFormBasicDialog há um método CreateParams sobrescrito que configura | |
199 | + // Params.WndParent com o Handle do TForm ou TApplication que for o dono do | |
200 | + // form sendo criado. Isso é o comportamento adequado para forms que abrem a | |
201 | + // partir de instâncias do form atual. Já para estas últimas, Params.WndParent | |
202 | + // precisa ser reconfigurado, como a seguir | |
195 | 203 | inherited; |
196 | - Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; | |
197 | -// Params.WndParent := 0; | |
204 | + // A linha abaixo faz com que este form tenha um botão correspondente na barra | |
205 | + // de tarefas, fazendo com que o desktop seja a janela pai deste form. Não | |
206 | + // fazer isso, faz com que ao clicar em um dos botões da barra de tarefas, | |
207 | + // todos os forms irmãos dentro da mesma aplicação sejam jogados para frente | |
208 | + Params.WndParent := GetDesktopWindow; | |
198 | 209 | end; |
199 | 210 | |
200 | 211 | procedure TFormTask.EDBRAdditionalInformationCreateWebViewCompleted(Sender: TCustomEdgeBrowser; AResult: HRESULT); |
@@ -414,10 +425,12 @@ | ||
414 | 425 | {$WARN SYMBOL_PLATFORM OFF} |
415 | 426 | if DebugHook > 0 then |
416 | 427 | begin |
417 | - var DatDirectory: String := ExpandFileName('..\res\dat\'); | |
418 | - FDamoTask.CLDSHistory.SaveToFile(DatDirectory + 'history.cds'); | |
419 | - FDamoTask.CLDSRelatedTasks.SaveToFile(DatDirectory + 'relatedtasks.cds'); | |
420 | - FDamoTask.CLDSAttachments.SaveToFile(DatDirectory + 'attachments.cds'); | |
428 | +// var DatDirectory: String := ExpandFileName('..\res\dat\'); | |
429 | +// FDamoTask.CLDSHistory.SaveToFile(DatDirectory + 'history.cds'); | |
430 | +// FDamoTask.CLDSRelatedTasks.SaveToFile(DatDirectory + 'relatedtasks.cds'); | |
431 | +// FDamoTask.CLDSAttachments.SaveToFile(DatDirectory + 'attachments.cds'); | |
432 | + | |
433 | +// FDamoTask.Task.ExecutionsCount; | |
421 | 434 | end; |
422 | 435 | {$WARN SYMBOL_PLATFORM ON} |
423 | 436 | end; |