MODULE WMPerfMonTabAlerts;
IMPORT
Kernel, Strings,
WMComponents, WMStandardComponents, WMGrids, WMStringGrids, WMGraphics, WMEditors, WMDialogs,
Perf := WMPerfMonComponents, Alerts := WMPerfMonAlerts;
CONST
PollingInterval = 500;
GridBgFillColor = 0646464FFH;
TYPE
CellData = POINTER TO RECORD
id : LONGINT;
END;
AlertsTab* = OBJECT(WMComponents.VisualComponent)
VAR
statusIndicator, statusLabel : WMStandardComponents.Label;
onOffBtn : WMStandardComponents.Button;
alertsGrid : WMStringGrids.StringGrid;
rulesGrid : WMStringGrids.StringGrid;
resetBtn, addBtn, removeBtn : WMStandardComponents.Button;
alertEdit : WMEditors.TextField;
saveBtn, loadBtn, appendBtn : WMStandardComponents.Button;
filenameEdit : WMEditors.TextField;
oldStatus, status : Alerts.Status;
filename : ARRAY 256 OF CHAR;
modified : BOOLEAN;
spacings : WMGrids.Spacings;
timer : Kernel.Timer;
dead, alive : BOOLEAN;
PROCEDURE HandleButtons(sender, data : ANY);
VAR string, msg : ARRAY 256 OF CHAR; nofRemoved, res : LONGINT;
BEGIN
IF sender = onOffBtn THEN
IF status.enabled THEN
Alerts.DisableAlerts;
ELSE
Alerts.EnableAlerts;
END;
ELSIF sender = resetBtn THEN
ResetSelectedAlerts;
ELSIF sender = addBtn THEN
alertEdit.GetAsString(string);
Alerts.AddByString(string, msg, res);
IF res # Alerts.Ok THEN
WMDialogs.Error("Error", msg);
ELSE
modified := TRUE;
END;
ELSIF sender = removeBtn THEN
nofRemoved := RemoveSelectedAlerts();
IF nofRemoved > 0 THEN modified := TRUE; END;
ELSIF (sender = loadBtn) OR (sender = appendBtn) THEN
filenameEdit.GetAsString(string);
Alerts.LoadRules(string, sender = appendBtn, msg, res);
IF res # Alerts.Ok THEN
WMDialogs.Error("Error", msg);
END;
ELSIF sender = saveBtn THEN
filenameEdit.GetAsString(string);
Alerts.StoreRules(string, msg, res);
IF res # Alerts.Ok THEN
WMDialogs.Error("Error", msg);
END;
END;
END HandleButtons;
PROCEDURE ResetSelectedAlerts;
VAR scol, srow, ecol, erow, row, res : LONGINT; ptr : ANY; cellData : CellData; msg : ARRAY 128 OF CHAR;
BEGIN
rulesGrid.Acquire;
rulesGrid.model.Acquire;
rulesGrid.GetSelection(scol, srow, ecol, erow);
IF (srow >= 1) & (erow >= 1) THEN
FOR row := srow TO erow DO
ptr := rulesGrid.model.GetCellData(0, row);
IF ptr # NIL THEN cellData := ptr (CellData); END;
IF cellData # NIL THEN
Alerts.SetStateByID(cellData.id, Alerts.Reset, msg, res);
END;
END;
END;
rulesGrid.model.Release;
rulesGrid.Release;
END ResetSelectedAlerts;
PROCEDURE RemoveSelectedAlerts() : LONGINT;
VAR scol, srow, ecol, erow, row : LONGINT; ptr : ANY; cellData : CellData; nofRemoved : LONGINT;
BEGIN
rulesGrid.Acquire;
rulesGrid.model.Acquire;
rulesGrid.GetSelection(scol, srow, ecol, erow);
IF (srow >= 1) & (erow >= 1) THEN
FOR row := srow TO erow DO
ptr := rulesGrid.model.GetCellData(0, row);
IF ptr # NIL THEN cellData := ptr (CellData); END;
IF cellData # NIL THEN
nofRemoved := nofRemoved + Alerts.RemoveAlertByID(cellData.id);
END;
END;
END;
rulesGrid.model.Release;
rulesGrid.Release;
RETURN nofRemoved;
END RemoveSelectedAlerts;
PROCEDURE Update;
BEGIN
status := Alerts.GetStatus();
IF status.stamp # oldStatus.stamp THEN
IF (status.filename # "") & (filename = "") THEN
COPY(status.filename, filename); modified := FALSE;
ELSE
IF status.filename # filename THEN modified := FALSE; END;
END;
UpdateStatusIndicator(status.enabled);
UpdateStatusLabel(status);
UpdateGrids;
oldStatus := status;
ELSIF modified THEN
UpdateStatusLabel(status);
END;
END Update;
PROCEDURE UpdateStatusIndicator(enabled : BOOLEAN);
BEGIN
IF enabled THEN
statusIndicator.fillColor.Set(WMGraphics.Green);
statusIndicator.caption.SetAOC("ON");
onOffBtn.caption.SetAOC("Disable");
ELSE
statusIndicator.fillColor.Set(WMGraphics.Red);
statusIndicator.caption.SetAOC("OFF");
onOffBtn.caption.SetAOC("Enable");
END;
END UpdateStatusIndicator;
PROCEDURE UpdateStatusLabel(status : Alerts.Status);
VAR nbr, caption : ARRAY 128 OF CHAR;
BEGIN
caption := " ";
Strings.IntToStr(status.nbrOfAlerts, nbr);
Strings.Append(caption, nbr);
Strings.Append(caption, " alerts, ");
Strings.IntToStr(status.nbrOfRules, nbr);
Strings.Append(caption, nbr);
Strings.Append(caption, " rules loaded");
IF status.filename # "" THEN
Strings.Append(caption, " from file "); Strings.Append(caption, status.filename);
IF modified THEN Strings.Append(caption, " (modified)"); END;
END;
Strings.Append(caption, ".");
statusLabel.caption.SetAOC(caption);
END UpdateStatusLabel;
PROCEDURE ComputeAlertInfo(alerts : Alerts.Alerts; VAR nbrOfRules, nbrOfAlerts : LONGINT);
VAR i : LONGINT;
BEGIN
nbrOfRules := 0; nbrOfAlerts := 0;
IF alerts # NIL THEN
FOR i := 0 TO LEN(alerts)-1 DO
INC(nbrOfRules);
IF alerts[i].state = Alerts.Triggered THEN
INC(nbrOfAlerts);
END;
END;
END;
END ComputeAlertInfo;
PROCEDURE SetRowText(grid : WMStringGrids.StringGrid; alert : Alerts.AlertInfo; row : LONGINT);
VAR caption : ARRAY 128 OF CHAR; col : LONGINT; cellData : CellData;
BEGIN
NEW(cellData); cellData.id := alert.id;
grid.model.SetCellData(0, row, cellData);
grid.model.SetTextAlign(0, row, WMGraphics.AlignCenter);
grid.model.SetTextAlign(4, row, WMGraphics.AlignCenter);
FOR col := 0 TO 4 DO
CASE col OF
|0: Alerts.GetStateString(alert.state, caption);
|1: Alerts.GetTypeString(alert.type, caption);
|2: Alerts.GetFullTriggerString(alert, caption);
|3: Strings.FloatToStr(alert.violation, 4, 2, 0, caption);
|4: Strings.IntToStr(alert.nbrOfViolations, caption);
ELSE
END;
grid.model.SetCellText(col, row, Strings.NewString(caption));
END;
END SetRowText;
PROCEDURE UpdateGrids;
VAR
gridRow, alertsGridRow : LONGINT; alerts : Alerts.Alerts;
nbrOfRules, nbrOfAlerts : LONGINT;
i : LONGINT;
BEGIN
alerts := Alerts.GetAlerts();
ComputeAlertInfo(alerts, nbrOfRules, nbrOfAlerts);
rulesGrid.Acquire;
rulesGrid.model.Acquire;
alertsGrid.Acquire;
alertsGrid.model.Acquire;
IF alerts # NIL THEN
rulesGrid.model.SetNofRows(nbrOfRules + 1); gridRow := 1;
alertsGrid.model.SetNofRows(nbrOfAlerts + 1); alertsGridRow := 1;
FOR i := 0 TO LEN(alerts)-1 DO
IF alerts[i].state = Alerts.Triggered THEN
SetRowText(alertsGrid, alerts[i], alertsGridRow);
INC(alertsGridRow);
END;
SetRowText(rulesGrid, alerts[i], gridRow);
INC(gridRow);
END;
ELSE
rulesGrid.model.SetNofRows(1);
alertsGrid.model.SetNofRows(1);
END;
alertsGrid.model.Release;
alertsGrid.Release;
rulesGrid.model.Release;
rulesGrid.Release;
END UpdateGrids;
PROCEDURE NewGrid() : WMStringGrids.StringGrid;
VAR grid : WMStringGrids.StringGrid;
BEGIN
NEW(grid);
grid.fixedRows.Set(1);
grid.fillColor.Set(GridBgFillColor);
grid.alignment.Set(WMComponents.AlignTop);
grid.SetSelectionMode(WMGrids.GridSelectRows);
grid.SetSelection(-1, -1, -1, -1);
grid.alwaysShowScrollX.Set(FALSE); grid.showScrollX.Set(TRUE);
grid.alwaysShowScrollY.Set(FALSE); grid.showScrollY.Set(TRUE);
grid.allowColResize.Set(TRUE); grid.allowRowResize.Set(FALSE);
grid.adjustFocusPosition.Set(FALSE);
NEW(spacings, 5);
spacings[0] := 40; spacings[1] := 80; spacings[2] := 480; spacings[3] := 50; spacings[4] := 70;
grid.Acquire;
grid.model.Acquire;
grid.model.SetNofCols(5); grid.SetColSpacings(spacings);
grid.model.SetNofRows(1);
grid.model.SetCellText(0, 0, Strings.NewString("Status")); grid.model.SetTextAlign(0, 0, WMGraphics.AlignCenter);
grid.model.SetCellText(1, 0, Strings.NewString("Type"));
grid.model.SetCellText(2, 0, Strings.NewString("Trigger"));
grid.model.SetCellText(3, 0, Strings.NewString("Violation"));
grid.model.SetCellText(4, 0, Strings.NewString("NbrOfAlerts"));
grid.model.Release;
grid.Release;
RETURN grid;
END NewGrid;
PROCEDURE CreateStatusPanel() : WMStandardComponents.GroupPanel;
VAR panel : WMStandardComponents.GroupPanel;
BEGIN
panel := Perf.NewGroupPanel("Status", WMComponents.AlignTop, 45);
statusIndicator := Perf.NewLabel("", WMComponents.AlignLeft, 80, 0);
statusIndicator.alignH.Set(WMGraphics.AlignCenter); statusIndicator.alignV.Set(WMGraphics.AlignCenter);
panel.AddContent(statusIndicator);
onOffBtn := Perf.NewButton("", HandleButtons); panel.AddContent(onOffBtn);
statusLabel := Perf.NewLabel("", WMComponents.AlignClient, 0, 0); panel.AddContent(statusLabel);
RETURN panel;
END CreateStatusPanel;
PROCEDURE CreateAlertsPanel() : WMStandardComponents.GroupPanel;
VAR panel : WMStandardComponents.GroupPanel;
BEGIN
panel := Perf.NewGroupPanel("Alerts", WMComponents.AlignTop, 100);
alertsGrid := NewGrid(); alertsGrid.bounds.SetHeight(100); alertsGrid.SetSelectionMode(WMGrids.GridSelectNone);
panel.AddContent(alertsGrid);
RETURN panel;
END CreateAlertsPanel;
PROCEDURE CreateRulesPanel() : WMStandardComponents.GroupPanel;
VAR panel : WMStandardComponents.GroupPanel; line : WMStandardComponents.Panel;
BEGIN
panel := Perf.NewGroupPanel("Rules", WMComponents.AlignTop, 180);
line := Perf.NewPanel(WMComponents.AlignBottom, 0, Perf.LineHeight); panel.AddContent(line);
resetBtn := Perf.NewButton("Reset", HandleButtons); line.AddContent(resetBtn);
removeBtn := Perf.NewButton("Remove", HandleButtons); line.AddContent(removeBtn);
addBtn := Perf.NewButton("Add", HandleButtons); line.AddContent(addBtn);
alertEdit := Perf.NewTextField(0); alertEdit.alignment.Set(WMComponents.AlignClient); line.AddContent(alertEdit);
alertEdit.SetAsString("PluginName.ValueName sticky|singleshot|multishot trigger value1 value2 onAlertCmd onLeaveCmd");
rulesGrid := NewGrid(); rulesGrid.alignment.Set(WMComponents.AlignClient);
panel.AddContent(rulesGrid);
RETURN panel;
END CreateRulesPanel;
PROCEDURE CreateRulefilesPanel() : WMStandardComponents.GroupPanel;
VAR panel : WMStandardComponents.GroupPanel;
BEGIN
panel := Perf.NewGroupPanel("Rule files", WMComponents.AlignTop, 45);
loadBtn := Perf.NewButton("Load", HandleButtons); panel.AddContent(loadBtn);
appendBtn := Perf.NewButton("Append", HandleButtons); panel.AddContent(appendBtn);
saveBtn := Perf.NewButton("Store", HandleButtons); panel.AddContent(saveBtn);
filenameEdit := Perf.NewTextField(0); filenameEdit.alignment.Set(WMComponents.AlignClient); panel.AddContent(filenameEdit);
RETURN panel;
END CreateRulefilesPanel;
PROCEDURE Finalize*;
BEGIN
alive := FALSE;
timer.Wakeup;
BEGIN {EXCLUSIVE} AWAIT(dead); END;
Finalize^;
END Finalize;
PROCEDURE &Init*;
VAR panel : WMStandardComponents.Panel;
BEGIN
Init^;
SetNameAsString(StrAlertsTab);
NEW(timer);
alive := TRUE; dead := FALSE;
AddContent(CreateStatusPanel());
AddContent(CreateRulefilesPanel());
AddContent(CreateAlertsPanel());
panel := CreateRulesPanel(); panel.alignment.Set(WMComponents.AlignClient);
AddContent(panel);
END Init;
BEGIN {ACTIVE}
WHILE alive DO
Update;
timer.Sleep(PollingInterval);
END;
BEGIN {EXCLUSIVE} dead := TRUE; END;
END AlertsTab;
VAR
StrAlertsTab : Strings.String;
BEGIN
StrAlertsTab := Strings.NewString("AlertsTab");
END WMPerfMonTabAlerts.