Subversion Repositories winbugtracker

Rev

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