Subversion Repositories winbugtracker

Rev

Rev 7 | Rev 11 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 daniel-mar 1
unit BugtrackerMain;
2
 
3
(*
4
 * TODO:
5 daniel-mar 5
 * - Spezielle Filter
6
 *   ... Auflisten nach Modul
7
 *   ... Anzeigen der Agenda
4 daniel-mar 8
 * - verbinden mit ticketsystem von HS
9
 * - rtf controls?
5 daniel-mar 10
 * - Neue Felder:
11
 *   ... Erfasser
12
 *   ... Agenda
13
 *   ... Status = Offen, gefixt, Abgelehnt, Veröffentlicht
14
 *   ... RTF Feld als BIGTEXT definieren
15
 * - Neue Aufteilung der States
16
 *   ... Open, Fixed, Published, Wontfix/Rejected, Planned(Agenda)
7 daniel-mar 17
 *
18
 * NOT INCLUDED:
19
 * - duplicate of
20
 *
21
 * FUTURE:
22
 * - HS Info integration
4 daniel-mar 23
 *)
24
 
25
interface
26
 
27
uses
28
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
6 daniel-mar 29
  Dialogs, WideStrings, DB, SqlExpr, StdCtrls, ExtCtrls, DBCtrls,
4 daniel-mar 30
  ADODB, ComCtrls, Grids, DBGrids, Mask, Menus, XPMan;
31
 
32
type
33
  TfrmBugtracker = class(TForm)
34
    Panel1: TPanel;
35
    DBGrid1: TDBGrid;
36
    ComboBox1: TComboBox;
37
    DBNavigator2: TDBNavigator;
38
    Panel2: TPanel;
39
    Label1: TLabel;
40
    Label2: TLabel;
41
    Label3: TLabel;
42
    Label4: TLabel;
43
    Label5: TLabel;
44
    Label6: TLabel;
45
    DBNavigator1: TDBNavigator;
46
    DBRichEdit1: TDBRichEdit;
47
    DBEdit1: TDBEdit;
48
    DBLookupComboBox1: TDBLookupComboBox;
49
    DBEdit2: TDBEdit;
50
    DBEdit3: TDBEdit;
51
    DBLookupComboBox2: TDBLookupComboBox;
52
    DBLookupComboBox3: TDBLookupComboBox;
53
    TrackBar1: TTrackBar;
54
    ADOConnection1: TADOConnection;
55
    dsBugs: TDataSource;
56
    tblMitarbeiter: TADOTable;
57
    dsMitarbeiter: TDataSource;
58
    MainMenu1: TMainMenu;
59
    Stammdaten1: TMenuItem;
60
    Mitarbeiter1: TMenuItem;
61
    Projekte1: TMenuItem;
62
    Module1: TMenuItem;
63
    Versionen1: TMenuItem;
64
    Projektwechseln1: TMenuItem;
65
    XPManifest1: TXPManifest;
66
    qryBugs: TADOQuery;
67
    dsVersionen: TDataSource;
68
    tblProjekte: TADOTable;
69
    dsProjekte: TDataSource;
70
    dsModule: TDataSource;
71
    Timer1: TTimer;
72
    Splitter1: TSplitter;
73
    Hilfe1: TMenuItem;
74
    ber1: TMenuItem;
75
    btnFixedToggle: TButton;
76
    btnBearbeitungsnotiz: TButton;
77
    qryBugsid: TAutoIncField;
78
    qryBugstitel: TStringField;
79
    qryBugsbeschreibung: TMemoField;
80
    qryBugserstellt: TDateTimeField;
81
    qryBugswichtigkeit: TIntegerField;
82
    qryBugsbearbeiter: TIntegerField;
83
    qryBugsfixdatum: TDateTimeField;
84
    qryBugsversion_release: TIntegerField;
85
    qryBugsmodul: TIntegerField;
86
    qryBugsprojekt: TIntegerField;
87
    qryVersionen: TADOQuery;
88
    qryModule: TADOQuery;
5 daniel-mar 89
    LblAngemeldet: TLabel;
90
    Label7: TLabel;
91
    Label8: TLabel;
6 daniel-mar 92
    DBLookupComboBox4: TDBLookupComboBox;
93
    qryBugserfasser: TIntegerField;
94
    qryBugsversion_agenda: TIntegerField;
95
    Label9: TLabel;
96
    cbxErfasser: TDBLookupComboBox;
97
    Label10: TLabel;
4 daniel-mar 98
    procedure Mitarbeiter1Click(Sender: TObject);
99
    procedure qryBugsAfterScroll(DataSet: TDataSet);
100
    procedure Module1Click(Sender: TObject);
101
    procedure Projekte1Click(Sender: TObject);
102
    procedure Versionen1Click(Sender: TObject);
103
    procedure TrackBar1Change(Sender: TObject);
104
    procedure Timer1Timer(Sender: TObject);
105
    procedure ComboBox1Change(Sender: TObject);
106
    procedure Projektwechseln1Click(Sender: TObject);
107
    procedure qryBugsAfterInsert(DataSet: TDataSet);
108
    procedure ber1Click(Sender: TObject);
109
    procedure btnFixedToggleClick(Sender: TObject);
110
    procedure qryBugsversion_releaseValidate(Sender: TField);
111
    procedure FormCreate(Sender: TObject);
112
    procedure qryVersionenAfterInsert(DataSet: TDataSet);
113
    procedure qryModuleAfterInsert(DataSet: TDataSet);
5 daniel-mar 114
    procedure btnBearbeitungsnotizClick(Sender: TObject);
8 daniel-mar 115
    procedure qryBugsBeforeCancel(DataSet: TDataSet);
116
    procedure DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn);
117
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
4 daniel-mar 118
  public
119
    eingeloggtMitarbeiter: integer;
5 daniel-mar 120
    eingeloggtMitarbeiterName: string;
4 daniel-mar 121
    aktuellesProjekt: integer;
5 daniel-mar 122
    aktuellesProjektName: string;
4 daniel-mar 123
    procedure NeuFiltern;
5 daniel-mar 124
    procedure NotizHinzufuegen(color: TColor; bez: string);
4 daniel-mar 125
  end;
126
 
127
var
128
  frmBugtracker: TfrmBugtracker;
129
 
130
implementation
131
 
132
uses Mitarbeiter, Module, Versionen, Projekte, Login, About, inifiles;
133
 
134
{$R *.dfm}
135
 
136
procedure TfrmBugtracker.qryBugsAfterInsert(DataSet: TDataSet);
137
begin
138
  // Standardwerte für einen neuen Bug
6 daniel-mar 139
  qryBugs.FieldByName('wichtigkeit').AsInteger := 5; // Mitte
140
  qryBugs.FieldByName('erstellt').AsDateTime := Now;
141
  qryBugs.FieldByName('erfasser').AsInteger := eingeloggtMitarbeiter;
4 daniel-mar 142
  // qryBugs.FieldByName('bearbeiter').AsInteger := eingeloggtMitarbeiter;
143
  qryBugs.FieldByName('projekt').AsInteger := aktuellesProjekt;
144
end;
145
 
146
procedure TfrmBugtracker.qryBugsAfterScroll(DataSet: TDataSet);
147
var
148
  bakEvent: TNotifyEvent;
149
begin
150
  bakEvent := TrackBar1.OnChange;
151
  TrackBar1.OnChange := nil;
152
  try
153
    TrackBar1.Position := qryBugs.FieldByName('wichtigkeit').AsInteger;
154
  finally
155
    TrackBar1.OnChange := bakEvent;
156
  end;
157
end;
158
 
8 daniel-mar 159
procedure TfrmBugtracker.qryBugsBeforeCancel(DataSet: TDataSet);
160
var
161
  abfrage: Integer;
162
begin
163
  // Tag 1 = Es wurde der "Abbrechen"-Knopf im DBNavigator gedrückt, also wollen wir keine unnötige Bestätigung
164
  // Alles andere = Irgendwas anderes (z.B. Scrolling oder versehentlich versucht das Fenster zu schließen)
165
  if qryBugs.Tag = 1 then exit;
166
 
167
  abfrage := MessageDlg('Speichern?', mtConfirmation, mbYesNoCancel, 0);
168
 
169
  if (abfrage = IDNo) or (abfrage = IDYes) or (abfrage = IDOK) then
170
  begin
171
     if abfrage = IDYes then
172
     begin
173
       if (qryBugs.state in [dsEdit, dsInsert]) then qryBugs.Post;
174
     end;
175
     if abfrage = IDNo then
176
     begin
177
       // Wir befinden uns bereits in qryBugs.Cancel, daher auskommentiert.
178
       // if (qryBugs.state in [dsEdit, dsInsert]) then qryBugs.Cancel;
179
     end;
180
  end
181
  else raise EAbort.Create('Abbruch durch Benutzer'); // Cancel geklickt
182
end;
183
 
4 daniel-mar 184
procedure TfrmBugtracker.qryBugsversion_releaseValidate(Sender: TField);
185
begin
186
  if qryBugs.FieldByName('fixdatum').IsNull then
187
  begin
188
    raise Exception.Create('Vor einer Veröffentlichung muss der Bugfix erst als gefixt markiert werden.');
189
  end;
190
end;
191
 
192
procedure TfrmBugtracker.qryModuleAfterInsert(DataSet: TDataSet);
193
begin
194
  // Standardwerte für ein neues Modul
195
  qryModule.FieldByName('projekt').AsInteger := aktuellesProjekt;
196
end;
197
 
198
procedure TfrmBugtracker.qryVersionenAfterInsert(DataSet: TDataSet);
199
begin
200
  // Standardwerte für eine neue Version
201
  qryVersionen.FieldByName('projekt').AsInteger := aktuellesProjekt;
202
end;
203
 
204
procedure TfrmBugtracker.Timer1Timer(Sender: TObject);
205
begin
206
  Timer1.Enabled := false;
207
  if frmLogin.ShowModal = mrCancel then Close;
208
end;
209
 
210
procedure TfrmBugtracker.TrackBar1Change(Sender: TObject);
211
begin
212
  if not (qryBugs.State in [dsEdit, dsInsert]) then qryBugs.Edit;
213
  qryBugs.FieldByName('wichtigkeit').AsInteger := TrackBar1.Position;
214
end;
215
 
216
procedure TfrmBugtracker.Versionen1Click(Sender: TObject);
217
begin
218
  frmVersionen.ShowModal;
219
end;
220
 
221
procedure TfrmBugtracker.ber1Click(Sender: TObject);
222
begin
223
  AboutBox.ShowModal;
224
end;
225
 
5 daniel-mar 226
procedure TfrmBugtracker.btnBearbeitungsnotizClick(Sender: TObject);
227
begin
228
  NotizHinzufuegen(clRed, 'Notiz');
229
end;
230
 
4 daniel-mar 231
procedure TfrmBugtracker.btnFixedToggleClick(Sender: TObject);
232
begin
233
  if not (qryBugs.State in [dsEdit, dsInsert]) then qryBugs.Edit;
234
  if qryBugs.FieldByName('fixdatum').IsNull then
5 daniel-mar 235
  begin
236
    qryBugs.FieldByName('fixdatum').AsDateTime := Now;
237
    NotizHinzufuegen(clGreen, 'Gefixt');
238
  end
4 daniel-mar 239
  else
5 daniel-mar 240
  begin
4 daniel-mar 241
    qryBugs.FieldByName('fixdatum').Clear;
5 daniel-mar 242
    NotizHinzufuegen(clBlue, 'Neu eröffnet');
243
  end;
4 daniel-mar 244
end;
245
 
246
procedure TfrmBugtracker.ComboBox1Change(Sender: TObject);
247
begin
248
  case ComboBox1.ItemIndex of
249
    0:
250
      begin
251
        // Meine offenen Bugs (nach Wichtigkeit)
252
        qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND fixdatum IS NULL AND bearbeiter = '+IntToStr(eingeloggtMitarbeiter)+' ORDER BY wichtigkeit DESC';
253
      end;
254
    1:
255
      begin
256
        // Alle offenen Bugs (nach Wichtigkeit)
257
        qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND fixdatum IS NULL ORDER BY wichtigkeit DESC';
258
      end;
259
    2:
260
      begin
261
        // Gelöst ohne Veröffentlichung (nach Lösungsdatum)
262
        qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND fixdatum IS NOT NULL ORDER BY fixdatum DESC';
263
      end;
264
    3:
265
      begin
266
        // Gelöst und Veröffentlicht (nach Version und Lösungsdatum)
267
        qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND fixdatum IS NOT NULL ORDER BY version_release DESC, fixdatum DESC';
268
      end;
269
    4:
270
      begin
271
        // Alle Bugs (nach Eröffnungsdatum)
272
        qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' ORDER BY erstellt DESC';
273
      end;
274
  end;
275
  qryBugs.Active := true;
276
end;
277
 
8 daniel-mar 278
procedure TfrmBugtracker.DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn);
279
begin
280
  if Button = nbCancel then
281
  begin
282
    if qryBugs.state  in [dsEdit,dsInsert] then
283
    begin
284
      // Tag=1 soll verhindern, dass nicht gefragt wird, ob man Speichern möchte.
285
      // Ansonsten würde diese Meldung kommen, denn ".Cancel" wird automatisch
286
      // bei Ereignissen wie z.B. dem Scrolling aufgerufen (noch bevor
287
      // OnBeforeScroll aufgerufen wird), bei dem man einen MBOnCloseQuery wünscht.
288
      qryBugs.Tag := 1;
289
      qryBugs.Cancel;
290
      qryBugs.Tag := 0;
291
    end;
292
  end;
293
end;
294
 
295
procedure TfrmBugtracker.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
296
begin
297
  qryBugs.Cancel;
298
end;
299
 
4 daniel-mar 300
procedure TfrmBugtracker.FormCreate(Sender: TObject);
301
var
302
  ini: TMemIniFile;
303
begin
304
  ini := TMemIniFile.Create('bugtracker.ini');
305
  try
6 daniel-mar 306
    ADOConnection1.Connected := false;
4 daniel-mar 307
    ADOConnection1.ConnectionString := ini.ReadString('Database', 'ConnectionString', '');
308
  finally
309
    ini.Free;
310
  end;
311
 
312
  ADOConnection1.Connected := true;
313
  qryBugs.Active := true;
314
  tblMitarbeiter.Active := true;
315
  qryVersionen.Active := true;
316
  tblProjekte.Active := true;
317
  qryModule.Active := true;
318
end;
319
 
320
procedure TfrmBugtracker.Mitarbeiter1Click(Sender: TObject);
321
begin
322
  frmMitarbeiter.ShowModal;
323
end;
324
 
325
procedure TfrmBugtracker.Module1Click(Sender: TObject);
326
begin
327
  frmModule.ShowModal;
328
end;
329
 
330
procedure TfrmBugtracker.NeuFiltern;
331
begin
332
  ComboBox1Change(ComboBox1);
333
 
334
  qryModule.SQL.Text := 'SELECT * FROM module WHERE projekt = ' + IntToStr(aktuellesProjekt);
335
  qryModule.Active := true;
336
 
337
  qryVersionen.SQL.Text := 'SELECT * FROM versionen WHERE projekt = ' + IntToStr(aktuellesProjekt);
338
  qryVersionen.Active := true;
339
end;
340
 
5 daniel-mar 341
procedure TfrmBugtracker.NotizHinzufuegen(color: TColor; bez: string);
342
var
343
  leerzeilen: integer;
344
  umbruch: string;
345
  prefix: string;
346
begin
347
  if not (qryBugs.State in [dsEdit, dsInsert]) then qryBugs.Edit;
348
 
349
  // Endet der Text mit zwei Zeilenabständen? Wenn nein, dann einfügen.
350
  leerzeilen := 0;
351
  if Copy(DBRichEdit1.Text, 1+Length(DBRichEdit1.Text)-2, 2) = #13#10 then Inc(leerzeilen); // letzte Zeile
352
  if Copy(DBRichEdit1.Text, 1+Length(DBRichEdit1.Text)-4, 2) = #13#10 then Inc(leerzeilen); // Vorletzte Zeile
353
  case leerzeilen of
354
    0: umbruch := #13#10#13#10;
355
    1: umbruch := #13#10;
356
    2: umbruch := '';
357
  end;
358
 
359
  DBRichEdit1.SelStart := DBRichEdit1.GetTextLen;
360
  DBRichEdit1.SelText := umbruch;
361
 
362
  DBRichEdit1.SelAttributes.Size := 13;
363
  DBRichEdit1.SelAttributes.Color := color;
364
  DBRichEdit1.SelAttributes.Style := [fsUnderline];
365
  if Trim(bez) <> '' then
366
    prefix := Trim(bez) + ' - '
367
  else
368
    prefix := '';
369
  DBRichEdit1.SelText := prefix + eingeloggtMitarbeiterName + ' ' + FormatDateTime('dd.mm.yyyy hh:nn', Now); // DateTimeToStr(Now);
370
 
371
  DBRichEdit1.SelAttributes.Size := 10;
372
  DBRichEdit1.SelAttributes.Color := clWindowText;
373
  DBRichEdit1.SelAttributes.Style := [];
374
  DBRichEdit1.SelText := #13#10 {+ '<Hier Text eingeben>'};
375
 
376
  // Ans Ende scrollen
377
  DBRichEdit1.SetFocus;
378
  DBRichEdit1.SelStart := DBRichEdit1.GetTextLen;
379
  DBRichEdit1.Perform(EM_SCROLLCARET, 0, 0);
380
end;
381
 
4 daniel-mar 382
procedure TfrmBugtracker.Projekte1Click(Sender: TObject);
383
begin
384
  frmProjekte.ShowModal;
385
end;
386
 
387
procedure TfrmBugtracker.Projektwechseln1Click(Sender: TObject);
388
begin
389
  frmLogin.ShowModal;
390
end;
391
 
392
end.