Subversion Repositories winbugtracker

Rev

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