diff --git a/com.minres.scviewer.e4.application/icons/page_white.png b/com.minres.scviewer.e4.application/icons/page_white.png new file mode 100644 index 0000000..8b8b1ca Binary files /dev/null and b/com.minres.scviewer.e4.application/icons/page_white.png differ diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/OpenHandler.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/OpenHandler.java index 48dbb7b..b064f05 100644 --- a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/OpenHandler.java +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/handlers/OpenHandler.java @@ -11,7 +11,7 @@ package com.minres.scviewer.e4.application.handlers; import java.io.File; -import java.util.ArrayList; +import java.util.List; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.Execute; @@ -21,27 +21,20 @@ import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import com.minres.scviewer.e4.application.Messages; +import com.minres.scviewer.e4.application.parts.FileBrowserDialog; public class OpenHandler { @Execute public void execute(Shell shell, MApplication app, EModelService modelService, EPartService partService){ - FileDialog dialog = new FileDialog(shell, SWT.OPEN | SWT.MULTI); - dialog.setFilterExtensions (new String []{Messages.OpenHandler_0}); - String ret = dialog.open(); - if(ret==null) - return; - String path = dialog.getFilterPath(); - ArrayList files = new ArrayList(); - for(String fileName: dialog.getFileNames()){ - File file = new File(path+File.separator+fileName); - if(file.exists()) - files.add(file); - } + FileBrowserDialog dlg = new FileBrowserDialog(shell); + dlg.create(); + dlg.setFilterExtensions (new String []{Messages.OpenHandler_0}); + if (dlg.open() != Window.OK) return; + List files = dlg.getSelectedFiles(); MPart part = partService .createPart("com.minres.scviewer.e4.application.partdescriptor.waveformviewer"); //$NON-NLS-1$ part.setLabel(files.get(0).getName()); MPartStack partStack = (MPartStack)modelService.find("org.eclipse.editorss", app); //$NON-NLS-1$ diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/messages.properties b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/messages.properties index 264be16..654ac95 100644 --- a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/messages.properties +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/messages.properties @@ -9,7 +9,7 @@ DesignBrowser_8=Insert before LoadingWaveformDb_0=Database loading... LoadStoreSettingsHandler_2=*.scview LoadStoreSettingsHandler_3=SCViewer.scview -OpenHandler_0=*.vcd;*.txdb;*.txlog;CURRENT +OpenHandler_0=*.vcd;*.txdb;*.txlog;*.fbrdb QuitHandler_0=Confirmation QuitHandler_1=Do you want to exit? RelationTypeToolControl_0=------------ diff --git a/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/FileBrowserDialog.java b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/FileBrowserDialog.java new file mode 100644 index 0000000..68531c2 --- /dev/null +++ b/com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/FileBrowserDialog.java @@ -0,0 +1,410 @@ +package com.minres.scviewer.e4.application.parts; + +import java.io.File; +import java.nio.file.FileSystems; +import java.nio.file.PathMatcher; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.wb.swt.ResourceManager; + +public class FileBrowserDialog extends TrayDialog { + + private Image folderImage; + + private Image fileImage; + + private Image dbImage; + + File currentDirFile; + + TreeViewer dirTreeViewer; + + TableViewer tableViewer; + + FileTableComparator fileTableComparator; + + private FileGlobber globber = new FileGlobber(); + + private List selectedFiles; + + String[] filterStrings = new String[] {"*"}; + + public FileBrowserDialog(Shell parentShell) { + super(parentShell); + folderImage=ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/folder.png"); //$NON-NLS-1$ //$NON-NLS-2$ + dbImage=ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/database.png"); //$NON-NLS-1$ //$NON-NLS-2$ + fileImage=ResourceManager.getPluginImage("com.minres.scviewer.e4.application", "icons/page_white.png"); //$NON-NLS-1$ //$NON-NLS-2$ + currentDirFile = new File("."); + } + + public void setFilterExtensions(String[] filterStrings) { + if(filterStrings.length==0){ + globber = new FileGlobber(); + } else + globber= new FileGlobber(filterStrings[0]); + this.filterStrings=filterStrings; + } + + public List getSelectedFiles(){ + return selectedFiles; + } + + @Override + public int open() { + dirTreeViewer.setInput("root"); + dirTreeViewer.refresh(); + setDirSelection(currentDirFile.getAbsoluteFile().getParentFile()); + getButton(IDialogConstants.OK_ID).setEnabled(!tableViewer.getSelection().isEmpty()); + return super.open(); + } + + @Override + protected Control createContents(Composite parent) { + Control ret = super.createContents(parent); + if(parent instanceof Shell) { + ((Shell)parent).setSize(800, 400); + ((Shell)parent).setText("Select database"); + } + return ret; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite area = (Composite) super.createDialogArea(parent); + final SashForm sashForm = new SashForm(area, SWT.HORIZONTAL); + sashForm.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL)); + + dirTreeViewer = new TreeViewer(sashForm); + dirTreeViewer.setContentProvider(new FileTreeContentProvider()); + dirTreeViewer.setLabelProvider(new FileTreeLabelProvider()); + dirTreeViewer.addSelectionChangedListener(event -> { + IStructuredSelection sel = event.getStructuredSelection(); + File entry = (File) sel.getFirstElement(); + if(entry.isDirectory()) { + tableViewer.setInput(entry.listFiles()); + } + }); + + final Composite tableViewerParent = new Composite(sashForm, SWT.BORDER); + tableViewerParent.setLayout(new GridLayout(1, true)); + tableViewer = new TableViewer(tableViewerParent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.getTable().setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); + tableViewer.addSelectionChangedListener(event -> { + getButton(IDialogConstants.OK_ID).setEnabled(!event.getStructuredSelection().isEmpty()); + }); + tableViewer.addDoubleClickListener(event -> { + IStructuredSelection sel = tableViewer.getStructuredSelection(); + if(sel.isEmpty()) return; + if(sel.size()==1) { + File elem = (File) sel.getFirstElement(); + if(globber.matches(elem)) + buttonPressed(IDialogConstants.OK_ID); + else if(elem.isDirectory()) + setDirSelection(elem); + } else + buttonPressed(IDialogConstants.OK_ID); + }); + tableViewer.setContentProvider(ArrayContentProvider.getInstance()); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { mouseUp(e); } + @Override + public void mouseUp(MouseEvent e) { + TableItem element = (TableItem)tableViewer.getTable().getItem(new Point(e.x, e.y)); + final Table table = tableViewer.getTable(); + if (element == null )//&& (e.stateMask&SWT.MODIFIER_MASK)!=0) + table.deselectAll(); + else { + int[] indices = table.getSelectionIndices(); + if(indices.length==1) { + TableItem ti = table.getItem(indices[0]); + if(!globber.matches(ti.getData()) && !((File)ti.getData()).isDirectory()) + table.deselect(indices[0]); + } else { + for (int idx : indices) { + TableItem ti = table.getItem(idx); + if(!globber.matches(ti.getData())) + table.deselect(idx); + } + } + } + } + }); + TableViewerColumn colName = new TableViewerColumn(tableViewer, SWT.NONE); + colName.setLabelProvider(new FileTableLabelProvider() { + @Override public String getText(Object element) { return ((File) element).getName(); } + @Override public Image getImage(Object element){ + if(globber.matches(element)) return dbImage; + return ((File) element).isDirectory()?folderImage:fileImage; + } + }); + colName.getColumn().setWidth(300); + colName.getColumn().setText("Name"); + colName.getColumn().addSelectionListener(getSelectionAdapter(colName.getColumn(), 0)); + + TableViewerColumn colSize = new TableViewerColumn(tableViewer, SWT.RIGHT); + colSize.setLabelProvider(new FileTableLabelProvider() { + @Override public String getText(Object element) { return String.format("%d", ((File) element).length()); } + }); + colSize.getColumn().setWidth(100); + colSize.getColumn().setText("Size"); + colSize.getColumn().addSelectionListener(getSelectionAdapter(colSize.getColumn(), 1)); + + TableViewerColumn colEmpty = new TableViewerColumn(tableViewer, SWT.CENTER); + colEmpty.setLabelProvider(new FileTableLabelProvider() { + @Override public String getText(Object element) { return ""; } + }); + //colEmpty.getColumn().setWidth(200); + colEmpty.getColumn().setText(""); + + fileTableComparator = new FileTableComparator(); + tableViewer.setComparator(fileTableComparator); + sashForm.setWeights(new int[]{2, 3}); + return area; + } + + private SelectionAdapter getSelectionAdapter(final TableColumn column, final int index) { + SelectionAdapter selectionAdapter = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + fileTableComparator.setColumn(index); + int dir = fileTableComparator.getDirection(); + tableViewer.getTable().setSortDirection(dir); + tableViewer.getTable().setSortColumn(column); + tableViewer.refresh(); + } + }; + return selectionAdapter; + } + + private void setDirSelection(File f) { + ArrayList fileTree = getParentDirList(f); + TreeSelection selection = new TreeSelection(new TreePath(fileTree.toArray())); + dirTreeViewer.setSelection(selection); + } + + private ArrayList getParentDirList(File actual){ + if(actual==null) + return new ArrayList<>(); + else { + ArrayList l = getParentDirList(actual.getParentFile()); + l.add(actual); + return l; + } + } + + @Override + protected boolean isResizable() { + return true; + } + + // save content of the Text fields because they get disposed + // as soon as the Dialog closes + @SuppressWarnings("unchecked") + private void saveInput() { + selectedFiles= tableViewer.getStructuredSelection().toList(); + } + + @Override + protected void okPressed() { + saveInput(); + super.okPressed(); + } + + class FileGlobber { + + List matchers; + + public FileGlobber() { + matchers = new ArrayList<>(); } + + public FileGlobber(String expr) { + ArrayList m = new ArrayList<>(); + if(expr.length()>0) { + String[] tok = expr.split(";"); + for (String string : tok) { + m.add(FileSystems.getDefault().getPathMatcher("glob:**/"+string)); + } + } + matchers = m; + } + + public boolean matches(Object f) { + assert(f instanceof File); + if(matchers.size()==0) return true; + for (PathMatcher m : matchers) { + if(m.matches(((File)f).toPath())) return true; + } + return false; + } + } + + class FileTreeContentProvider implements ITreeContentProvider { + public Object[] getChildren(Object arg0) { + File[] entries = ((File) arg0).listFiles(); + if(entries != null) { + List res = Arrays.stream(entries) + .filter(file -> !(file.isFile()||file.getName().startsWith(".") ||globber.matches(file))) + .sorted(new Comparator(){ + public int compare(File f1, File f2){return f1.getName().compareTo(f2.getName());} + }) + .collect(Collectors.toList()); ; + return res.toArray(); + } else + return new Object[0]; + } + + public Object getParent(Object arg0) { + return ((File) arg0).getParentFile(); + } + + public boolean hasChildren(Object arg0) { + Object[] obj = getChildren(arg0); + return obj == null ? false : obj.length > 0; + } + + public Object[] getElements(Object arg0) { + return File.listRoots(); + } + + public void dispose() { + } + + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + } + + class FileTreeLabelProvider implements ILabelProvider { + private List listeners; + + private Image file; + + private Image dir; + + public FileTreeLabelProvider() { + listeners = new ArrayList(); + } + + public Image getImage(Object arg0) { + return ((File) arg0).isDirectory() ? folderImage : file; + } + + public String getText(Object arg0) { + File f = (File)arg0; + return f.getName().length() == 0? f.getPath() : f.getName(); + } + + public void addListener(ILabelProviderListener arg0) { + listeners.add(arg0); + } + + public void dispose() { + // Dispose the images + if (dir != null) + dir.dispose(); + if (file != null) + file.dispose(); + } + + public boolean isLabelProperty(Object arg0, String arg1) { + return false; + } + + public void removeListener(ILabelProviderListener arg0) { + listeners.remove(arg0); + } + + } + + public class FileTableComparator extends ViewerComparator { + private int propertyIndex = 0; + private boolean descending = false; + + public FileTableComparator() { + } + + public int getDirection() { + return descending ? SWT.DOWN : SWT.UP; + } + + public void setColumn(int column) { + descending = column == this.propertyIndex?!descending : false; + this.propertyIndex = column; + } + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + File p1 = (File) e1; + File p2 = (File) e2; + int rc = 0; + switch (propertyIndex) { + case 0: + rc = p1.getName().compareTo(p2.getName()); + break; + case 1: + rc = Long.valueOf(p1.length()).compareTo(p2.length()); + break; + default: + rc = 0; + } + // If descending order, flip the direction + return descending? -rc : rc; + } + + } + + public class FileTableLabelProvider extends ColumnLabelProvider { + @Override + public Color getBackground(Object element) { + return null; + } + + @Override + public Color getForeground(Object element) { + return globber.matches(element) || ((File)element).isDirectory()? null: ResourceManager.getColor(SWT.COLOR_GRAY); + } + + } +} +