Subversion Repositories winbugtracker

Rev

Rev 11 | Rev 13 | Go to most recent revision | 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.     procedure Mitarbeiter1Click(Sender: TObject);
  97.     procedure qryBugsAfterScroll(DataSet: TDataSet);
  98.     procedure Module1Click(Sender: TObject);
  99.     procedure Projekte1Click(Sender: TObject);
  100.     procedure Versionen1Click(Sender: TObject);
  101.     procedure TrackBar1Change(Sender: TObject);
  102.     procedure Timer1Timer(Sender: TObject);
  103.     procedure ComboBox1Change(Sender: TObject);
  104.     procedure Projektwechseln1Click(Sender: TObject);
  105.     procedure qryBugsAfterInsert(DataSet: TDataSet);
  106.     procedure ber1Click(Sender: TObject);
  107.     procedure qryBugsversion_releaseValidate(Sender: TField);
  108.     procedure FormCreate(Sender: TObject);
  109.     procedure qryVersionenAfterInsert(DataSet: TDataSet);
  110.     procedure qryModuleAfterInsert(DataSet: TDataSet);
  111.     procedure btnBearbeitungsnotizClick(Sender: TObject);
  112.     procedure qryBugsBeforeCancel(DataSet: TDataSet);
  113.     procedure DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn);
  114.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  115.     procedure qryBugsstatusChange(Sender: TField);
  116.     procedure Wechselnzu1Click(Sender: TObject);
  117.   public
  118.     eingeloggtMitarbeiter: integer;
  119.     eingeloggtMitarbeiterName: string;
  120.     aktuellesProjekt: integer;
  121.     aktuellesProjektName: string;
  122.     procedure NeuFiltern;
  123.     procedure NotizHinzufuegen(color: TColor; bez: string);
  124.   end;
  125.  
  126. var
  127.   frmBugtracker: TfrmBugtracker;
  128.  
  129. implementation
  130.  
  131. uses Mitarbeiter, Module, Versionen, Projekte, Login, About, inifiles;
  132.  
  133. {$R *.dfm}
  134.  
  135. procedure TfrmBugtracker.qryBugsAfterInsert(DataSet: TDataSet);
  136. begin
  137.   // Standardwerte für einen neuen Bug
  138.   qryBugs.FieldByName('wichtigkeit').AsInteger := 5; // Mitte
  139.   qryBugs.FieldByName('erstellt').AsDateTime := Now;
  140.   qryBugs.FieldByName('erfasser').AsInteger := eingeloggtMitarbeiter;
  141.   qryBugs.FieldByName('projekt').AsInteger := aktuellesProjekt;
  142.   qryBugs.FieldByName('status').AsInteger := 1; // Offen
  143. end;
  144.  
  145. procedure TfrmBugtracker.qryBugsAfterScroll(DataSet: TDataSet);
  146. var
  147.   bakEvent: TNotifyEvent;
  148. begin
  149.   bakEvent := TrackBar1.OnChange;
  150.   TrackBar1.OnChange := nil;
  151.   try
  152.     TrackBar1.Position := qryBugs.FieldByName('wichtigkeit').AsInteger;
  153.   finally
  154.     TrackBar1.OnChange := bakEvent;
  155.   end;
  156. end;
  157.  
  158. procedure TfrmBugtracker.qryBugsBeforeCancel(DataSet: TDataSet);
  159. var
  160.   abfrage: Integer;
  161. begin
  162.   // Tag 1 = Es wurde der "Abbrechen"-Knopf im DBNavigator gedrückt, also wollen wir keine unnötige Bestätigung
  163.   // Alles andere = Irgendwas anderes (z.B. Scrolling oder versehentlich versucht das Fenster zu schließen)
  164.   if qryBugs.Tag = 1 then exit;
  165.  
  166.   abfrage := MessageDlg('Speichern?', mtConfirmation, mbYesNoCancel, 0);
  167.  
  168.   if (abfrage = IDNo) or (abfrage = IDYes) or (abfrage = IDOK) then
  169.   begin
  170.      if abfrage = IDYes then
  171.      begin
  172.        if (qryBugs.state in [dsEdit, dsInsert]) then qryBugs.Post;
  173.      end;
  174.      if abfrage = IDNo then
  175.      begin
  176.        // Wir befinden uns bereits in qryBugs.Cancel, daher auskommentiert.
  177.        // if (qryBugs.state in [dsEdit, dsInsert]) then qryBugs.Cancel;
  178.      end;
  179.   end
  180.   else raise EAbort.Create('Abbruch durch Benutzer'); // Cancel geklickt
  181. end;
  182.  
  183. procedure TfrmBugtracker.qryBugsstatusChange(Sender: TField);
  184. var
  185.   col: TColor;
  186. begin
  187.   qryBugsstatus_geaendert.AsDateTime := Now;
  188.  
  189.   DBLookupComboBox5.KeyValue := qryBugsstatus.AsVariant; // nur benötigt, daamit wir auf DBLookupComboBox5.Text zugreifen können
  190.   case qryBugsstatus.AsInteger of
  191.     // TODO: farben in db?
  192.     1: col := clRed; // Offen
  193.     2: col := clMaroon; // Abgelehnt
  194.     3: col := clPurple; // In Bearbeitung
  195.     4: col := clTeal; // Gefixt
  196.     5: col := clGreen; // Veröffentlicht
  197.     else
  198.       col := clBlack; // sollte nicht passieren
  199.   end;
  200.   NotizHinzufuegen(col, DBLookupComboBox5.Text);
  201. end;
  202.  
  203. procedure TfrmBugtracker.qryBugsversion_releaseValidate(Sender: TField);
  204. begin
  205.   if qryBugs.FieldByName('status').AsInteger <> 5 then
  206.   begin
  207.     // raise Exception.Create('Vor einer Veröffentlichung muss der Bugfix erst als "Veröffentlicht" markiert werden.');
  208.     qryBugs.FieldByName('status').AsInteger := 5;
  209.   end;
  210. end;
  211.  
  212. procedure TfrmBugtracker.qryModuleAfterInsert(DataSet: TDataSet);
  213. begin
  214.   // Standardwerte für ein neues Modul
  215.   qryModule.FieldByName('projekt').AsInteger := aktuellesProjekt;
  216. end;
  217.  
  218. procedure TfrmBugtracker.qryVersionenAfterInsert(DataSet: TDataSet);
  219. begin
  220.   // Standardwerte für eine neue Version
  221.   qryVersionen.FieldByName('projekt').AsInteger := aktuellesProjekt;
  222. end;
  223.  
  224. procedure TfrmBugtracker.Timer1Timer(Sender: TObject);
  225. begin
  226.   Timer1.Enabled := false;
  227.   if frmLogin.ShowModal = mrCancel then Close;
  228. end;
  229.  
  230. procedure TfrmBugtracker.TrackBar1Change(Sender: TObject);
  231. begin
  232.   if not (qryBugs.State in [dsEdit, dsInsert]) then qryBugs.Edit;
  233.   qryBugs.FieldByName('wichtigkeit').AsInteger := TrackBar1.Position;
  234. end;
  235.  
  236. procedure TfrmBugtracker.Versionen1Click(Sender: TObject);
  237. begin
  238.   frmVersionen.ShowModal;
  239. end;
  240.  
  241. procedure TfrmBugtracker.Wechselnzu1Click(Sender: TObject);
  242. var
  243.   s: string;
  244.   id, ec: integer;
  245. begin
  246.   s := Trim(InputBox('Wechseln zu Bug', 'ID des Bugs eingeben', '0'));
  247.   if s = '' then exit;  
  248.   Val(s, id, ec);
  249.   if ec <> 0 then
  250.   begin
  251.     ShowMessageFmt('"%s" ist keine gültige Bug-ID-Nummer.', [id]);
  252.     exit;
  253.   end;
  254.   qryBugs.Locate('id', id, []);
  255. end;
  256.  
  257. procedure TfrmBugtracker.ber1Click(Sender: TObject);
  258. begin
  259.   AboutBox.ShowModal;
  260. end;
  261.  
  262. procedure TfrmBugtracker.btnBearbeitungsnotizClick(Sender: TObject);
  263. begin
  264.   NotizHinzufuegen(clOlive, 'Notiz');
  265. end;
  266.  
  267. procedure TfrmBugtracker.ComboBox1Change(Sender: TObject);
  268. begin
  269.   case ComboBox1.ItemIndex of
  270.     0:
  271.       begin
  272.         // Meine offenen Bugs (nach Wichtigkeit)
  273.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND (status = 1 OR status = 3) AND bearbeiter = '+IntToStr(eingeloggtMitarbeiter)+' ORDER BY wichtigkeit DESC';
  274.       end;
  275.     1:
  276.       begin
  277.         // Alle offenen Bugs (nach Wichtigkeit)
  278.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND (status = 1 OR status = 3) ORDER BY wichtigkeit DESC';
  279.       end;
  280.     2:
  281.       begin
  282.         // Gelöst ohne Veröffentlichung (nach Lösungsdatum)
  283.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND status = 4 ORDER BY status_geaendert DESC';
  284.       end;
  285.     3:
  286.       begin
  287.         // Gelöst und Veröffentlicht (nach Version und Lösungsdatum)
  288.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' AND status = 5 ORDER BY status_geaendert DESC';
  289.       end;
  290.     4:
  291.       begin
  292.         // Alle Bugs (nach Eröffnungsdatum)
  293.         qryBugs.SQL.Text := 'SELECT * FROM bugs WHERE projekt = '+IntToStr(aktuellesProjekt)+' ORDER BY erstellt DESC';
  294.       end;
  295.   end;
  296.   qryBugs.Active := true;
  297. end;
  298.  
  299. procedure TfrmBugtracker.DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn);
  300. begin
  301.   if Button = nbCancel then
  302.   begin
  303.     if qryBugs.state  in [dsEdit,dsInsert] then
  304.     begin
  305.       // Tag=1 soll verhindern, dass nicht gefragt wird, ob man Speichern möchte.
  306.       // Ansonsten würde diese Meldung kommen, denn ".Cancel" wird automatisch
  307.       // bei Ereignissen wie z.B. dem Scrolling aufgerufen (noch bevor
  308.       // OnBeforeScroll aufgerufen wird), bei dem man einen MBOnCloseQuery wünscht.
  309.       qryBugs.Tag := 1;
  310.       qryBugs.Cancel;
  311.       qryBugs.Tag := 0;
  312.     end;
  313.   end;
  314. end;
  315.  
  316. procedure TfrmBugtracker.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  317. begin
  318.   qryBugs.Cancel;
  319. end;
  320.  
  321. procedure TfrmBugtracker.FormCreate(Sender: TObject);
  322. var
  323.   ini: TMemIniFile;
  324. begin
  325.   ini := TMemIniFile.Create('bugtracker.ini');
  326.   try
  327.     ADOConnection1.Connected := false;
  328.     ADOConnection1.ConnectionString := ini.ReadString('Database', 'ConnectionString', '');
  329.   finally
  330.     ini.Free;
  331.   end;
  332.  
  333.   ADOConnection1.Connected := true;
  334.   qryBugs.Active := true;
  335.   tblMitarbeiter.Active := true;
  336.   qryVersionen.Active := true;
  337.   tblProjekte.Active := true;
  338.   qryModule.Active := true;
  339.   lkpStatus.Active := true;
  340. end;
  341.  
  342. procedure TfrmBugtracker.Mitarbeiter1Click(Sender: TObject);
  343. begin
  344.   frmMitarbeiter.ShowModal;
  345. end;
  346.  
  347. procedure TfrmBugtracker.Module1Click(Sender: TObject);
  348. begin
  349.   frmModule.ShowModal;
  350. end;
  351.  
  352. procedure TfrmBugtracker.NeuFiltern;
  353. begin
  354.   ComboBox1Change(ComboBox1);
  355.  
  356.   qryModule.SQL.Text := 'SELECT * FROM module WHERE projekt = ' + IntToStr(aktuellesProjekt);
  357.   qryModule.Active := true;
  358.  
  359.   qryVersionen.SQL.Text := 'SELECT * FROM versionen WHERE projekt = ' + IntToStr(aktuellesProjekt);
  360.   qryVersionen.Active := true;
  361. end;
  362.  
  363. procedure TfrmBugtracker.NotizHinzufuegen(color: TColor; bez: string);
  364. var
  365.   leerzeilen: integer;
  366.   umbruch: string;
  367.   prefix: string;
  368. begin
  369.   if not (qryBugs.State in [dsEdit, dsInsert]) then qryBugs.Edit;
  370.  
  371.   // Endet der Text mit zwei Zeilenabständen? Wenn nein, dann einfügen.
  372.   if Trim(DBRichEdit1.Text) <> '' then
  373.   begin
  374.     leerzeilen := 0;
  375.     if Copy(DBRichEdit1.Text, 1+Length(DBRichEdit1.Text)-2, 2) = #13#10 then Inc(leerzeilen); // letzte Zeile
  376.     if Copy(DBRichEdit1.Text, 1+Length(DBRichEdit1.Text)-4, 2) = #13#10 then Inc(leerzeilen); // Vorletzte Zeile
  377.     case leerzeilen of
  378.       0: umbruch := #13#10#13#10;
  379.       1: umbruch := #13#10;
  380.       2: umbruch := '';
  381.     end;
  382.   end
  383.   else
  384.   begin
  385.     umbruch := '';
  386.   end;
  387.  
  388.   DBRichEdit1.SelStart := DBRichEdit1.GetTextLen;
  389.   DBRichEdit1.SelText := umbruch;
  390.  
  391.   DBRichEdit1.SelAttributes.Size := 13;
  392.   DBRichEdit1.SelAttributes.Color := color;
  393.   DBRichEdit1.SelAttributes.Style := [fsUnderline];
  394.   if Trim(bez) <> '' then
  395.     prefix := Trim(bez) + ' - '
  396.   else
  397.     prefix := '';
  398.   DBRichEdit1.SelText := prefix + eingeloggtMitarbeiterName + ' ' + FormatDateTime('dd.mm.yyyy hh:nn', Now); // DateTimeToStr(Now);
  399.  
  400.   DBRichEdit1.SelAttributes.Size := 10;
  401.   DBRichEdit1.SelAttributes.Color := clWindowText;
  402.   DBRichEdit1.SelAttributes.Style := [];
  403.   DBRichEdit1.SelText := #13#10 {+ '<Hier Text eingeben>'};
  404.  
  405.   // Ans Ende scrollen
  406.   DBRichEdit1.SetFocus;
  407.   DBRichEdit1.SelStart := DBRichEdit1.GetTextLen;
  408.   DBRichEdit1.Perform(EM_SCROLLCARET, 0, 0);
  409. end;
  410.  
  411. procedure TfrmBugtracker.Projekte1Click(Sender: TObject);
  412. begin
  413.   frmProjekte.ShowModal;
  414. end;
  415.  
  416. procedure TfrmBugtracker.Projektwechseln1Click(Sender: TObject);
  417. begin
  418.   frmLogin.ShowModal;
  419. end;
  420.  
  421. end.
  422.