use of org.csstudio.trends.databrowser3.model.ArchiveDataSource in project org.csstudio.display.builder by kasemir.
the class DataBrowserEditor method hookDragAndDrop.
/**
* Allow 'drop' of PV name, archive, ..
* @param canvas FXCanvas
*/
private void hookDragAndDrop(final Control canvas) {
// CS-Studio uses the ControlSystemDragSource
// and ControlSystemDropTarget to transfer its own
// data types, using the SWT drag-and-drop API
// plus some class loader hacking to de-serialize
// types from other plugins.
//
// The JavaFX plot is inside an FXCanvas.
// The FXCanvas establishes an SWT DropTarget
// to forward drops from SWT to the hosted JavaFX scene.
//
// Issues:
// The FXCanvas only reliably forwards standard transfers
// (string, ..), and not custom data types.
// SWT generally doesn't allow multiple drop targets.
//
// Option 1)
// Use the JavaFX drop API on the plot, and parse the received strings.
// -> Don't want to parse possibly arbitrary strings.
//
// Option 2)
// Change the ControlSystemDropTarget to use
// getSite().getService(IDragAndDropService.class).addMergedDropTarget(..)
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=162192
// This would allow 'adding' another DropTarget,
// but requires changes to the ControlSystemDropTarget,
// would only work in RCP, not plain SWT.
// Who then receives the drop events would depend on the order
// in which drop targets are added and which transfers they use.
//
// Option 3)
// Hack around the SWT limitation by fetching
// the FXCanva's DropTarget via
// control.getData(DND.DROP_TARGET_KEY);
// and disposing it.
// Checking the source code for the SWT DropTarget
// on Windows, Mac and Linux for SWT 3.104,
// this detaches the DropTarget and allows us
// to add our own.
final DropTarget old = (DropTarget) canvas.getData(DND.DROP_TARGET_KEY);
if (old != null)
old.dispose();
if (canvas.getData(DND.DROP_TARGET_KEY) != null)
throw new IllegalStateException("Cannot remove FXCanvas's DropTarget");
// Allow dropped arrays
new ControlSystemDropTarget(canvas, ChannelInfo[].class, ProcessVariable[].class, ArchiveDataSource[].class, File.class, String.class) {
@Override
public void handleDrop(final Object item) {
final PlotListener lst = plot.getListener();
if (lst == null)
return;
if (item instanceof ChannelInfo[]) {
final ChannelInfo[] channels = (ChannelInfo[]) item;
final int N = channels.length;
final ProcessVariable[] pvs = new ProcessVariable[N];
final ArchiveDataSource[] archives = new ArchiveDataSource[N];
for (int i = 0; i < N; ++i) {
pvs[i] = channels[i].getProcessVariable();
archives[i] = channels[i].getArchiveDataSource();
}
lst.droppedPVNames(pvs, archives);
} else if (item instanceof ProcessVariable[]) {
final ProcessVariable[] pvs = (ProcessVariable[]) item;
lst.droppedPVNames(pvs, null);
} else if (item instanceof ArchiveDataSource[]) {
final ArchiveDataSource[] archives = (ArchiveDataSource[]) item;
lst.droppedPVNames(null, archives);
} else if (item instanceof String) {
final List<String> pvs = new ArrayList<>();
// Allow passing in many names, assuming that white space separates them
// $NON-NLS-1$
final String[] names = ((String) item).split("[\\r\\n\\t ]+");
for (String one_name : names) {
// Might also have received "[pv1, pv2, pv2]", turn that into "pv1", "pv2", "pv3"
String suggestion = one_name;
if (suggestion.startsWith("["))
suggestion = suggestion.substring(1);
if (suggestion.endsWith("]") && !suggestion.contains("["))
suggestion = suggestion.substring(0, suggestion.length() - 1);
if (suggestion.endsWith(","))
suggestion = suggestion.substring(0, suggestion.length() - 1);
pvs.add(suggestion);
}
if (pvs.size() > 0)
lst.droppedNames(pvs.toArray(new String[pvs.size()]));
} else if (item instanceof String[]) {
// File names arrive as String[]...
final String[] files = (String[]) item;
try {
for (String filename : files) lst.droppedFilename(filename);
} catch (Exception ex) {
ExceptionDetailsErrorDialog.openError(canvas.getShell(), Messages.Error, ex);
}
}
}
};
}
use of org.csstudio.trends.databrowser3.model.ArchiveDataSource in project org.csstudio.display.builder by kasemir.
the class ArchiveListGUI method createGUI.
/**
* Create GUI elements
* @param parent Parent widget
*/
private void createGUI(final Composite parent) {
final GridLayout layout = new GridLayout(3, false);
parent.setLayout(layout);
// URL: ___urls___ [info]
Label l;
l = new Label(parent, 0);
l.setText(Messages.Search_URL);
l.setLayoutData(new GridData());
urls = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
urls.setToolTipText(Messages.Search_URL_TT);
for (ArchiveServerURL url : server_urls) urls.add(url.getDisplayName());
urls.setLayoutData(new GridData(SWT.FILL, 0, true, false));
if (urls.getItemCount() <= 0) {
urls.add(Messages.ArchiveListGUI_NoArchives);
urls.setEnabled(false);
}
urls.select(0);
info = new Button(parent, SWT.PUSH);
info.setText(Messages.ArchiveServerInfo);
info.setToolTipText(Messages.ArchiveServerInfoTT);
info.setEnabled(false);
// Table for archives, displaying array of ArchiveDataSource entries
// TableColumnLayout requires table in its own container
final Composite table_parent = new Composite(parent, 0);
table_parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, layout.numColumns, 1));
final TableColumnLayout table_layout = new MinSizeTableColumnLayout(10);
table_parent.setLayout(table_layout);
archive_table = new TableViewer(table_parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
archive_table.setContentProvider(new ArrayContentProvider());
TableViewerColumn col = TableHelper.createColumn(table_layout, archive_table, Messages.ArchiveName, 150, 100);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final ArchiveDataSource archive = (ArchiveDataSource) cell.getElement();
cell.setText(archive.getName());
}
});
new TableColumnSortHelper<ArchiveDataSource>(archive_table, col) {
@Override
public int compare(final ArchiveDataSource item1, final ArchiveDataSource item2) {
return item1.getName().compareTo(item2.getName());
}
};
col = TableHelper.createColumn(table_layout, archive_table, Messages.ArchiveDescription, 50, 100);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final ArchiveDataSource archive = (ArchiveDataSource) cell.getElement();
cell.setText(archive.getDescription());
}
});
new TableColumnSortHelper<ArchiveDataSource>(archive_table, col) {
@Override
public int compare(final ArchiveDataSource item1, final ArchiveDataSource item2) {
return item1.getDescription().compareTo(item2.getDescription());
}
};
col = TableHelper.createColumn(table_layout, archive_table, Messages.ArchiveKey, 35, 5);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final ArchiveDataSource archive = (ArchiveDataSource) cell.getElement();
cell.setText(Integer.toString(archive.getKey()));
}
});
new TableColumnSortHelper<ArchiveDataSource>(archive_table, col) {
@Override
public int compare(final ArchiveDataSource item1, final ArchiveDataSource item2) {
return item1.getKey() - item2.getKey();
}
};
final Table table = archive_table.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
}
use of org.csstudio.trends.databrowser3.model.ArchiveDataSource in project org.csstudio.display.builder by kasemir.
the class ArchiveListGUI method getSelectedArchives.
/**
* @return Selected archive data sources or 'all' when nothing selected.
* Returns <code>null</code> if user decided not to search 'all',
* or if connection to data server is not available.
*/
@SuppressWarnings("unchecked")
public ArchiveDataSource[] getSelectedArchives() {
if (url == null)
return null;
final ArrayList<ArchiveDataSource> archives;
final IStructuredSelection sel = (IStructuredSelection) archive_table.getSelection();
if (sel.isEmpty()) {
// Use 'all' archives, but prompt for confirmation
archives = (ArrayList<ArchiveDataSource>) archive_table.getInput();
if (archives.size() > 1 && !MessageDialog.openConfirm(archive_table.getTable().getShell(), Messages.Search, NLS.bind(Messages.SearchArchiveConfirmFmt, archives.size())))
return null;
} else {
archives = new ArrayList<ArchiveDataSource>();
final Object[] objs = sel.toArray();
for (Object obj : objs) archives.add((ArchiveDataSource) obj);
}
return (ArchiveDataSource[]) archives.toArray(new ArchiveDataSource[archives.size()]);
}
use of org.csstudio.trends.databrowser3.model.ArchiveDataSource in project org.csstudio.display.builder by kasemir.
the class SearchView method searchForChannels.
/**
* Search selected archives for channels, updating the
* <code>channel_table</code> with the result
* @see #channel_table
*/
private void searchForChannels() {
final ArchiveDataSource[] archives = archive_gui.getSelectedArchives();
if (archives == null)
return;
final String pattern_txt = pattern.getText().trim();
// Warn when searching ALL channels
if (pattern_txt.length() <= 0) {
MessageDialog.openInformation(pattern.getShell(), Messages.Search, Messages.SearchPatternEmptyMessage);
// Aborted, move focus to search pattern
pattern.setFocus();
return;
}
new SearchJob(archives, pattern_txt, !regex.getSelection()) {
@Override
protected void receivedChannelInfos(final ChannelInfo[] channels) {
displayChannelInfos(channels);
}
@Override
protected void archiveServerError(final String url, final Exception ex) {
handleServerError(url, ex);
}
}.schedule();
}
use of org.csstudio.trends.databrowser3.model.ArchiveDataSource in project org.csstudio.display.builder by kasemir.
the class AddPVAction method runWithSuggestedName.
/**
* Run the 'add PV' dialog with optional defaults
* @param name Suggested PV name, for example from drag-n-drop
* @param archive Archive data source for the new PV
* @return <code>true</code> if PV name was added, <code>false</code> if canceled by user
*/
public boolean runWithSuggestedName(final String name, final ArchiveDataSource archive) {
// Prompt for PV name
final AddPVDialog dlg = new AddPVDialog(shell, 1, model, formula);
dlg.setName(0, name);
if (dlg.open() != Window.OK)
return false;
// Did user select axis?
final AxisConfig axis;
if (dlg.getAxisIndex(0) >= 0)
axis = model.getAxis(dlg.getAxisIndex(0));
else
// Use first empty axis, or create a new one
axis = model.getEmptyAxis().orElseGet(() -> new AddAxisCommand(operations_manager, model).getAxis());
// Create item
if (formula) {
final Optional<AddModelItemCommand> command = AddModelItemCommand.forFormula(shell, operations_manager, model, dlg.getName(0), axis);
if (!command.isPresent())
return false;
// Open configuration dialog
final FormulaItem formula = (FormulaItem) command.get().getItem();
final EditFormulaDialog edit = new EditFormulaDialog(operations_manager, shell, formula);
edit.open();
} else
AddModelItemCommand.forPV(shell, operations_manager, model, dlg.getName(0), dlg.getScanPeriod(0), axis, archive);
return true;
}
Aggregations