Skip to content

Commit

Permalink
Merge pull request #2064 from ControlSystemStudio/alarm_table_column_…
Browse files Browse the repository at this point in the history
…order_pref

Alarm table column order pref
  • Loading branch information
kasemir authored Nov 19, 2021
2 parents 8c69622 + 6afd4a8 commit f43aa27
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ public class AlarmSystem
/** Limit for the number of context menu items */
@Preference public static int alarm_menu_max_items;

/** Alarm table columns */
@Preference public static String[] alarm_table_columns;

/** Use background color to indicate alarm severity? Default: Text color */
@Preference public static boolean alarm_table_color_background;

/** Alarm table row limit */
@Preference public static int alarm_table_max_rows;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ alarm_area_font_size=15
# 'display' and 'command' menu entries.
alarm_menu_max_items=10

# Order of columns in alarm table
# Allows re-ordering as well as omitting columns
alarm_table_columns=Icon, PV, Description, Alarm Severity, Alarm Status, Alarm Time, Alarm Value, PV Severity, PV Status

# Use background color to indicate alarm severity? Default: Text color
alarm_table_color_background=false

# Alarm table row limit
# If there are more rows, they're suppressed
alarm_table_max_rows=2500
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018-2020 Oak Ridge National Laboratory.
* Copyright (c) 2018-2021 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -57,6 +57,19 @@ public class AlarmUI
ImageCache.getImage(AlarmUI.class, "/icons/undefined.png")
};

private static final Background[] severity_backgrounds = new Background[]
{
null, // OK
new Background(new BackgroundFill(Color.rgb(180, 170, 70), CornerRadii.EMPTY, Insets.EMPTY)), // MINOR_ACK
new Background(new BackgroundFill(Color.rgb(255, 90, 90), CornerRadii.EMPTY, Insets.EMPTY)), // MAJOR_ACK
new Background(new BackgroundFill(Color.rgb(255, 128, 255), CornerRadii.EMPTY, Insets.EMPTY)), // INVALID_ACK
new Background(new BackgroundFill(Color.rgb(255, 128, 255), CornerRadii.EMPTY, Insets.EMPTY)), // UNDEFINED_ACK
new Background(new BackgroundFill(Color.rgb(207, 192, 0), CornerRadii.EMPTY, Insets.EMPTY)), // MINOR
new Background(new BackgroundFill(Color.rgb(255, 0, 0), CornerRadii.EMPTY, Insets.EMPTY)), // MAJOR
new Background(new BackgroundFill(Color.rgb(255, 0, 255), CornerRadii.EMPTY, Insets.EMPTY)), // INVALID
new Background(new BackgroundFill(Color.rgb(255, 0, 255), CornerRadii.EMPTY, Insets.EMPTY)), // UNDEFINED
};

public static final Image disabled_icon = ImageCache.getImage(AlarmUI.class, "/icons/disabled.png");

/** @param severity {@link SeverityLevel}
Expand All @@ -76,6 +89,14 @@ public static Image getIcon(final SeverityLevel severity)
return severity_icons[severity.ordinal()];
}

/** @param severity {@link SeverityLevel}
* @return Background, may be <code>null</code>
*/
public static Background getBackground(final SeverityLevel severity)
{
return severity_backgrounds[severity.ordinal()];
}

/** Verify authorization, qualified by model's current config
* @param model Alarm client model
* @param auto Authorization name
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,46 @@
/*******************************************************************************
* Copyright (c) 2018-2020 Oak Ridge National Laboratory.
* Copyright (c) 2018-2021 Oak Ridge National Laboratory.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.phoebus.applications.alarm.ui.table;

import static org.phoebus.applications.alarm.AlarmSystem.logger;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.regex.Pattern;

import org.phoebus.applications.alarm.AlarmSystem;
import org.phoebus.applications.alarm.client.AlarmClient;
import org.phoebus.applications.alarm.model.AlarmTreeItem;
import org.phoebus.applications.alarm.model.SeverityLevel;
import org.phoebus.applications.alarm.ui.AlarmContextMenuHelper;
import org.phoebus.applications.alarm.ui.AlarmUI;
import org.phoebus.applications.alarm.ui.tree.ConfigureComponentAction;
import org.phoebus.framework.jobs.JobManager;
import org.phoebus.framework.persistence.Memento;
import org.phoebus.framework.selection.Selection;
import org.phoebus.framework.selection.SelectionService;
import org.phoebus.ui.application.ContextMenuService;
import org.phoebus.ui.application.SaveSnapshotAction;
import org.phoebus.ui.javafx.ClearingTextField;
import org.phoebus.ui.javafx.ImageCache;
import org.phoebus.ui.javafx.PrintAction;
import org.phoebus.ui.javafx.Screenshot;
import org.phoebus.ui.javafx.ToolbarHelper;
import org.phoebus.ui.selection.AppSelection;
import org.phoebus.ui.spi.ContextMenuEntry;
import org.phoebus.ui.text.RegExHelper;
import org.phoebus.util.text.CompareNatural;
import org.phoebus.util.time.TimestampFormats;

import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
Expand Down Expand Up @@ -37,38 +71,7 @@
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import org.phoebus.applications.alarm.AlarmSystem;
import org.phoebus.applications.alarm.client.AlarmClient;
import org.phoebus.applications.alarm.model.AlarmTreeItem;
import org.phoebus.applications.alarm.model.SeverityLevel;
import org.phoebus.applications.alarm.ui.AlarmContextMenuHelper;
import org.phoebus.applications.alarm.ui.AlarmUI;
import org.phoebus.applications.alarm.ui.tree.ConfigureComponentAction;
import org.phoebus.framework.jobs.JobManager;
import org.phoebus.framework.persistence.Memento;
import org.phoebus.framework.selection.Selection;
import org.phoebus.framework.selection.SelectionService;
import org.phoebus.ui.application.ContextMenuService;
import org.phoebus.ui.application.SaveSnapshotAction;
import org.phoebus.ui.javafx.ClearingTextField;
import org.phoebus.ui.javafx.ImageCache;
import org.phoebus.ui.javafx.PrintAction;
import org.phoebus.ui.javafx.Screenshot;
import org.phoebus.ui.javafx.ToolbarHelper;
import org.phoebus.ui.selection.AppSelection;
import org.phoebus.ui.spi.ContextMenuEntry;
import org.phoebus.ui.text.RegExHelper;
import org.phoebus.util.text.CompareNatural;
import org.phoebus.util.time.TimestampFormats;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.regex.Pattern;

import static org.phoebus.applications.alarm.AlarmSystem.logger;
/** Alarm Table UI
*
* <p>Show list of active and acknowledged alarms.
Expand Down Expand Up @@ -196,12 +199,18 @@ protected void updateItem(final SeverityLevel item, final boolean empty)
if (empty || item == null)
{
setText("");
setTextFill(Color.BLACK);
if (AlarmSystem.alarm_table_color_background)
setBackground(null);
else
setTextFill(Color.BLACK);
}
else
{
setText(item.toString());
setTextFill(AlarmUI.getColor(item));
if (AlarmSystem.alarm_table_color_background)
setBackground(AlarmUI.getBackground(item));
else
setTextFill(AlarmUI.getColor(item));
}
}
}
Expand Down Expand Up @@ -365,71 +374,91 @@ private TableView<AlarmInfoRow> createTable(final ObservableList<AlarmInfoRow> r
// of the TableView is changed by the user clicking on table headers.
sorted.comparatorProperty().bind(table.comparatorProperty());

// Prepare columns.
final List<TableColumn<AlarmInfoRow, ?>> cols = new ArrayList<>();
TableColumn<AlarmInfoRow, SeverityLevel> sevcol = new TableColumn<>(/* Icon */);
sevcol.setPrefWidth(25);
sevcol.setReorderable(false);
sevcol.setResizable(false);
sevcol.setCellValueFactory(cell -> cell.getValue().severity);
sevcol.setCellFactory(c -> new SeverityIconCell());
table.getColumns().add(sevcol);
cols.add(sevcol);

final TableColumn<AlarmInfoRow, String> pv_col = new TableColumn<>("PV");
pv_col.setPrefWidth(240);
pv_col.setReorderable(false);
pv_col.setCellValueFactory(cell -> cell.getValue().pv);
pv_col.setCellFactory(c -> new DragPVCell());
pv_col.setComparator(CompareNatural.INSTANCE);
table.getColumns().add(pv_col);
cols.add(pv_col);

TableColumn<AlarmInfoRow, String> col = new TableColumn<>("Description");
col.setPrefWidth(400);
col.setReorderable(false);
col.setCellValueFactory(cell -> cell.getValue().description);
col.setCellFactory(c -> new DragPVCell());
col.setComparator(CompareNatural.INSTANCE);
table.getColumns().add(col);
cols.add(col);

sevcol = new TableColumn<>("Alarm Severity");
sevcol.setPrefWidth(130);
sevcol.setReorderable(false);
sevcol.setCellValueFactory(cell -> cell.getValue().severity);
sevcol.setCellFactory(c -> new SeverityLevelCell());
table.getColumns().add(sevcol);
cols.add(sevcol);

col = new TableColumn<>("Alarm Status");
col.setPrefWidth(130);
col.setReorderable(false);
col.setCellValueFactory(cell -> cell.getValue().status);
col.setCellFactory(c -> new DragPVCell());
table.getColumns().add(col);
cols.add(col);

TableColumn<AlarmInfoRow, Instant> timecol = new TableColumn<>("Alarm Time");
timecol.setPrefWidth(200);
timecol.setReorderable(false);
timecol.setCellValueFactory(cell -> cell.getValue().time);
timecol.setCellFactory(c -> new TimeCell());
table.getColumns().add(timecol);
cols.add(timecol);

col = new TableColumn<>("Alarm Value");
col.setPrefWidth(100);
col.setReorderable(false);
col.setCellValueFactory(cell -> cell.getValue().value);
col.setCellFactory(c -> new DragPVCell());
table.getColumns().add(col);
cols.add(col);

sevcol = new TableColumn<>("PV Severity");
sevcol.setPrefWidth(130);
sevcol.setReorderable(false);
sevcol.setCellValueFactory(cell -> cell.getValue().pv_severity);
sevcol.setCellFactory(c -> new SeverityLevelCell());
table.getColumns().add(sevcol);
cols.add(sevcol);

col = new TableColumn<>("PV Status");
col.setPrefWidth(130);
col.setReorderable(false);
col.setCellValueFactory(cell -> cell.getValue().pv_status);
col.setCellFactory(c -> new DragPVCell());
table.getColumns().add(col);
cols.add(col);

// Each column is non-reorderable at runtime to avoid operator surprises.
// Sites can customize the order via preferences
for (String header : AlarmSystem.alarm_table_columns)
{
// "Icon" is used for the nameless icon column.
// Other column names used in pref must match header.
final String actual_header = header.equals("Icon")
? ""
: header;
final Optional<TableColumn<AlarmInfoRow, ?>> to_add =
cols.stream()
.filter(c -> actual_header.equals(c.getText()))
.findFirst();
if (to_add.isPresent())
table.getColumns().add(to_add.get());
else
logger.log(Level.WARNING, "Unknown Alarm Table column '" + header + "'");
}

// Initially, sort on PV name
// - restore(Memento) might change that
Expand Down

0 comments on commit f43aa27

Please sign in to comment.