Subversion Repositories winbugtracker

Rev

Rev 7 | Rev 11 | 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.  * - verbinden mit ticketsystem von HS
  9.  * - rtf controls?
  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)
  17.  *
  18.  * NOT INCLUDED:
  19.  * - duplicate of
  20.  *
  21.  * FUTURE:
  22.  * - HS Info integration
  23.  *)
  24.  
  25. interface
  26.  
  27. uses
  28.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  29.   Dialogs, WideStrings, DB, SqlExpr, StdCtrls, ExtCtrls, DBCtrls,
  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;
  89.     LblAngemeldet: TLabel;
  90.     Label7: TLabel;
  91.     Label8: TLabel;
  92.     DBLookupComboBox4: TDBLookupComboBox;
  93.     qryBugserfasser: TIntegerField;
  94.     qryBugsversion_agenda: TIntegerField;
  95.     Label9: TLabel;
  96.     cbxErfasser: TDBLookupComboBox;
  97.     Label10: TLabel;
  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);
  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.   public
  119.     eingeloggtMitarbeiter: integer;
  120.     eingeloggtMitarbeiterName: string;
  121.     aktuellesProjekt: integer;
  122.     aktuellesProjektName: string;
  123.     procedure NeuFiltern;
  124.     procedure NotizHinzufuegen(color: TColor; bez: string);
  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
  139.   qryBugs.FieldByName('wichtigkeit').AsInteger := 5; // Mitte
  140.   qryBugs.FieldByName('erstellt').AsDateTime := Now;
  141.   qryBugs.FieldByName('erfasser').AsInteger := eingeloggtMitarbeiter;
  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.  
  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.  
  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.  
  226. procedure TfrmBugtracker.btnBearbeitungsnotizClick(Sender: TObject);
  227. begin
  228.   NotizHinzufuegen(clRed, 'Notiz');
  229. end;
  230.  
  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
  235.   begin
  236.     qryBugs.FieldByName('fixdatum').AsDateTime := Now;
  237.     NotizHinzufuegen(clGreen, 'Gefixt');
  238.   end
  239.   else
  240.   begin
  241.     qryBugs.FieldByName('fixdatum').Clear;
  242.     NotizHinzufuegen(clBlue, 'Neu eröffnet');
  243.   end;
  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.  
  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.  
  300. procedure TfrmBugtracker.FormCreate(Sender: TObject);
  301. var
  302.   ini: TMemIniFile;
  303. begin
  304.   ini := TMemIniFile.Create('bugtracker.ini');
  305.   try
  306.     ADOConnection1.Connected := false;
  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.  
  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.  
  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.
  393.