Subversion Repositories winbugtracker

Rev

Rev 14 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit BugtrackerMain;
  2.  
  3. (*
  4.  * TODO:
  5.  * - Spezielle Filter
  6.  *   ... Auflisten nach Modul
  7.  *   ... Anzeigen der Agenda
  8.  * - rtf control bar?
  9.  * - ein neu angelegter bug soll links aus der leiste verschwinden, wenn er nicht in das kriterium passt
  10.  *
  11.  * NOT INCLUDED:
  12.  * - duplicate of
  13.  *
  14.  * FUTURE:
  15.  * - HS Info integration
  16.  *)
  17.  
  18. interface
  19.  
  20. uses
  21.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  22.   Dialogs, WideStrings, DB, SqlExpr, StdCtrls, ExtCtrls, DBCtrls,
  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;
  80.     LblAngemeldet: TLabel;
  81.     Label7: TLabel;
  82.     Label8: TLabel;
  83.     DBLookupComboBox4: TDBLookupComboBox;
  84.     qryBugserfasser: TIntegerField;
  85.     qryBugsversion_agenda: TIntegerField;
  86.     Label9: TLabel;
  87.     cbxErfasser: TDBLookupComboBox;
  88.     Label10: TLabel;
  89.     lkpStatus: TADOTable;
  90.     dsStatus: TDataSource;
  91.     DBLookupComboBox5: TDBLookupComboBox;
  92.     qryBugsstatus: TIntegerField;
  93.     qryBugsstatus_geaendert: TDateTimeField;
  94.     Bugs1: TMenuItem;
  95.     Wechselnzu1: TMenuItem;
  96.     lkpStatusid: TAutoIncField;
  97.     lkpStatusstatus: TStringField;
  98.     lkpStatuscolor: TIntegerField;
  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);
  114.     procedure btnBearbeitungsnotizClick(Sender: TObject);
  115.     procedure qryBugsBeforeCancel(DataSet: TDataSet);
  116.     procedure DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn);
  117.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  118.     procedure qryBugsstatusChange(Sender: TField);
  119.     procedure Wechselnzu1Click(Sender: TObject);
  120.   public
  121.     eingeloggtMitarbeiter: integer;
  122.     eingeloggtMitarbeiterName: string;
  123.     aktuellesProjekt: integer;
  124.     aktuellesProjektName: string;
  125.     procedure NeuFiltern;
  126.     procedure NotizHinzufuegen(color: TColor; bez: string);
  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
  141.   qryBugs.FieldByName('wichtigkeit').AsInteger := 5; // Mitte
  142.   qryBugs.FieldByName('erstellt').AsDateTime := Now;
  143.   qryBugs.FieldByName('erfasser').AsInteger := eingeloggtMitarbeiter;
  144.   qryBugs.FieldByName('projekt').AsInteger := aktuellesProjekt;
  145.   qryBugs.FieldByName('status').AsInteger := 1; // Offen
  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.  
  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.  
  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
  193.   col := TColor(lkpStatuscolor.AsInteger);
  194.   NotizHinzufuegen(col, DBLookupComboBox5.Text);
  195. end;
  196.  
  197. procedure TfrmBugtracker.qryBugsversion_releaseValidate(Sender: TField);
  198. begin
  199.   if qryBugs.FieldByName('status').AsInteger <> 5 then
  200.   begin
  201.     // raise Exception.Create('Vor einer Veröffentlichung muss der Bugfix erst als "Veröffentlicht" markiert werden.');
  202.     qryBugs.FieldByName('status').AsInteger := 5;
  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.  
  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.  
  251. procedure TfrmBugtracker.ber1Click(Sender: TObject);
  252. begin
  253.   AboutBox.ShowModal;
  254. end;
  255.  
  256. procedure TfrmBugtracker.btnBearbeitungsnotizClick(Sender: TObject);
  257. begin
  258.   NotizHinzufuegen(clOlive, 'Notiz');
  259. end;
  260.  
  261. procedure TfrmBugtracker.ComboBox1Change(Sender: TObject);
  262. begin
  263.   case ComboBox1.ItemIndex of
  264.     0:
  265.       begin
  266.         // Meine offenen Aufgaben (nach Wichtigkeit)
  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';
  268.       end;
  269.     1:
  270.       begin
  271.         // Alle offenen Aufgaben (nach Wichtigkeit)
  272.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND (status = 1 OR status = 3) ORDER BY wichtigkeit DESC';
  273.       end;
  274.     2:
  275.       begin
  276.         // Gelöst ohne Veröffentlichung (nach Lösungsdatum)
  277.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND status = 4 ORDER BY status_geaendert DESC';
  278.       end;
  279.     3:
  280.       begin
  281.         // Gelöst und Veröffentlicht (nach Version und Lösungsdatum)
  282.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND status = 5 ORDER BY status_geaendert DESC';
  283.       end;
  284.     4:
  285.       begin
  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)
  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.  
  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;
  309.       try
  310.         qryBugs.Cancel;
  311.       finally
  312.         qryBugs.Tag := 0;
  313.       end;
  314.     end;
  315.   end;
  316. end;
  317.  
  318. procedure TfrmBugtracker.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  319. begin
  320.   qryBugs.Cancel;
  321. end;
  322.  
  323. procedure TfrmBugtracker.FormCreate(Sender: TObject);
  324. var
  325.   ini: TMemIniFile;
  326. begin
  327.   ini := TMemIniFile.Create('bugtracker.ini');
  328.   try
  329.     ADOConnection1.Connected := false;
  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;
  341.   lkpStatus.Active := true;
  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.  
  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.
  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 := '';
  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.  
  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.
  424.