/******************************************************************************* * Copyright (c) 2014 Elphel, Inc. * Copyright (c) 2006 Elphel, Inc and Excelsior, LLC. * This file is a part of VDT plug-in. * VDT plug-in is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VDT plug-in is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Additional permission under GNU GPL version 3 section 7: * If you modify this Program, or any covered work, by linking or combining it * with Eclipse or Eclipse plugins (or a modified version of those libraries), * containing parts covered by the terms of EPL/CPL, the licensors of this * Program grant you additional permission to convey the resulting work. * {Corresponding Source for a non-source form of such a combination shall * include the source code for the parts of Eclipse or Eclipse plugins used * as well as that of the covered work.} *******************************************************************************/ package com.elphel.vdt.ui.variables; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Stack; import com.elphel.vdt.VDT; import com.elphel.vdt.VerilogUtils; import com.elphel.vdt.core.tools.params.Tool; import com.elphel.vdt.core.tools.params.ToolSequence; import com.elphel.vdt.ui.MessageUI; import com.elphel.vdt.veditor.VerilogPlugin; import com.elphel.vdt.veditor.preference.PreferenceStrings; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IMemento; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.ISelectionService; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; /** * Maintains the context used to launch tools. The context is based on * the selected resource. * * Created: 26.01.2006 * @author Lvov Konstantin */ public class SelectedResourceManager implements IWindowListener, ISelectionListener { // singleton private static SelectedResourceManager fgDefault = new SelectedResourceManager(); private IResource fSelectedResource = null; private IResource fSelectedVerilogFile = null; private ITextSelection fSelectedText = null; private Stack<IWorkbenchWindow> fWindowStack = new Stack<IWorkbenchWindow>(); //Andrey private String fChosenTarget=null; // full path of the chosen (for action) resource or any string. Used to calculate CurrentFile, verilog file, ... private String fChosenShort=null; // last segment of the chosen resource name private IResource fChosenVerilogFile = null; // to keep fSelectedVerilogFile private int fChosenAction=0; // Chosen variant of running the tool // private long timestamp=0; private String timestamp; private String ignoreFilter=null; private boolean toolsLinked=true; private ToolSequence toolSequence=null; // to be able to reach toolSequence instance from VEditor // private Tool selectedTool=null; // last selected tool // private SelectedResourceManager() { IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench != null) { //may be running headless workbench.addWindowListener(this); IWorkbenchWindow activeWindow = workbench.getActiveWorkbenchWindow(); if (activeWindow != null) { windowActivated(activeWindow); } } } // SelectedResourceManager() /** * Returns the singleton resource selection manager * * @return VariableContextManager */ public static SelectedResourceManager getDefault() { if (fgDefault.fSelectedResource == null) fgDefault.tryDefaultSelection(); return fgDefault; } private void tryDefaultSelection() { IWorkbenchPage page = fWindowStack.peek().getActivePage(); if (page != null) { IViewPart view = page.findView(IPageLayout.ID_RES_NAV); if (view != null) selectionChanged(view, view.getViewSite().getSelectionProvider().getSelection()); } } public void setToolsLinked(boolean linked){ this.toolsLinked=linked; } public boolean isToolsLinked(){ return toolsLinked; } public void setToolSequence (ToolSequence toolSequence){ this.toolSequence=toolSequence; } public ToolSequence getToolSequence(){ return toolSequence; } /** * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow) */ public void windowActivated(IWorkbenchWindow window) { fWindowStack.remove(window); fWindowStack.push(window); ISelectionService service = window.getSelectionService(); service.addSelectionListener(this); IWorkbenchPage page = window.getActivePage(); if (page != null) { IWorkbenchPart part = page.getActivePart(); if (part != null) { ISelection selection = service.getSelection(); if (selection != null) { selectionChanged(part, selection); } } } } // windowActivated() /** * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow) */ public void windowClosed(IWorkbenchWindow window) { ISelectionService selectionService = window.getSelectionService(); selectionService.removeSelectionListener(this); fWindowStack.remove(window); } /** * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow) */ public void windowDeactivated(IWorkbenchWindow window) { } /** * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow) */ public void windowOpened(IWorkbenchWindow window) { windowActivated(window); } /** * Returns the currently selected resource in the active workbench window, * or <code>null</code> if none. If an editor is active, the resource adapter * associated with the editor is returned. * * @return selected resource or <code>null</code> */ public IResource getSelectedResource() { return fSelectedResource; } public IProject getSelectedProject() { if (fSelectedResource != null) return fSelectedResource.getProject(); else return null; } public IResource getSelectedVerilogFile() { return fSelectedVerilogFile; } /** * Returns resource by selection in the active workbench window, * or <code>null</code> if none. If an editor is active, the resource adapater * associated with the editor is returned. * * @return selected resource or <code>null</code> */ public IResource getSelectedResource(IWorkbenchPart part, ISelection selection) { IResource selectedResource = null; if (selection instanceof IStructuredSelection) { Object result = ((IStructuredSelection)selection).getFirstElement(); if (result instanceof IResource) { selectedResource = (IResource) result; } else if (result instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) result; selectedResource = (IResource)adaptable.getAdapter(IResource.class); } } if (selectedResource == null) { // If the active part is an editor, get the file resource used as input. if (part instanceof IEditorPart) { IEditorPart editorPart = (IEditorPart) part; IEditorInput input = editorPart.getEditorInput(); selectedResource = (IResource) input.getAdapter(IResource.class); } } if (selectedResource != null) return selectedResource; else return fSelectedResource; } // getSelectedResource() public IResource getViewSelectedResource(String viewId) { IWorkbenchPage page = fWindowStack.peek().getActivePage(); if (page != null) { IViewPart view = page.findView(viewId); if (view != null) { return getSelectedResource(view, view.getViewSite().getSelectionProvider().getSelection()); } } return null; } /** * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) */ public void selectionChanged(IWorkbenchPart part, ISelection selection) { if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) System.out.print("$$$ Selection changed, fSelectedResource="+fSelectedResource); // System.out.println("SelectedResourceManager.selectionChanged()"); IWorkbenchWindow window = part.getSite().getWorkbenchWindow(); if (fWindowStack.isEmpty() || !fWindowStack.peek().equals(window)) { // selection is not in the active window System.out.println(" - stray selection outside acrtive window"); return; } IResource selectedResource = getSelectedResource(part, selection); if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) System.out.println(" New selection: "+selectedResource); if (selectedResource != null) { fSelectedResource = selectedResource; if ((selectedResource.getType()==IResource.FILE) && (VerilogUtils.isHhdlFile((IFile)fSelectedResource))){ fSelectedVerilogFile = selectedResource; /* Maybe same will work for vhdl too? */ if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) System.out.println("Updated fSelectedVerilogFile: "+fSelectedVerilogFile); } else { if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) System.out.println(selectedResource+" is not a file or not an HDL file"); } } if (selection instanceof ITextSelection) { fSelectedText = (ITextSelection)selection; } } // selectionChanged() //TODO: Make them project-relative public String tryRelativePath(String path){ if (path==null) return null; if (getSelectedProject()==null) return path; IProject project=getSelectedProject(); if (path.startsWith(project.getLocation().toString())) return path.substring(project.getLocation().toString().length()+1); return path; } public void updateActionChoice(String chosenTarget, int choice, String ignoreFilter){ fChosenAction=choice; fChosenTarget=tryRelativePath(chosenTarget); this.ignoreFilter=ignoreFilter; IProject project=getSelectedProject(); if (project==null) return; IPath path = new Path(fChosenTarget); IFile file=null; try { file = (path==null)?null:project.getFile(path); } catch (IllegalArgumentException e) { // Path must include project and resource name: /x353 } if ((file != null) && (VerilogUtils.isHhdlFile(file))) fChosenVerilogFile=file; else if (fChosenVerilogFile==null) fChosenVerilogFile=fSelectedVerilogFile; if (file!=null){ fChosenShort=file.getName(); // last segment } else { fChosenShort=fChosenTarget; // whatever } } // Build stamp/date methods public String setBuildStamp(){ timestamp=getBuildStamp(new Date()); return getBuildStamp(); } public String getBuildStamp(){ return timestamp; } public static String getBuildStamp(Date date){ return new SimpleDateFormat(VDT.TIME_STAMP_FORMAT).format(date); } public static Date parseStamp(String stamp){ Date d; try { d = new SimpleDateFormat(VDT.TIME_STAMP_FORMAT).parse(stamp); } catch (ParseException e) { d=new Date(0); System.out.println("Date format '"+stamp+"' not recognized, using beginning of all of times: "+ new SimpleDateFormat(VDT.TIME_STAMP_FORMAT).format(d)); return d; // 1970 } return d; } public static boolean afterStamp(String after, String before){ return parseStamp(after).after(parseStamp(before)); } public String getChosenTarget() { return fChosenTarget; } public String getChosenShort() { return fChosenShort; } public IResource getChosenVerilogFile() { IProject project=getSelectedProject(); if (project==null) return null; IResource rslt=(fChosenVerilogFile!=null)?fChosenVerilogFile:fSelectedVerilogFile; if (rslt==null) return null; if (project.getFullPath().toPortableString().equals(rslt.getProject().getFullPath().toPortableString())){ return (fChosenVerilogFile!=null)?fChosenVerilogFile:fSelectedVerilogFile; } else { System.out.println("Wrong getChosenVerilogFile="+rslt+" for project "+project); if (fSelectedVerilogFile==null) return null; if (project.getFullPath().toPortableString().equals(fSelectedVerilogFile.getProject().getFullPath().toPortableString())){ System.out.println("Using: "+fSelectedVerilogFile); return fSelectedVerilogFile; } else { System.out.println("fSelectedVerilogFile is also wrong: "+fSelectedVerilogFile); } return fSelectedResource; } } // Used when restoring from memento public void setChosenVerilogFile(IResource file) { if (file != null){ if (file.getType() != IResource.FILE) { String msg="Tried to use "+file+" as HDL file"; if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) { MessageUI.error(msg); } System.out.println(msg); return; } if (!VerilogUtils.isHhdlFile((IFile)file)){ String msg="Tried to use non-HDL "+file+" as HDL file"; if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) { MessageUI.error(msg); } System.out.println(msg); return; } } fChosenVerilogFile=file; IProject project=getSelectedProject(); IProject newProject= (file == null)? null: file.getProject(); // if file is different project than selectedResource if ((newProject != null) && ((project == null) || !newProject.getFullPath().toPortableString().equals(project.getFullPath().toPortableString()))){ fSelectedResource=file; } if (fSelectedResource==null) fSelectedResource=file; } public int getChosenAction() { return fChosenAction; } // public Tool getSelectedTool(){ // return selectedTool; // } public String getFilter(){ return ignoreFilter; } public void setFilter(String filter){ ignoreFilter=filter; } /** * Returns the current text selection as a <code>String</code>, or <code>null</code> if * none. * * @return the current text selection as a <code>String</code> or <code>null</code> */ public String getSelectedText() { return fSelectedText.getText(); } } // class SelectedResourceManager()