Skip to content

Commit dd813fc

Browse files
authored
Merge pull request #3228 from katysaintin/master
Fix issue in app-pvtable for PV that contains dot in the name the last part of the name is removed
2 parents 8a7f24a + c3ab02a commit dd813fc

File tree

6 files changed

+132
-33
lines changed

6 files changed

+132
-33
lines changed

app/pvtable/src/main/java/org/phoebus/applications/pvtable/model/PVTableItem.java

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import org.epics.vtype.Alarm;
1919
import org.epics.vtype.AlarmSeverity;
2020
import org.epics.vtype.AlarmStatus;
21+
import org.epics.vtype.Display;
22+
import org.epics.vtype.DisplayProvider;
2123
import org.epics.vtype.Time;
2224
import org.epics.vtype.VByteArray;
2325
import org.epics.vtype.VEnum;
@@ -30,6 +32,7 @@
3032
import org.phoebus.core.vtypes.VTypeHelper;
3133
import org.phoebus.pv.PV;
3234
import org.phoebus.pv.PVPool;
35+
import org.phoebus.pv.PVPool.TypedName;
3336

3437
import io.reactivex.rxjava3.disposables.Disposable;
3538

@@ -51,7 +54,8 @@ public class PVTableItem
5154
private volatile VType value;
5255

5356
/** Value of the PV's description */
54-
private volatile String desc_value = "";
57+
private volatile String desc_value = null;
58+
private volatile String desc_name = "";
5559

5660
/** Saved (snapshot) value */
5761
private volatile Optional<SavedValue> saved = Optional.empty();
@@ -77,6 +81,9 @@ public class PVTableItem
7781

7882
/** Listener to description PV */
7983
private volatile Disposable desc_flow;
84+
85+
private static final String DESC_FIELD = "DESC";
86+
private static final String DOT = ".";
8087

8188
/** Initialize
8289
*
@@ -122,16 +129,24 @@ private void createPVs(final String name)
122129
updateValue(null);
123130
return;
124131
}
132+
PV new_pv = null;
125133
try
126134
{
127135
updateValue(VString.of("", Alarm.disconnected(), Time.now()));
128-
final PV new_pv = PVPool.getPV(name);
136+
new_pv = PVPool.getPV(name);
129137
value_flow = new_pv.onValueEvent()
130138
.throttleLatest(Settings.max_update_period_ms, TimeUnit.MILLISECONDS)
131139
.subscribe(this::updateValue);
132140
permission_flow = new_pv.onAccessRightsEvent()
133141
.subscribe(writable -> listener.tableItemChanged(PVTableItem.this));
134142
pv.set(new_pv);
143+
// read the value for getting description
144+
if (new_pv != null) {
145+
VType newVal = new_pv.read();
146+
if(newVal != null){
147+
updateValue(newVal);
148+
}
149+
}
135150
}
136151
catch (Exception ex)
137152
{
@@ -141,19 +156,25 @@ private void createPVs(final String name)
141156
Time.now()));
142157
}
143158

144-
// For CA PVs, check the .DESC field
145-
// Hardcoded knowledge to avoid non-record PVs.
146-
if (Settings.show_description &&
147-
! (name.startsWith("sim:") ||
148-
name.startsWith("loc:")))
149-
{
150-
// Determine DESC field.
151-
// If name already includes a field,
152-
// replace it with DESC field.
153-
final int sep = name.lastIndexOf('.');
154-
final String desc_name = sep >= 0
155-
? name.substring(0, sep) + ".DESC"
156-
: name + ".DESC";
159+
// First try to get description from value or pv
160+
updateDescription();
161+
// If still no description found and channel access source
162+
final TypedName type_name = TypedName.analyze(name);
163+
String dataType = type_name != null ? type_name.type : null;
164+
boolean channelAccess = dataType.equals("ca");
165+
if (Settings.show_description && desc_value == null && channelAccess) {
166+
// For CA PVs, check the .DESC field
167+
// Hardcoded knowledge to avoid non-record PVs.
168+
// First get default datasource
169+
desc_name = name + DOT + DESC_FIELD; // by default add .DESC
170+
if (!name.endsWith(DOT + DESC_FIELD) && name.contains(DOT)) {
171+
final int sep = name.lastIndexOf('.');
172+
String fieldVal = name.substring(sep + 1);
173+
// then replace by .DESC
174+
// Determine DESC field include dot in case of variable name such as variableEGUName
175+
desc_name = name.replace(DOT + fieldVal, DOT + DESC_FIELD);
176+
}
177+
157178
try
158179
{
159180
final PV new_desc_pv = PVPool.getPV(desc_name);
@@ -175,6 +196,27 @@ private void createPVs(final String name)
175196
}
176197
}
177198
}
199+
200+
private void updateDescription() {
201+
if(desc_value == null) {
202+
//update description from value or pv
203+
VType currentValue = getValue();
204+
if(currentValue != null) {
205+
PV thePV = pv.get();
206+
// DisplayProvider is an optional interface for VType values,
207+
// not PVs, but the custum datasource as Muscade happens to implement
208+
// DisplayProvider for enum and bool PVs, so check for that here
209+
Display display = thePV instanceof DisplayProvider ? ((DisplayProvider) thePV).getDisplay() : null;
210+
display = display == null && currentValue instanceof DisplayProvider ? ((DisplayProvider) currentValue).getDisplay(): display;
211+
if (display != null) {
212+
String description = display.getDescription();
213+
desc_value = description != null ? description : null;
214+
desc_name = desc_value != null ? "Description of " + name + " PV" : "no description";
215+
desc_flow = value_flow;
216+
}
217+
}
218+
}
219+
}
178220

179221
/** @return <code>true</code> if item is selected to be restored */
180222
public boolean isSelected()
@@ -240,9 +282,13 @@ public VType getValue()
240282
}
241283

242284
/** @return Description */
243-
public String getDescription()
244-
{
245-
return desc_value;
285+
public String getDescription() {
286+
return desc_value == null ? "" : desc_value;
287+
}
288+
289+
/** @return description pv name **/
290+
public String getDescriptionName() {
291+
return desc_name;
246292
}
247293

248294
/** @return Enum options for current value, <code>null</code> if not enumerated */
@@ -285,14 +331,17 @@ public void setValue(String new_value)
285331
throw new Exception("Not connected");
286332

287333
final VType pv_type = the_pv.read();
288-
if (pv_type instanceof VNumber)
289-
{
290-
if (Settings.show_units)
291-
{ // Strip units so that only the number gets written
292-
final String units = ((VNumber)pv_type).getDisplay().getUnit();
293-
if (units.length() > 0 && new_value.endsWith(units))
334+
Display display = the_pv instanceof DisplayProvider ? ((DisplayProvider) the_pv).getDisplay() : null;
335+
display = display == null && pv_type instanceof DisplayProvider ? ((DisplayProvider) pv_type).getDisplay():null;
336+
337+
if (display != null && Settings.show_units) {
338+
// Strip units so that only the number gets written
339+
final String units = display.getUnit();
340+
if (units.length() > 0 && new_value.endsWith(units))
294341
new_value = new_value.substring(0, new_value.length() - units.length()).trim();
295342
}
343+
if (pv_type instanceof VNumber)
344+
{
296345
the_pv.write(Double.parseDouble(new_value));
297346
}
298347
else if (pv_type instanceof VEnum)

app/pvtable/src/main/java/org/phoebus/applications/pvtable/ui/Messages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class Messages
1414
{
1515
/** Externalized strings */
1616
public static String Alarm,
17+
AddPVList,
1718
Description,
1819
CheckAll,
1920
CheckAll_TT,

app/pvtable/src/main/java/org/phoebus/applications/pvtable/ui/PVTable.java

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@
6969
import javafx.scene.control.TableRow;
7070
import javafx.scene.control.TableView;
7171
import javafx.scene.control.TableView.TableViewSelectionModel;
72+
import javafx.scene.control.TextArea;
7273
import javafx.scene.control.TextField;
74+
import javafx.scene.control.TextInputControl;
7375
import javafx.scene.control.ToolBar;
7476
import javafx.scene.control.Tooltip;
7577
import javafx.scene.control.cell.TextFieldTableCell;
@@ -83,8 +85,6 @@
8385
import javafx.scene.paint.Color;
8486
import javafx.util.converter.DefaultStringConverter;
8587

86-
import static org.phoebus.ui.application.PhoebusApplication.logger;
87-
8888

8989
/** PV Table and its toolbar
9090
* @author Kay Kasemir
@@ -95,6 +95,7 @@ public class PVTable extends VBox
9595
private static final String comment_style = "-fx-text-fill: blue;";
9696
private static final String new_item_style = "-fx-text-fill: gray;";
9797
private static final String changed_style = "-fx-background-color: -fx-table-cell-border-color, cyan;-fx-background-insets: 0, 0 0 1 0;";
98+
private static final String SPLIT_PV = "[ \\t\\n\\r,]+";
9899

99100
/** When sorting, keep the 'NEW_ITEM' row at the bottom **/
100101
private static final Comparator<TableItemProxy> SORT_NEW_ITEM_LAST = (a, b) ->
@@ -164,12 +165,31 @@ protected void updateItem(final Boolean selected, final boolean empty)
164165
}
165166
}
166167
}
168+
169+
private static class DescriptionTableCell extends TableCell<TableItemProxy, String>
170+
{
171+
@Override
172+
protected void updateItem(final String item, final boolean empty)
173+
{
174+
super.updateItem(item, empty);
175+
setText(item);
176+
final int row = getIndex();
177+
final List<TableItemProxy> items = getTableView().getItems();
178+
if (! empty && row >= 0 && row < items.size()) {
179+
final TableItemProxy itemCell = items.get(row);
180+
if(itemCell != null && itemCell.getItem() != null) {
181+
setTooltip(new Tooltip(itemCell.getItem().getDescriptionName()));
182+
}
183+
}
184+
}
185+
}
167186

168187
/** Table cell for 'name' column, colors comments */
169188
private static class PVNameTableCell extends TextFieldTableCell<TableItemProxy, String>
170189
{
171-
private TextField textField;
172-
190+
private TextInputControl textField;
191+
private static ContextMenu contextMenu;
192+
173193
public PVNameTableCell()
174194
{
175195
super(new DefaultStringConverter());
@@ -179,11 +199,26 @@ public PVNameTableCell()
179199
public void startEdit()
180200
{
181201
super.startEdit();
182-
textField = new TextField();
183-
textField.setOnAction(event -> commitEdit(textField.getText()));
202+
final int index = getIndex();
203+
boolean newPv = index == getTableView().getItems().size() - 1;
204+
if(newPv) {
205+
textField = new TextArea();
206+
textField.setMaxHeight(100);
207+
if(contextMenu == null) {
208+
MenuItem addPVMenu = new MenuItem(Messages.AddPVList);
209+
addPVMenu.setOnAction(event -> commitEdit(textField.getText()));
210+
contextMenu = new ContextMenu(addPVMenu);
211+
}
212+
textField.setContextMenu(contextMenu);
213+
}
214+
else {
215+
textField = new TextField();
216+
((TextField)textField).setOnAction(event -> commitEdit(textField.getText()));
217+
}
184218
PVAutocompleteMenu.INSTANCE.attachField(textField);
185219
showCurrentValue();
186220
}
221+
187222

188223
private void showCurrentValue()
189224
{
@@ -759,8 +794,14 @@ private void createTableColumns()
759794
final TableItemProxy proxy = event.getRowValue();
760795
if (proxy == TableItemProxy.NEW_ITEM)
761796
{
762-
if (!new_name.isEmpty())
763-
model.addItem(new_name);
797+
if (!new_name.isEmpty()) {
798+
//Can be a list of pv
799+
final String[] pvs = new_name.split(SPLIT_PV);
800+
//Add a list
801+
for(String pv : pvs) {
802+
model.addItem(pv);
803+
}
804+
}
764805
// else: No name entered, do nothing
765806
}
766807
else
@@ -784,6 +825,7 @@ private void createTableColumns()
784825
{
785826
col = new TableColumn<>(Messages.Description);
786827
col.setCellValueFactory(cell -> cell.getValue().desc_value);
828+
col.setCellFactory(column -> new DescriptionTableCell());
787829
table.getColumns().add(col);
788830
}
789831

@@ -959,7 +1001,7 @@ else if (db.hasString())
9591001

9601002
private void addPVsFromString(final PVTableItem existing, final String pv_text)
9611003
{
962-
final String[] pvs = pv_text.split("[ \\t\\n\\r,]+");
1004+
final String[] pvs = pv_text.split(SPLIT_PV);
9631005
for (String pv : pvs)
9641006
if (! pv.isEmpty())
9651007
model.addItemAbove(existing, pv);

app/pvtable/src/main/resources/org/phoebus/applications/pvtable/ui/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Alarm=Alarm
2+
AddPVList=Add a list of pv
23
Description=Description
34
CheckAll=Check All
45
CheckAll_TT=Check all PVs in table

app/pvtable/src/main/resources/org/phoebus/applications/pvtable/ui/messages_fr.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Alarm=Alarme
2+
AddPVList=Ajout d une liste de pv
23
Description=Description
34
CheckAll=Tout sélectionner
45
CheckAll_TT=Sélectionner tous les PVs dans le tableau

jitpack.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
before_install:
2+
# update maven version 3.9.9
3+
- sdk install maven 3.9.9
4+
install:
5+
- mvn install -DskipTests

0 commit comments

Comments
 (0)