MyTracker events

Event is a small pascal program which is hooked on certain myTracker event. Currently supports myTracker 9 events (OnCanDelete, OnCanEdit, OnCreateIssue, OnFormShow, OnFormClosing, OnGetStylesheet, OnShowIssueReference, OnInitFormControls, OnChangeEditorValue). The first is fired before myTracker deletes an issue, the second before mytracker edit an issue, the third allows you set the default content of issue, the 4th allows you to adjust the issue content before the dialog opens and (or) choose the appropriate dialog for the issue, the 5th allows you to check you the issue consistency after the dialog closes, the 6th allows you to specify a stylesheet for each issue this event fires when an issue becomes the focus and the last event allows you to specify which issues should have see which issue references. Don't you understand; read bellow ;-)

The code above does the following

01.Begin - Indicates the start of the event handler
02.  if NEWISSUE then - test if the NEWISSUE variable has a true value
03.    case FORMID of- depending on FORMID make one of following assignment
04       1: ISSUETYPE := 71;- sets ISSUTYPE to 71 when FORMID =1
05.      2: ISSUETYPE := 72;- sets ISSUTYPE to 72 when FORMID =1
05.      3: ISSUETYPE := 73;- sets ISSUTYPE to 73 when FORMID =1
06.      4: ISSUETYPE := 74;- sets ISSUTYPE to 74 when FORMID =1
07.      5: ISSUETYPE := 75;- sets ISSUTYPE to 75 when FORMID =1
08.      6: ISSUETYPE := 76;- sets ISSUTYPE to 75 when FORMID =1
09.      7: ISSUETYPE := 77;- sets ISSUTYPE to 77 when FORMID =1
10.    end- Indicates the end of case statement
11.  else- if the NEWISSUE variable has a false value proceed the statement after else
12.    case ISSUETYPE of- depending on ISSUETYPE make one of following assignment
13.      71: FORMID := 1;- sets FORMID to 1 when ISSUETYPE =71
14.      72: FORMID := 2;- sets FORMID to 2 when ISSUETYPE =72
15.      73: FORMID := 3;- sets FORMID to 3 when ISSUETYPE =73
16.      74: FORMID := 4;- sets FORMID to 4 when ISSUETYPE =74
17.      75: FORMID := 5;- sets FORMID to 5 when ISSUETYPE =75
18.      76: FORMID := 6;- sets FORMID to 6 when ISSUETYPE =76
19.      77: FORMID := 7;- sets FORMID to 7 when ISSUETYPE =77
20.    end;- Indicates the end of case statement
21.end.- Indicates the end of the event handler

And now in spoken language the OnFormShow event is fired before a new issue (NEWISSUE=True) will be edited or a existend issue will be editing (NEWISSUE=True). The sample comes from the tutorial where we defined a ISSUTYPE issue field which is not visible on any form and it stores only the type of issue. In first part of event we set the issue type depending on actual form's ID in the else part we already have an issue and we select the form depending on issue type. The question is why we need the else part? It is simple some queries deliver heterogenou results eg. several issue types. In such cases it is not enough to have one default query dialog, while each issue can have an different type. So the event decides what form should be used.

How myTracker selects the dialog?

  1. The user can select one dialog. It works always.
  2. If the selected query has a default dialog it is taken.
  3. Now we have a form ID from step 1 or 2
  4. Now goes the form ID as a FormID parameter to the OnFormShow if the event modifies the FormID variable it will be used. If you want to forbid the edition (addition) set the FormID to -1.


For example you could add a new issue type Meeting (ID=123) and a new issue field Place. Now you would like test if the Meeting has a place selected. If no, you would like to show a message like "Please select a meeting place!". After that message shows can the user correct the data.

  if (ISSUETYPE=123) and (PLACE=0) then
    ERRORMSG := 'Please select a meeting place!';

The OnCanDelete and OnCanEdit events support the fine tuned activity tuning. You can on issue level disable for example the deleting of closed bugs or what ever you need. Set the CanDelete or CanEdit variables in the events.

Events flow by creating an issue

  1. OnCreateIssue
  2. OnFormShow
  3. OnInitFormControls
  4. OnChangeEditorValue
  5. OnFormClosing
  6. OnGetStylesheet
  7. OnShowIssueReference


This event allows you to manage the forms controls before the form will be shown. You can use it to fine control the visibility of fields. If you want to have a form with lot of controls but only the superadmin should be able to edit some "superadminnotes" field you could use the EnableControl/DisabbleControl. If you would to hide/show the field use HideControl/ShowControl.

  if IsInGroup(LOGGEDUSER, 2) then


This event allows you to manage the forms controls when the user change some value. It works good if you want to show for example additional information box for High priority issues. And this change is made while editing the issue.

List of in events and one-clicks supported delphi functions:

function IsInGroup(UserID, UsersGropID): Boolean;
procedure ShowMessage( const Msg : string);
function InputBox(const ACaption, APrompt, ADefault: string): string;
procedure HideControl(IssueFieldName: string);
procedure HideControlByID(IssueField: Integer);
procedure ShowControl(IssueFieldName: string);
procedure ShowControlByID(IssueField: Integer);
procedure DisableControlByID(IssueField: Integer);
procedure DisableControl(IssueFieldName: string);
procedure EnableControlByID(IssueField: Integer);
procedure EnsableControl(IssueFieldName: string);
procedure ExcludeElements(IssueField: string; Elements: string); -elements are semicolon separated IDs as '1;2;'
procedure RestoreAllElements(IssueField: string);
function EncodeDate(Year, Month, Day: Word): TDateTime;
function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;
function TryEncodeDate(Year, Month, Day: Word; out Date: TDateTime): Boolean;
function TryEncodeTime(Hour, Min, Sec, MSec: Word; out Time: TDateTime): Boolean;
procedure DecodeDate(const DateTime: TDateTime; var Year, Month, Day: Word);
procedure DecodeTime(const DateTime: TDateTime; var Hour, Min, Sec, MSec: Word);
function DayOfWeek(const DateTime: TDateTime): Word;
function Date: TDateTime;
function Time: TDateTime;
function Now: TDateTime;
function DateTimeToUnix(D: TDateTime): Int64;
function UnixToDateTime(U: Int64): TDateTime;
function DateToStr(D: TDateTime): string;
function StrToDate(const s: string): TDateTime;
function FormatDateTime(const fmt: string; D: TDateTime): string;

Others are:

Q:Why must every event have the begin end. Construct. Could I omit it?

A: No! The myTracker allows you to declare your own variables and function if you need a complex logic. You can write such code.

  I : Integer;
  I := 10;
  I := I * I;

It will work and show a dialog with 100! The lection is: myTracker has no debugger but you can user Showmessage to track the values.

See also:
Examples in tutorial