package org.csstudio.sds.ui.dialogs; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.nebula.widgets.gallery.AbstractGalleryItemRenderer; import org.eclipse.nebula.widgets.gallery.AbstractGridGroupRenderer; import org.eclipse.nebula.widgets.gallery.DefaultGalleryGroupRenderer; import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer; import org.eclipse.nebula.widgets.gallery.Gallery; import org.eclipse.nebula.widgets.gallery.GalleryItem; import org.eclipse.nebula.widgets.gallery.ListItemRenderer; import org.eclipse.nebula.widgets.gallery.NoGroupRenderer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.FileEditorInput; public class LibraryPanel extends Composite { public enum LibraryPanelLayout { GroupedGrid, UngroupedGrid, UngroupedList; } private Gallery gallery; private List<File> sortedDisplays = new ArrayList<File>(); private Map<File, GalleryItem> displayFileToGalleryItemMap = new HashMap<File, GalleryItem>(); private Map<GalleryItem, File> galleryItemToDisplayFileMap = new HashMap<GalleryItem, File>(); private List<File> folderList; private final ThumbnailCreator thumbnailCreator = new ThumbnailCreator(); private IResourceChangeListener resourceChangeListener; public LibraryPanel(Composite parent, int style, LibraryPanelLayout libraryLayout) { super(parent, style); setLayout(new FillLayout()); gallery = new Gallery(this, SWT.V_SCROLL | SWT.SINGLE); setLibraryLayout(libraryLayout); gallery.addMouseListener(new MouseAdapter() { @Override public void mouseDoubleClick(MouseEvent arg0) { try { File selectedFile = getSelectedFile(); if (selectedFile != null) { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root = workspace.getRoot(); IFile file = root.getFileForLocation(new Path( selectedFile.getAbsolutePath())); IEditorInput editorInput = new FileEditorInput(file); IWorkbenchWindow window = PlatformUI.getWorkbench() .getActiveWorkbenchWindow(); IWorkbenchPage page = window.getActivePage(); page.openEditor(editorInput, "org.csstudio.sds.ui.internal.editor.DisplayEditor"); } } catch (Exception e) { e.printStackTrace(); } } }); initResourceListener(); } public void setLibraryLayout(LibraryPanelLayout layout) { assert layout != null : "Precondition failed: layout != null"; AbstractGalleryItemRenderer itemRenderer = null; final AbstractGridGroupRenderer groupRenderer; int itemHeight = 120; switch (layout) { case GroupedGrid: itemRenderer = new DefaultGalleryItemRenderer(); groupRenderer = new DefaultGalleryGroupRenderer(); break; case UngroupedGrid: itemRenderer = new DefaultGalleryItemRenderer(); groupRenderer = new NoGroupRenderer(); break; case UngroupedList: itemRenderer = new ListItemRenderer(); itemHeight = 40; groupRenderer = new NoGroupRenderer(); gallery.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { int newWidth = gallery.getClientArea().width; if (newWidth > 0) { groupRenderer.setItemWidth(newWidth); } } }); break; default: itemRenderer = new DefaultGalleryItemRenderer(); groupRenderer = new DefaultGalleryGroupRenderer(); break; } groupRenderer.setItemHeight(itemHeight); groupRenderer.setItemWidth(100); groupRenderer.setAutoMargin(true); gallery.setGroupRenderer(groupRenderer); gallery.setItemRenderer(itemRenderer); } private void initResourceListener() { resourceChangeListener = new IResourceChangeListener() { @Override public void resourceChanged(IResourceChangeEvent event) { boolean relevantChange = false; IResourceDelta rootDelta = event.getDelta(); for (File folder : folderList) { IResourceDelta folderDelta = rootDelta.findMember(new Path( getWorkspaceRelativePath(folder))); if (folderDelta != null) { // if (folderDelta.getKind() == IResourceDelta.REMOVED // || folderDelta.getKind() == IResourceDelta.MOVED_TO) // { // force complete update relevantChange = true; // return; // } // // handleFolderChanged(folderDelta); } } if (relevantChange) { getDisplay().asyncExec(new Runnable() { @Override public void run() { setFolders(folderList); } }); } } // private void handleFolderChanged(IResourceDelta folderDelta) { // // try { // folderDelta.accept(new IResourceDeltaVisitor() { // public boolean visit(IResourceDelta delta) { // // IResource resource = delta.getResource(); // // only interested in files with the "txt" extension // // if (resource.getType() == IResource.FILE // && "css-sds".equalsIgnoreCase(resource // .getFileExtension())) { // // if (resource.exists()) { // // resource.get // // } // // } // return true; // } // }); // } catch (CoreException e) { // // open error dialog with syncExec or print to plugin log // // file // } // } }; ResourcesPlugin.getWorkspace().addResourceChangeListener( resourceChangeListener, IResourceChangeEvent.POST_CHANGE); } public Gallery getGallery() { return gallery; } private GalleryItem getSelected() { GalleryItem[] selection = gallery.getSelection(); if (selection != null && selection.length > 0) { return selection[0]; } else { return null; } } public void setFolders(List<File> folderList) { this.folderList = folderList; sortedDisplays.clear(); displayFileToGalleryItemMap.clear(); galleryItemToDisplayFileMap.clear(); gallery.clearAll(); gallery.removeAll(); for (File folder : folderList) { String text = getWorkspaceRelativePath(folder); final GalleryItem folderGroupItem = new GalleryItem(gallery, SWT.NONE); folderGroupItem.setText(text); folderGroupItem.setExpanded(true); FileFilter fileFilter = new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile() && pathname.getName().endsWith(".css-sds"); } }; for (File file : folder.listFiles(fileFilter)) { GalleryItem galleryItem = new GalleryItem(folderGroupItem, SWT.NONE); galleryItem.setText(file.getName().substring(0, file.getName().lastIndexOf("."))); addFileToLibrary(file, galleryItem); } } createThumbnailsAsync(); } private String getWorkspaceRelativePath(File folder) { IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root = workspace.getRoot(); IPath rootPath = root.getLocation(); Path path = new Path(folder.getAbsolutePath()); return path.makeRelativeTo(rootPath).toString(); } private void addFileToLibrary(File file, GalleryItem galleryItem) { sortedDisplays.add(file); displayFileToGalleryItemMap.put(file, galleryItem); galleryItemToDisplayFileMap.put(galleryItem, file); } public File getSelectedFile() { GalleryItem selected = getSelected(); return selected != null ? galleryItemToDisplayFileMap.get(selected) : null; } private void createThumbnailsAsync() { // FIXME gs, fz: Handle disposed display correctly! final Display display = Display.getDefault(); new Thread(new Runnable() { @Override public void run() { for (final File file : sortedDisplays) { final ImageData imageData = thumbnailCreator.createImage( file, 100, display); if (!display.isDisposed()) { display.syncExec(new Runnable() { @Override public void run() { GalleryItem item = displayFileToGalleryItemMap .get(file); if (!display.isDisposed()) { Image image = new Image(display, imageData); if (!image.isDisposed()) { item.setImage(image); } } } }); } } } }).start(); } @Override public void dispose() { super.dispose(); ResourcesPlugin.getWorkspace().removeResourceChangeListener( resourceChangeListener); } }