/* * ==================================================================== * * The ObjectStyle Group Software License, Version 1.0 * * Copyright (c) 2007 The ObjectStyle Group and individual authors of the * software. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: 1. * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. 2. Redistributions in * binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. 3. The end-user documentation * included with the redistribution, if any, must include the following * acknowlegement: "This product includes software developed by the ObjectStyle * Group (http://objectstyle.org/)." Alternately, this acknowlegement may * appear in the software itself, if and wherever such third-party * acknowlegements normally appear. 4. The names "ObjectStyle Group" and * "Cayenne" must not be used to endorse or promote products derived from this * software without prior written permission. For written permission, please * contact andrus@objectstyle.org. 5. Products derived from this software may * not be called "ObjectStyle" nor may "ObjectStyle" appear in their names * without prior written permission of the ObjectStyle Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * OBJECTSTYLE GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many individuals * on behalf of the ObjectStyle Group. For more information on the ObjectStyle * Group, please see <http://objectstyle.org/> . * */ package org.objectstyle.wolips.componenteditor.part; import java.util.ArrayList; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IShowEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.ide.ResourceUtil; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.ui.part.MultiPageSelectionProvider; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.objectstyle.wolips.baseforuiplugins.IEditorTarget; import org.objectstyle.wolips.componenteditor.outline.ComponentEditorOutline; import org.objectstyle.wolips.components.editor.ComponentEditorInteraction; import org.objectstyle.wolips.components.editor.IComponentEditor; import org.objectstyle.wolips.components.input.ComponentEditorInput; import org.objectstyle.wolips.templateeditor.TemplateEditor; import org.objectstyle.wolips.wodclipse.editor.WodEditor; /** * @author uli */ public class ComponentEditorPart extends MultiPageEditorPart implements IEditorTarget, IResourceChangeListener, IComponentEditor, IShowEditorInput { private int htmlPageId; private int wodPageId; private int wooPageId; private int previewPageId; private int apiPageId; ComponentEditorInput componentEditorInput; private ComponentEditorInteraction editorInteraction = new ComponentEditorInteraction(); private ComponentEditorOutline componentEditorOutline; private HtmlWodTab[] htmlWodTabs; private HtmlPreviewTab htmlPreviewTab; private ApiTab apiTab; private ComponentEditorTab[] componentEditorTabs; // Frank public boolean _tabsInitialized = false; private boolean _saving; public ComponentEditorPart() { super(); ResourcesPlugin.getWorkspace().addResourceChangeListener(this); editorInteraction.setComponentEditor(this); } public boolean embeddedEditorWillSave(IProgressMonitor progressMonitor) { boolean saveEmbeddedEditor = true; if (!_saving) { saveEmbeddedEditor = false; doSave(progressMonitor); } return saveEmbeddedEditor; } @Override public void addPage(int index, IEditorPart editor, IEditorInput input) throws PartInitException { super.addPage(index, editor, input); } private ComponentEditorOutline getComponentEditorOutline() { if (componentEditorOutline == null) { componentEditorOutline = new ComponentEditorOutline(); } return componentEditorOutline; } public Object getAdapter(Class adapter) { if (adapter.equals(IContentOutlinePage.class)) { return this.getComponentEditorOutline(); } return super.getAdapter(adapter); } public void init(IEditorSite site, IEditorInput input) throws PartInitException { super.init(site, input); componentEditorInput = (ComponentEditorInput) input; if (input != null) { String inputName = input.getName(); setPartName(inputName); } site.setSelectionProvider(new ComponentEditorPartSelectionProvider(this)); } public IEditorInput getEditorInput() { if (componentEditorTabs == null) { return null; } else if (this.getActivePage() < 0) { return null; } return componentEditorTabs[this.getActivePage()].getActiveEditorInput(); } protected void createPages() { if (componentEditorInput == null) { return; } IEditorInput[] editorInput = componentEditorInput.getComponentEditors(); ArrayList<ComponentEditorTab> componentEditorTabsList = new ArrayList<ComponentEditorTab>(); ArrayList<HtmlWodTab> htmlWodTabsList = new ArrayList<HtmlWodTab>(); // htmlwod tabs IFileEditorInput htmlInput = null; IFileEditorInput wodInput = null; IFileEditorInput wooInput = null; int inputsPerComponent = 3; int tabIndex = 0; boolean hasMultipleComponents = editorInput.length > inputsPerComponent; for (int componentNum = 0; componentNum < editorInput.length; componentNum += inputsPerComponent) { htmlInput = (IFileEditorInput) editorInput[componentNum + 0]; wodInput = (IFileEditorInput) editorInput[componentNum + 1]; wooInput = (IFileEditorInput) editorInput[componentNum + 2]; String language = null; if (hasMultipleComponents) { language = ComponentEditorInput.getLanguageName(htmlInput); if (language == null) { language = ComponentEditorInput.getLanguageName(wodInput); if (language == null) { language = ComponentEditorInput.getLanguageName(wooInput); } } if (language == null) { language = ""; } else { language = language + " "; } } else { language = ""; } HtmlWodTab htmlWodTab = new HtmlWodTab(this, tabIndex, htmlInput, wodInput); componentEditorTabsList.add(htmlWodTab); htmlWodTabsList.add(htmlWodTab); htmlWodTab.createTab(); htmlPageId = this.addPage(htmlWodTab); wodPageId = htmlPageId; this.setPageText(tabIndex, language + "Component"); tabIndex++; WooTab wooTab = new WooTab(this, tabIndex, wooInput); componentEditorTabsList.add(wooTab); wooTab.createTab(); wooPageId = this.addPage(wooTab); this.setPageText(tabIndex, language + "Display Groups"); tabIndex++; } if (componentEditorInput.getStandaloneHtmlEditor() != null) { IFileEditorInput standaloneHtmlInput = (IFileEditorInput) componentEditorInput.getStandaloneHtmlEditor(); HtmlWodTab htmlWodTab = new HtmlWodTab(this, tabIndex, standaloneHtmlInput, null); componentEditorTabsList.add(htmlWodTab); htmlWodTabsList.add(htmlWodTab); htmlWodTab.createTab(); htmlPageId = this.addPage(htmlWodTab); wodPageId = htmlPageId; this.setPageText(tabIndex, "HTML"); tabIndex++; } if (componentEditorInput.getStandaloneHtmlEditor() == null) { // api tab IFileEditorInput apiInput = (IFileEditorInput) componentEditorInput.getApiEditor(); apiTab = new ApiTab(this, tabIndex, apiInput); componentEditorTabsList.add(apiTab); apiTab.createTab(); apiPageId = this.addPage(apiTab); this.setPageText(tabIndex, "Api"); tabIndex++; } if (editorInput.length > 0) { // html preview tab htmlPreviewTab = new HtmlPreviewTab(this, tabIndex, htmlInput); componentEditorTabsList.add(htmlPreviewTab); htmlPreviewTab.createTab(); previewPageId = this.addPage(htmlPreviewTab); this.setPageText(tabIndex, "Preview (Experimental)"); tabIndex++; } componentEditorTabs = componentEditorTabsList.toArray(new ComponentEditorTab[componentEditorTabsList.size()]); htmlWodTabs = htmlWodTabsList.toArray(new HtmlWodTab[htmlWodTabsList.size()]); CTabFolder tabFolder = (CTabFolder) this.getContainer(); tabFolder.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { ComponentEditorPart.this.updateOutline(); } public void widgetDefaultSelected(SelectionEvent e) { return; } }); if (componentEditorInput.isDisplayWodPartOnReveal()) { this.switchToWod(); } else if (componentEditorInput.isDisplayWooPartOnReveal()) { this.switchToWoo(); } else if (componentEditorInput.isDisplayApiPartOnReveal()) { this.switchToApi(); } else if (componentEditorInput.isDisplayHtmlPartOnReveal()) { this.switchToHtml(); } // Frank _tabsInitialized = true; return; } public void doSave(IProgressMonitor monitor) { _saving = true; try { for (int i = 0; i < componentEditorTabs.length; i++) { if (componentEditorTabs[i] != null && componentEditorTabs[i].isDirty()) { componentEditorTabs[i].doSave(monitor); } } return; } finally { _saving = false; } } public void close(boolean save) { for (int i = 0; i < componentEditorTabs.length; i++) { if (componentEditorTabs[i] != null) { componentEditorTabs[i].close(save); } } } public void doSaveAs() { assert false; return; } public boolean isSaveAsAllowed() { return false; } public void updateOutline() { IEditorPart editorPart = this.getActiveEditor(); if (editorPart != null) { IContentOutlinePage contentOutlinePage = (IContentOutlinePage) editorPart.getAdapter(IContentOutlinePage.class); this.getComponentEditorOutline().setPageActive(contentOutlinePage); } } public boolean isDirty() { if (super.isDirty()) { return true; } for (int i = 0; i < componentEditorTabs.length; i++) { if (componentEditorTabs[i].isDirty()) { return true; } } return false; } public IEditorPart switchTo(int targetEditorID) { switch (targetEditorID) { case IEditorTarget.TARGET_API: this.switchToApi(); break; case IEditorTarget.TARGET_HTML: this.switchToHtml(); break; case IEditorTarget.TARGET_PREVIEW: this.switchToPreview(); break; case IEditorTarget.TARGET_WOD: this.switchToWod(); break; case IEditorTarget.TARGET_WOO: this.switchToWoo(); break; default: break; } IEditorPart editorPart = getActiveEditor(); return editorPart; } public HtmlWodTab htmlWodTab() { return (htmlWodTabs != null && htmlWodTabs.length > 0) ? htmlWodTabs[0] : null; } public void switchToHtml() { this.htmlWodTab().setHtmlActive(); switchToPage(htmlPageId); } public void switchToWod() { this.htmlWodTab().setWodActive(); switchToPage(wodPageId); } public void switchToWoo() { switchToPage(wooPageId); } public void switchToPreview() { switchToPage(previewPageId); } public void switchToApi() { switchToPage(apiPageId); } public void switchToPage(int page) { this.setActivePage(page); setFocus(); } protected void pageChange(int newPageIndex) { // Frank if (componentEditorTabs == null) return; super.pageChange(newPageIndex); componentEditorTabs[newPageIndex].editorSelected(); } public ComponentEditorInput getComponentEditorInput() { return componentEditorInput; } public TemplateEditor getTemplateEditor() { return (htmlWodTab() == null) ? null : htmlWodTab().templateEditor(); } public WodEditor getWodEditor() { return (htmlWodTab() == null) ? null : htmlWodTab().wodEditor(); } public IEditorPart getEditor(int pageIndex) { if (componentEditorTabs == null) return null; int tabIndex = this.getActivePage(); if (tabIndex < 0) tabIndex = 0; return componentEditorTabs[this.getActivePage()].getActiveEmbeddedEditor(); } public IEditorPart getActiveEditor() { int activePage = this.getActivePage(); if(activePage == -1) { return null; } return componentEditorTabs[activePage].getActiveEmbeddedEditor(); } private static class ComponentEditorPartSelectionProvider extends MultiPageSelectionProvider { private ISelection globalSelection; public ComponentEditorPartSelectionProvider(ComponentEditorPart componentEditorPart) { super(componentEditorPart); } public ISelection getSelection() { IEditorPart activeEditor = ((ComponentEditorPart) getMultiPageEditor()).getActiveEditor(); if (activeEditor != null) { ISelectionProvider selectionProvider = activeEditor.getSite().getSelectionProvider(); if (selectionProvider != null) { return selectionProvider.getSelection(); } } return globalSelection; } public void setSelection(ISelection selection) { IEditorPart activeEditor = ((ComponentEditorPart) getMultiPageEditor()).getActiveEditor(); if (activeEditor != null) { ISelectionProvider selectionProvider = activeEditor.getSite().getSelectionProvider(); if (selectionProvider != null) { selectionProvider.setSelection(selection); } } else { this.globalSelection = selection; fireSelectionChanged(new SelectionChangedEvent(this, globalSelection)); } } } public void publicHandlePropertyChange(int propertyId) { this.handlePropertyChange(propertyId); } public IEditorSite publicCreateSite(IEditorPart editor) { return this.createSite(editor); } public Composite publicGetContainer() { return super.getContainer(); } public ComponentEditorInteraction getEditorInteraction() { return editorInteraction; } public void resourceChanged(final IResourceChangeEvent event) { if (event.getType() == IResourceChangeEvent.PRE_CLOSE) { Display.getDefault().asyncExec(new Runnable() { public void run() { boolean closed = false; for (int i = 0; i < componentEditorInput.getInput().length; i++) { if (((FileEditorInput) componentEditorInput.getInput()[i]).getFile().getProject().equals(event.getResource())) { IWorkbenchPage[] pages = getSite().getWorkbenchWindow().getPages(); for (int j = 0; j < pages.length; j++) { IEditorPart editorPart = pages[i].findEditor(componentEditorInput); if (editorPart != null) { if (pages[i].closeEditor(ComponentEditorPart.this, true)) { closed = true; } } } } if (closed) { break; } } } }); } } public void dispose() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); if (componentEditorTabs != null) { for (int i = 0; i < componentEditorTabs.length; i++) { if (componentEditorTabs[i] != null) { componentEditorTabs[i].dispose(); } } } super.dispose(); } public void showEditorInput(IEditorInput editorInput) { IFile inputFile = ((FileEditorInput) editorInput).getFile(); IEditorInput[] editorInputArray = componentEditorInput.getInput(); for (int i = 0; i < editorInputArray.length; i++) { IFile inputFileFromEditor = ResourceUtil.getFile(editorInputArray[i]); if (inputFileFromEditor == null) { continue; } if (inputFileFromEditor.equals(inputFile)) { switch (i) { case 0: switchToHtml(); break; case 1: switchToWod(); break; case 2: switchToWoo(); break; case 3: switchToApi(); break; default: break; } } } } }