/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation * *****************************************************************************/ package kr.co.apexsoft.stella.modeler.explorer.view; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import kr.co.apexsoft.stella.modeler.explorer.Activator; import kr.co.apexsoft.stella.modeler.explorer.core.ApexStellaProjectMap; import kr.co.apexsoft.stella.modeler.explorer.provider.ApexDecoratingLabelProviderWTooltips; import kr.co.apexsoft.stella.modeler.explorer.util.ApexModelTreeUtil; import org.eclipse.core.commands.operations.IUndoContext; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.domain.IEditingDomainProvider; import org.eclipse.emf.facet.infra.browser.uicore.internal.model.ModelElementItem; import org.eclipse.emf.transaction.ResourceSetChangeEvent; import org.eclipse.emf.transaction.ResourceSetListener; import org.eclipse.emf.transaction.ResourceSetListenerImpl; import org.eclipse.emf.transaction.Transaction; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.impl.DiagramImpl; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.ToolTip; import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor; import org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor; import org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener; import org.eclipse.papyrus.infra.core.lifecycleevents.ISaveAndDirtyService; import org.eclipse.papyrus.infra.core.resource.ModelMultiException; import org.eclipse.papyrus.infra.core.resource.ModelSet; import org.eclipse.papyrus.infra.core.resource.additional.AdditionalResourcesModel; import org.eclipse.papyrus.infra.core.sasheditor.contentprovider.IPageMngr; import org.eclipse.papyrus.infra.core.services.ServiceException; import org.eclipse.papyrus.infra.core.services.ServicesRegistry; import org.eclipse.papyrus.infra.core.ui.IApexStellaExplorerViewService; import org.eclipse.papyrus.infra.core.ui.IRevealSemanticElement; import org.eclipse.papyrus.infra.core.utils.EditorUtils; import org.eclipse.papyrus.infra.core.utils.ServiceUtils; import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers; import org.eclipse.papyrus.infra.emf.providers.SemanticFromModelExplorer; import org.eclipse.papyrus.infra.onefile.utils.OneFileUtils; import org.eclipse.papyrus.views.modelexplorer.CustomCommonViewer; import org.eclipse.papyrus.views.modelexplorer.Messages; import org.eclipse.papyrus.views.modelexplorer.matching.IMatchingItem; import org.eclipse.papyrus.views.modelexplorer.matching.LinkItemMatchingItem; import org.eclipse.papyrus.views.modelexplorer.matching.ModelElementItemMatchingItem; import org.eclipse.papyrus.views.modelexplorer.matching.ReferencableMatchingItem; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IMemento; import org.eclipse.ui.ISaveablePart; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.navigator.NavigatorContentService; import org.eclipse.ui.internal.navigator.extensions.NavigatorContentDescriptor; import org.eclipse.ui.navigator.CommonNavigator; import org.eclipse.ui.navigator.CommonViewer; import org.eclipse.ui.navigator.CommonViewerSorter; import org.eclipse.ui.operations.RedoActionHandler; import org.eclipse.ui.operations.UndoActionHandler; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.views.properties.IPropertySheetPage; import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor; import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; /** * ApexStellaExplorer 는 여러개의 IMultiDiagramEditor에 존재하는 여러 모델을 하나의 View에서 보여준다. * */ public class ApexStellaExplorerView extends CommonNavigator implements IRevealSemanticElement, IEditingDomainProvider, ITabbedPropertySheetPageContributor, IApexStellaExplorerViewService { /** ID of the view, as given in the plugin.xml file */ public static final String VIEW_ID = "org.eclipse.papyrus.uml.modelexplorer.modellipseexplorer"; //$NON-NLS-1$ /** * The associated EditorPart * The View is associated to the ServicesRegistry rather than to an editor. * */ // private IMultiDiagramEditor editorPart; /** * The {@link ServicesRegistry} associated to the Editor. This view is associated to the * ServicesRegistry rather than to the EditorPart. */ private ServicesRegistry serviceRegistry; /** The save aservice associated to the editor. */ private ISaveAndDirtyService saveAndDirtyService; /** {@link IUndoContext} used to tag command in the commandStack. */ private IUndoContext undoContext; /** editing domain used to read/write the model */ private TransactionalEditingDomain editingDomain; /** Flag to avoid reentrant call to refresh. */ private AtomicBoolean isRefreshing = new AtomicBoolean(false); /** Undo action handler */ UndoActionHandler undoHandler; /** Redo action handler */ RedoActionHandler redoHandler; /** The {@link IPropertySheetPage} this model explorer will use. */ private IPropertySheetPage propertySheetPage = null; /** * A listener on page (all editors) selection change. This listener is set * in {@link ApexStellaExplorerView#init(IViewSite)}. It should be dispose to remove * hook to the Eclipse page. */ private ISelectionListener pageSelectionListener = new ISelectionListener() { public void selectionChanged(IWorkbenchPart part, ISelection selection) { handleSelectionChangedFromDiagramEditor(part, selection); handleSelectionChange(part, selection); } }; /** * Listener on {@link ISaveAndDirtyService#addInputChangedListener(IEditorInputChangedListener)} */ protected IEditorInputChangedListener editorInputChangedListener = new IEditorInputChangedListener() { /** * This method is called when the editor input is changed from the ISaveAndDirtyService. * * @see org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener#editorInputChanged(org.eclipse.ui.part.FileEditorInput) * * @param fileEditorInput */ public void editorInputChanged(FileEditorInput fileEditorInput) { // Change the editor input. setPartName(fileEditorInput.getName()); } /** * The isDirty flag has changed, reflect its new value * * @see org.eclipse.papyrus.infra.core.lifecycleevents.IEditorInputChangedListener#isDirtyChanged() * */ public void isDirtyChanged() { // firePropertyChange(IEditorPart.PROP_DIRTY); } }; // public ApexStellaExplorerView(IMultiDiagramEditor part) { // super(part); // // TODO Auto-generated constructor stub // } public ApexStellaExplorerView() { super(); setLinkingEnabled(true); } /** * apex updated * Editor 또는 Diagram이 바뀌는 경우 해당 Editor의 serviceRegistry가져와서 * editingDomain, saveAndDirtyService, undoContext setting * * Handle a selection change in the editor. * * @param part * @param selection */ private void handleSelectionChangedFromDiagramEditor(IWorkbenchPart part, ISelection selection) { // Handle selection from diagram editor if(isLinkingEnabled()) { if(part instanceof IEditorPart) { if(selection instanceof IStructuredSelection) { Iterator<?> selectionIterator = ((IStructuredSelection)selection).iterator(); ArrayList<Object> semanticElementList = new ArrayList<Object>(); while(selectionIterator.hasNext()) { Object currentSelection = selectionIterator.next(); if(currentSelection instanceof IAdaptable) { Object semanticElement = ((IAdaptable)currentSelection).getAdapter(EObject.class); if(semanticElement != null) { semanticElementList.add(semanticElement); } } } revealSemanticElement(semanticElementList); } } } } private ITreeSelection getRoot(ITreeSelection iTreeElement) { // ITreeSelection parent = iTreeElement..getTreeParent(); // if ( parent != null ) { // getRoot(parent); // } return iTreeElement; } private void setEditingDomainFromServicesRegistry(ServicesRegistry servicesRegistry) { try { editingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry); // this.editingDomain = EditorUtils.getTransactionalEditingDomain(editorPart.getServicesRegistry()); // Set Viewer input if it already exist // if(getCommonViewer() != null) { // getCommonViewer().setInput(serviceRegistry); // } saveAndDirtyService = serviceRegistry.getService(ISaveAndDirtyService.class); undoContext = serviceRegistry.getService(IUndoContext.class); editingDomain.addResourceSetListener(resourceSetListener); saveAndDirtyService.addInputChangedListener(editorInputChangedListener); } catch (ServiceException e) { // Can't get EditingDomain, skip e.printStackTrace(); } } private void setServiceRegistryFromEditor(PapyrusMultiDiagramEditor editor) { PapyrusMultiDiagramEditor papyrusEditor = (PapyrusMultiDiagramEditor)editor; serviceRegistry = papyrusEditor.getServicesRegistry(); setEditingDomainFromServicesRegistry(serviceRegistry); } private void setServiceRegistryFromExplorer(ITreeSelection treeSelection) { serviceRegistry = ApexModelTreeUtil.getServicesRegistryFromModelTreeSelection(treeSelection); setEditingDomainFromServicesRegistry(serviceRegistry); } /** * Selection 이 바뀌었을 경우 처리 * 탐색기의 요소를 select할 경우 해당 요소가 있는 모델 에디터에서 ServiceRegistry가져와서 세팅 * 선택이 여러 모델에 걸쳐 있을 경우 최종 선택 요소의 모델 에디터를 기준으로 처리 * * ModelExplorer의 선택에 따라 해당 요소의 View를 Editor에서 reveal하도록 구현하려 했으나 실패 * 현재 Editor선택에 따라 ServiceRegistry를 구성하는 역할 수행 * * @param part * @param selection */ private void handleSelectionChange(IWorkbenchPart part, ISelection selection) { PapyrusMultiDiagramEditor editorPart = null; /* apex added start */ if ( part instanceof ApexStellaExplorerView ) { if ( selection instanceof ITreeSelection ) { ITreeSelection aTreeSelection = (ITreeSelection)selection; TreePath[] treePaths = aTreeSelection.getPaths(); for ( TreePath aTreePath : treePaths ) { if ( aTreePath.getLastSegment() instanceof ModelElementItem ) { editorPart = ApexModelTreeUtil.getEditorPartFromModelTreeSelection(aTreeSelection); if ( editorPart != null ) { setServiceRegistryFromEditor(editorPart); } else { if ( !aTreeSelection.isEmpty() ) { setServiceRegistryFromExplorer(aTreeSelection); } } } } } } else if ( part instanceof PapyrusMultiDiagramEditor ) { setServiceRegistryFromEditor((PapyrusMultiDiagramEditor)part); } // System.out.println("part.getEditorSite().getId() : " + ((PapyrusMultiDiagramEditor) part).getEditorSite().getId()); // if(selection instanceof IStructuredSelection) { //System.out.println("ApexStellaExplorerView.handleSelectionChange(), line " // + Thread.currentThread().getStackTrace()[1].getLineNumber()); // // String selectedModelName = null; // IStructuredSelection structuredSelection = (IStructuredSelection)selection; // // Iterator its = structuredSelection.iterator(); // for ( int i = 0 ; its.hasNext() ; i++ ) { // Object obj = its.next(); // if ( obj instanceof ITreeElement ) { // ITreeElement itree = (ITreeElement)obj; // System.out.println(" structuredSelection["+i+"].getText() : " + itree.getText()); // System.out.println(" structuredSelection["+i+"] : " + itree); // } // // } // // Iterator it = structuredSelection.iterator(); // while(it.hasNext()) { // Object obj = it.next(); // // if ( obj instanceof EditPart ) { // return; // } else if ( obj instanceof IFile ) { // IFile diFile = (IFile)obj; // // if(OneFileUtils.isDi(diFile)) { // selectedModelName = diFile.getName(); // } // System.out.println(" obj instanceof IFile"); // System.out.println(" obj : " + obj); // } else if ( obj instanceof ITreeElement ) { // ITreeElement modelItem = (ITreeElement)obj; // ITreeElement modelImplElement = getDiWrapperFromChildren(modelItem); // // if ( modelImplElement instanceof ApexDIWrapper ) { // selectedModelName = ((ApexDIWrapper)modelImplElement).getFile().getName(); // } else { // System.out.println("getDIWrapper()가 DI가 아닌 것을 반환했다!!"); // System.out.println(" selected ModelItem.getText() : " + modelItem.getText()); // System.out.println(" selected ModelItem : " + modelItem); // System.out.println(" returned ITreeElement from getDIWrapper() : " + modelImplElement); // } // System.out.println(" obj instanceof ITreeElement"); // System.out.println(" obj : " + obj); // } else { // System.out.println(" obj is fucking mess"); // System.out.println(" obj : " + obj); // } // // System.out.println(" selectedModelName : " + selectedModelName); // } // // IWorkbenchPage workbenchPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); // IEditorReference[] editorRefs = workbenchPage.getEditorReferences(); // // for ( IEditorReference editorRef : editorRefs ) { // IEditorPart editorPart = editorRef.getEditor(true); // String editorName = editorPart.getTitle(); // // if ( editorName.equals(selectedModelName) ) { // System.out.println(" editorName : " + editorName); // workbenchPage.activate(editorPart); // } // } // } // /* apex added start */ // if ( part instanceof PapyrusMultiDiagramEditor ) { // // PapyrusMultiDiagramEditor papyrusEditor = (PapyrusMultiDiagramEditor)part; // serviceRegistry = papyrusEditor.getServicesRegistry(); // try { // editingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry); // // this.editingDomain = EditorUtils.getTransactionalEditingDomain(editorPart.getServicesRegistry()); // // Set Viewer input if it already exist //// if(getCommonViewer() != null) { //// getCommonViewer().setInput(serviceRegistry); //// } // saveAndDirtyService = serviceRegistry.getService(ISaveAndDirtyService.class); // undoContext = serviceRegistry.getService(IUndoContext.class); // // editingDomain.addResourceSetListener(resourceSetListener); // saveAndDirtyService.addInputChangedListener(editorInputChangedListener); // } catch (ServiceException e) { // // Can't get EditingDomain, skip // e.printStackTrace(); // } // } /* apex added end */ } // private ITreeElement getDiWrapperFromChildren(ITreeElement modelItem) { // // ITreeElement diWrapper = null; // ITreeElement parentItem = modelItem.getTreeParent(); // // if ( parentItem != null ) { // System.out.println(" selectedItem.getText() : " + modelItem.getText()); // System.out.println(" selectedItem : " + modelItem); // System.out.println(" parentItem.getText() : " + parentItem.getText()); // System.out.println(" parentItem : " + parentItem); // // // if (parentItem instanceof ModelElementItem // || parentItem instanceof LinkItem) { // parentItem = getDiWrapperFromChildren((ITreeElement)parentItem); // } // if (parentItem instanceof ApexDIWrapper) { // diWrapper = (ApexDIWrapper)parentItem; // } else { // System.out // .println("ApexStellaExplorerView.getDiFileFromChildren(), line " // + Thread.currentThread().getStackTrace()[1] // .getLineNumber()); // System.out.println(" di없다"); // System.out.println(" parentItem : " + parentItem); // } // } else { // System.out.println("In getDIWrapper(), parentItem이 null이다"); // System.out.println(" modelItem.getText() : " + modelItem.getText()); // System.out.println(" modelItem : " + modelItem); // } // return diWrapper; // } /** * look for the path the list of element (comes from the content provider) to go the eObject * * @param eobject * that we look for. * @param objects * a list of elements where eobject can be wrapped. * @return the list of modelElementItem ( from the root to the element that wrap the eobject) */ protected List<Object> searchPath(EObject eobject, List<Object> objects) { SemanticFromModelExplorer semanticGetter = new SemanticFromModelExplorer(); List<Object> path = new ArrayList<Object>(); ITreeContentProvider contentProvider = (ITreeContentProvider)getCommonViewer().getContentProvider(); // IPageMngr iPageMngr = EditorUtils.getIPageMngr(); IPageMngr iPageMngr; try { iPageMngr = ServiceUtils.getInstance().getIPageMngr(serviceRegistry); } catch (ServiceException e) { // This shouldn't happen. return Collections.emptyList(); } Object[] result = iPageMngr.allPages().toArray(); List<Object> editors = Arrays.asList(result); for(Object o : objects) { // Search matches in this level // if(!(o instanceof Diagram) && o instanceof IAdaptable) { if(!editors.contains(o) && o instanceof IAdaptable) { if(eobject.equals(((IAdaptable)o).getAdapter(EObject.class))) { path.add(o); return path; } } // Find childs only for feature container for(int i = 0; i < contentProvider.getChildren(o).length; i++) { Object treeItem = contentProvider.getChildren(o)[i]; List<Object> tmppath = new ArrayList<Object>(); Object element = semanticGetter.getSemanticElement(treeItem); if(element != null) { if(element instanceof EReference) { if(((EReference)element).isContainment() && (!((EReference)element).isDerived())) { List<Object> childs = new ArrayList<Object>(); childs.add(treeItem); tmppath = searchPath(eobject, childs); } } else { if(element instanceof EObject) { List<Object> childs = new ArrayList<Object>(); childs.add(treeItem); tmppath = searchPath(eobject, childs); } } } // if tmppath contains the wrapped eobject we have find the good path if(tmppath.size() > 0) { if(tmppath.get(tmppath.size() - 1) instanceof IAdaptable) { if(eobject.equals(((IAdaptable)(tmppath.get(tmppath.size() - 1))).getAdapter(EObject.class))) { path.add(o); path.addAll(tmppath); return path; } } } } } return new ArrayList<Object>(); } /** * {@inheritDoc} */ // FIXME Use of internal class (NavigatorContentService) - in the hope that the bug gets fixed soon. @Override protected CommonViewer createCommonViewerObject(Composite aParent) { CommonViewer viewer = new CustomCommonViewer(getViewSite().getId(), aParent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); // enable tool-tips // workaround for bug 311827: the Common Viewer always uses NavigatorDecoratingLabelProvider // as a wrapper for the LabelProvider provided by the application. The NavigatorDecoratingLabelProvider // does not delegate tooltip related functions but defines them as empty. NavigatorContentService contentService = new NavigatorContentService(getViewSite().getId()); @SuppressWarnings("unchecked") // get label provider from content service (which in turn evaluates extension points in // function of the input) Set<Object> descriptors = contentService.findDescriptorsByTriggerPoint(getInitialInput(), false); for(Object descriptor : descriptors) { if(descriptor instanceof NavigatorContentDescriptor) { try { ILabelProvider labelProvider = ((NavigatorContentDescriptor)descriptor).createLabelProvider(); viewer.setLabelProvider(new ApexDecoratingLabelProviderWTooltips(labelProvider)); // add for decorator and tooltip support } catch (CoreException e) { Activator.log.error(e); } break; } } ColumnViewerToolTipSupport.enableFor(viewer, ToolTip.NO_RECREATE); return viewer; } @Override public void createPartControl(Composite aParent) { super.createPartControl(aParent); // getCommonViewer().setSorter(new CommonViewerSorter()); ((CustomCommonViewer)getCommonViewer()).getDropAdapter().setFeedbackEnabled(true); getCommonViewer().addDoubleClickListener(new ApexDoubleClickListener()); Tree tree = getCommonViewer().getTree(); Activator.getDefault().getCustomizationManager().installCustomPainter(tree); // makeApexCustomContextMenu(aParent); } private void makeApexCustomContextMenu(Composite aParent) { // final List<IContributionItem> contextMenuItemList = new ArrayList<IContributionItem>(); // IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); // // if ( window instanceof WorkbenchWindow ) { // MenuManager menuMgr = ((WorkbenchWindow)window).getMenuManager(); // // IContributionItem[] items = menuMgr.getItems(); // System.out // .println("ApexStellaExplorerView.createPartControl(), line " // + Thread.currentThread().getStackTrace()[1] // .getLineNumber()); // System.out.println(" from Window Menu Manager"); // // for ( IContributionItem item : items ) { // String menuId = item.getId(); // System.out.println(" " + menuId); // // if ( item != null && item.getId() != null ) { // if ( menuId.equals("file") ) { // contextMenuItemList.add(item); // } // } // } // } // // MenuManager menuMgr = new MenuManager("#Popup") { // @Override // public IContributionItem[] getItems() { // // IContributionItem[] items = super.getItems(); // System.out.println(" super.getItems().length : " + super.getItems().length); // List<IContributionItem> filteredItems = new ArrayList<IContributionItem> (); // filteredItems.addAll(contextMenuItemList); // System.out.println("filteredItems : " + filteredItems); // // for ( IContributionItem aItem : filteredItems) { // System.out.println(" item from filtered : " + aItem); // if ( aItem instanceof MenuManager ) { // MenuManager aMenuManager = (MenuManager)aItem; // IContributionItem[] aSubofItem = aMenuManager.getItems(); // // for ( IContributionItem aofaItem : aSubofItem ) { // System.out.println(" sub of filtered : " + aofaItem); // } // } // } // // System.out // .println("ApexStellaExplorerView.createPartControl(), line " // + Thread.currentThread().getStackTrace()[1] // .getLineNumber()); // System.out.println(" contextFromMain : " + contextMenuItemList); // System.out.println(" from Overriding"); // // for ( IContributionItem menuItem : items ) { // String menuId = menuItem.getId(); // System.out.println(" menuItem : " + menuItem); // System.out.println(" menuItem.getId() : " + menuId); // // if ( menuItem!=null && menuItem.getId()!=null) { // if ( !menuId.equals("org.eclipse.papyrus.uml.diagram.ui.menu") // && !menuId.equals("org.eclipse.papyrus.ui.menu") // && !menuId.equals("org.eclipse.debug.ui.contextualLaunch.run.submenu") // && !menuId.equals("org.eclipse.debug.ui.contextualLaunch.debug.submenu") // && !menuId.equals("org.eclipse.ui.projectConfigure") // && !menuId.equals("org.eclipse.modisco.infra.discovery.ui.menu") // ) { // filteredItems.add(menuItem); // System.out.println(" added : " + menuItem); // } else { // System.out.println(" not added : " + menuItem); // } // } // // } // items = new IContributionItem[ filteredItems.size()]; // return filteredItems.toArray( items ); // } // }; // Menu menu = menuMgr.createContextMenu(aParent); // getCommonViewer().getControl().setMenu(menu); // getSite().registerContextMenu(menuMgr, getCommonViewer()); // MenuManager menuMgr = new MenuManager("#Popup") { // @Override // public IContributionItem[] getItems() { // // IContributionItem[] items = super.getItems(); // List<IContributionItem> filteredItems = new ArrayList<IContributionItem> (); // System.out // .println("ApexStellaExplorerView.createPartControl(...).new MenuManager() {...}.getItems(), line " // + Thread.currentThread() // .getStackTrace()[1] // .getLineNumber()); // // for( IContributionItem item : items ) { // // if( item != null // && item.getId() != null //// && !item.getId().startsWith( "org.eclipse.debug.ui.contextualLaunch." ) //// || item.getId().startsWith("kr.co.apexsoft.") //// || item.getId().startsWith("org.eclipse.ui.navigator.resources.") //// ) // ) { // System.out.println(" menuItem : " + item.getId()); // filteredItems.add( item ); // } // // } // // items = new IContributionItem[ filteredItems.size()]; // return filteredItems.toArray( items ); // } // // }; // Menu menu = menuMgr.createContextMenu(aParent); // getCommonViewer().getTree().setMenu(menu); // getSite().registerContextMenu(menuMgr, getCommonViewer()); } /** * Return the control used to render this View * * @see org.eclipse.papyrus.views.modelexplorer.core.ui.pagebookview.IPageBookNestableViewPart#getControl() * * @return the main control of the navigator viewer */ public Control getControl() { return getCommonViewer().getControl(); } /** * {@inheritDoc} */ @Override public void init(IViewSite site, IMemento aMemento) throws PartInitException { super.init(site, aMemento); // Hook undo/redo action // hookGlobalHistoryHandler(site); // page.addPartListener(partListener); activate(); } /** * {@inheritDoc} */ @Override public void init(IViewSite site) throws PartInitException { super.init(site); IWorkbenchPage page = site.getPage(); // an ISelectionListener to react to workbench selection changes. page.addSelectionListener(pageSelectionListener); // ISelectionProvider selectionProvider = site.getSelectionProvider(); // selectionProvider.addSelectionChangedListener(selectionChangeListener); } /** * Hook the global undo/redi actions. */ // private void hookGlobalHistoryHandler(IViewSite site) { // undoHandler = new UndoActionHandler(site, null); // redoHandler = new RedoActionHandler(site, null); // // IActionBars actionBars = site.getActionBars(); // // actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undoHandler); // actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redoHandler); // } /** * {@link ResourceSetListener} to listen and react to changes in the * resource set. */ private final ResourceSetListener resourceSetListener = new ResourceSetListenerImpl() { /** * {@inheritDoc} */ @Override public void resourceSetChanged(ResourceSetChangeEvent event) { super.resourceSetChanged(event); handleResourceSetChanged(event); } }; /** cache variable with last transaction which triggered a refresh */ private Transaction lastTrans = null; /** * Run in a UI thread to avoid non UI thread exception. * * @param event */ private void handleResourceSetChanged(ResourceSetChangeEvent event) { // avoid refreshing N times for the same transaction (called for each object in resource) Transaction curTrans = event.getTransaction(); if(lastTrans != null && lastTrans.equals(curTrans)) { return; } lastTrans = curTrans; PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { /** * {@inheritDoc} */ public void run() { refresh(); } }); } /** * refresh the view. */ public void refresh() { // Need to refresh, even if (temporarily) invisible // (Better alternative?: store refresh event and execute once visible again) if(getControl().isDisposed()) { return; } // avoid reentrant call // Refresh only of we are not already refreshing. if(isRefreshing.compareAndSet(false, true)) { if(!getCommonViewer().isBusy()) { getCommonViewer().refresh(); } isRefreshing.set(false); } } /** * {@inheritDoc} */ @Override protected Object getInitialInput() { Object initialInput = null; // if(serviceRegistry != null) { // initialInput = serviceRegistry; // } else { // initialInput = super.getInitialInput(); // } initialInput = super.getInitialInput(); return initialInput; } /** * Activate specified Part. */ private void activate() { if(this.getCommonViewer() != null) { refresh(); } } /** * Deactivate the Model Explorer. */ private void deactivate() { // deactivate global handler if(Activator.log.isDebugEnabled()) { Activator.log.debug("deactivate ModelExplorerView"); //$NON-NLS-1$ } // Stop listening on change events getSite().getPage().removeSelectionListener(pageSelectionListener); // Stop Listening to isDirty flag saveAndDirtyService.removeInputChangedListener(editorInputChangedListener); // unhook // IUndoContext undoContext = getUndoContext(editorPart); // undoHandler.setContext(undoContext); // undoHandler.update(); // redoHandler.setContext(undoContext); // redoHandler.update(); if(editingDomain != null) { editingDomain.removeResourceSetListener(resourceSetListener); editingDomain = null; } this.removeListenerObject(pageSelectionListener); } /** * {@inheritDoc} */ @Override public void dispose() { // Stop if we are already disposed if(isDisposed()) { return; } deactivate(); saveAndDirtyService = null; undoContext = null; editingDomain = null; serviceRegistry = null; super.dispose(); // Clean up properties to help GC } /** * Return true if the component is already disposed. * * @return */ public boolean isDisposed() { // use editorPart as flag return saveAndDirtyService == null; } /** * Retrieves the {@link IPropertySheetPage} that his Model Explorer uses. * * @return */ private IPropertySheetPage getPropertySheetPage() { final IMultiDiagramEditor multiDiagramEditor = EditorUtils.getMultiDiagramEditor(); if(multiDiagramEditor != null) { if(propertySheetPage == null) { if(multiDiagramEditor instanceof ITabbedPropertySheetPageContributor) { ITabbedPropertySheetPageContributor contributor = (ITabbedPropertySheetPageContributor)multiDiagramEditor; this.propertySheetPage = new TabbedPropertySheetPage(contributor); } } return propertySheetPage; } return null; } /** * in order to see element if the property view */ @Override @SuppressWarnings("rawtypes") public Object getAdapter(Class adapter) { if(IPropertySheetPage.class.equals(adapter)) { return getPropertySheetPage(); } if(IUndoContext.class == adapter) { // Return the IUndoContext of associated model. return undoContext; } if(ISaveablePart.class.equals(adapter)) { return saveAndDirtyService; } if(ServicesRegistry.class == adapter) { return serviceRegistry; } return super.getAdapter(adapter); } /** * {@inheritDoc} * * @return the EditingDomain used by the properties view */ public EditingDomain getEditingDomain() { return editingDomain; } /** * {@inheritDoc} */ @Override public void selectReveal(ISelection selection) { if(getCommonViewer() != null) { getCommonViewer().setSelection(selection, true); } } public void revealSemanticElement(List<?> elementList) { reveal(elementList, getCommonViewer()); } /** * apex updated * * 다이어그램 추가 시에도 reveal & select 되도록 처리 * 다이어그램의 경우 currentEObject.eContainer() 가 null 이라서 currentEObject.getElement()를 사용하도록 수정 * * Expands the given CommonViewer to reveal the given elements * @param elementList The elements to reveal * @param commonViewer The CommonViewer they are to be revealed in */ public static void reveal(Iterable<?> elementList, CommonViewer commonViewer) { ArrayList<IMatchingItem> matchingItemsToSelect = new ArrayList<IMatchingItem>(); // filter out non EMF objects Iterable<EObject> list = Iterables.transform(Iterables.filter(elementList, EObject.class), new Function<Object, EObject>() { public EObject apply(Object from) { return (EObject)from; } }); for(EObject currentEObject : list) { matchingItemsToSelect.add(new ModelElementItemMatchingItem(currentEObject)); // the content provider exist? if(commonViewer.getContentProvider() != null /* apex added start */ && !commonViewer.isBusy()) { /* apex added end */ // retrieve the ancestors to reveal them // and allow the selection of the object ArrayList<EObject> parents = new ArrayList<EObject>(); /* apex improved started */ EObject tmp = currentEObject.eContainer(); if ( tmp == null && (currentEObject instanceof Diagram) ) { Diagram diagram = (Diagram)currentEObject; tmp = diagram.getElement(); } /* apex improved end */ //* apex replaced // EObject tmp = currentEObject.eContainer(); //*/ while(tmp != null) { parents.add(tmp); tmp = tmp.eContainer(); } Iterable<EObject> reverseParents = Iterables.reverse(parents); // reveal the resource if necessary Resource r = null; if (!parents.isEmpty()) { r = parents.get(parents.size() - 1).eResource(); } else { r = currentEObject.eResource(); } if (r != null) { ResourceSet rs = r.getResourceSet(); if (rs instanceof ModelSet && AdditionalResourcesModel.isAdditionalResource((ModelSet)rs, r.getURI())) { commonViewer.expandToLevel(new ReferencableMatchingItem(rs), 1); commonViewer.expandToLevel(new ReferencableMatchingItem(r), 1); } } /* * reveal the ancestors tree using expandToLevel on each of them * in the good order. This is a lot faster than going through the whole tree * using getChildren of the ContentProvider since our Viewer uses a Hashtable * to keep track of the revealed elements. * * However we need to use a dedicated MatchingItem to do the matching, * and a specific comparer in our viewer so than the equals of MatchingItem is * used in priority. * * Please refer to MatchingItem for more infos. */ EObject previousParent = null; for(EObject parent : reverseParents) { if(parent.eContainingFeature() != null && previousParent != null) { commonViewer.expandToLevel(new LinkItemMatchingItem(previousParent, parent.eContainmentFeature()), 1); } commonViewer.expandToLevel(new ModelElementItemMatchingItem(parent), 1); previousParent = parent; } commonViewer.expandToLevel(new LinkItemMatchingItem(currentEObject.eContainer(), currentEObject.eContainmentFeature()), 1); } } selectReveal(new StructuredSelection(matchingItemsToSelect), commonViewer); } /** * Selects the given ISelection in the given CommonViwer * @param structuredSelection The ISelection to select * @param commonViewer The ComonViewer to select it in */ public static void selectReveal(ISelection structuredSelection, Viewer commonViewer) { commonViewer.setSelection(structuredSelection, true); } /** * Selects and, if possible, reveals the given ISelection in the given CommonViwer * @param selection The ISelection to select * @param viewer The ComonViewer to select it in */ public static void reveal(ISelection selection, CommonViewer viewer) { if(selection instanceof IStructuredSelection) { IStructuredSelection structured = (IStructuredSelection)selection; reveal(Lists.newArrayList(structured.iterator()), viewer); } else { viewer.setSelection(selection); } } protected void warnUser(ModelMultiException e) { MessageDialog.openError(getSite().getShell(), "Error", String.format("Your model is corrupted, invalid links have been found :\n" + "%s" + "It is recommended to fix it before editing it", e.getMessage())); } /** * {@inheritDoc} */ public String getContributorId() { // return Activator.PLUGIN_ID; // papyrus 내용 재사용. xml에서 TreeOutlinePage 검색으로 분석 가능 // 실제는 MultiDiagramEditor의 getContributorId()에 명시되어 있는 것이 유효 return "TreeOutlinePage"; //$NON-NLS-1$ } public class ApexDoubleClickListener implements IDoubleClickListener { public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); // IPageMngr pageMngr = null; // //get the page Manager // try { // pageMngr = ServiceUtilsForActionHandlers.getInstance().getIPageMngr(); // } catch (Exception e) { // Activator.log.error(Messages.DoubleClickListener_Error_NoLoadManagerToOpen, e); // } // if(pageMngr != null) { if(selection instanceof IStructuredSelection) { Iterator<?> iter = ((IStructuredSelection)selection).iterator(); while(iter.hasNext()) { Object currentObject = iter.next(); if ( currentObject instanceof IFile ) { // 에디터 열고 IEditorPart editor = null; IFile diFile = (IFile)currentObject; if(OneFileUtils.isDi(diFile)) { editor = ApexStellaProjectMap.openEditor(diFile); } if ( editor != null && editor instanceof PapyrusMultiDiagramEditor ) { ServicesRegistry servicesRegistry = ((PapyrusMultiDiagramEditor)editor).getServicesRegistry(); ApexStellaProjectMap.setUpModelServices(diFile, servicesRegistry); Viewer aViewer = event.getViewer(); aViewer.refresh(); } } else if ( currentObject instanceof ModelElementItem ) { //Diagram 더블클릭 시 오픈 ModelElementItem mItem = (ModelElementItem)currentObject; EObject eObj = mItem.getEObject(); if ( eObj instanceof DiagramImpl ) { // 해당 다이어그램이 있는 에디터를 활성화 IEditorPart tmpEditorPart = null; if ( selection instanceof ITreeSelection ) { ITreeSelection aTreeSelection = (ITreeSelection)selection; TreePath[] treePaths = aTreeSelection.getPaths(); for ( TreePath aTreePath : treePaths ) { if ( aTreePath.getLastSegment() instanceof ModelElementItem ) { tmpEditorPart = ApexModelTreeUtil.getEditorPartFromModelTreeSelection(aTreeSelection); } } } IWorkbenchPage workbenchPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); IEditorReference[] editorRefs = workbenchPage.getEditorReferences(); for ( IEditorReference editorRef : editorRefs ) { IEditorPart editorPart = editorRef.getEditor(true); if ( editorPart.equals(tmpEditorPart) ) { workbenchPage.activate(editorPart); } } // 해당 다이어그램을 활성화 IPageMngr pageMngr = null; try { pageMngr = ServiceUtilsForActionHandlers.getInstance().getIPageMngr(); } catch (ServiceException e) { Activator.log.error(Messages.DoubleClickListener_Error_NoLoadManagerToOpen, e); } /* apex // * 별도의 activate나 setFocus같은 활성화 방법이 없어 기존 페이지를 닫고 새로 여는 것으로 활성화 처리 // * 닫고 추가로 여는 방법이므로 가장 마지막 페이지에서 활성화되며, // * 원래 있던 자리에서 활성화되게 하려면 TabFolderImpl의 movePage() 이용 // */ if ( pageMngr.isOpen(eObj)) { pageMngr.closePage(eObj); } pageMngr.openPage(eObj); } } } } } } @Override public ServicesRegistry getServicesRegistry() { return serviceRegistry; } public void nullifyServicesRegistry() { serviceRegistry = null; } }