/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.texteditors; import java.util.ResourceBundle; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextListener; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.TextEvent; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.events.FocusListener; 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.texteditor.IAbstractTextEditorHelpContextIds; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IDocumentProviderExtension; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.ITextEditorActionConstants; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; import org.eclipse.ui.texteditor.ResourceAction; import org.eclipse.ui.texteditor.RevertToSavedAction; import org.eclipse.ui.texteditor.SaveAction; import org.jboss.tools.common.editor.ObjectTextEditor; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.ui.ModelUIPlugin; import org.jboss.tools.common.model.ui.editor.IModelObjectEditorInput; import org.jboss.tools.common.model.ui.texteditors.propertyeditor.PropertiesTextEditorStub; import org.jboss.tools.common.propertieseditor.PropertiesCompoundEditor; import org.jboss.tools.common.propertieseditor.text.PropertyTextEditorSupport; /** * @author Jeremy * */ public class PropertiesTextEditorComponent extends PropertiesTextEditorStub implements ITextListener, ITextProvider, ObjectTextEditor { protected TextEditorSupport support = createSupport(); protected boolean isObjectNull = false; public void createPartControl(Composite parent) { super.createPartControl(parent); dnd.enable(); setModified(false); getSourceViewer().getDocument().addDocumentListener(this); } public PropertiesTextEditorComponent() { support.setProvider(this); } protected TextEditorSupport createSupport() { return new PropertyTextEditorSupport(); } public TextEditorSupport getSupport() { return support; } public void setObject(XModelObject object) { isObjectNull = (object == null); if(isObjectNull) return; getSourceViewer().getDocument().removeDocumentListener(this); support.setObject(object); getSourceViewer().getDocument().addDocumentListener(this); } public void updateDocument() { support.update(); } public void dispose() { super.dispose(); } public boolean isDirty() { return (isObjectNull) ? super.isDirty() : false; } public String getText() { String text = null; if(getSourceViewer() == null) return null; if(getSourceViewer().getDocument() == null) return null; text = getSourceViewer().getDocument().get(); return (text == null) ? "" : text; //$NON-NLS-1$ } public boolean isEditable() { return !isEditorInputReadOnly(); } public boolean isEditorInputReadOnly() { if(!(getEditorInput() instanceof IModelObjectEditorInput)) return super.isEditorInputReadOnly(); IModelObjectEditorInput input = (IModelObjectEditorInput)getEditorInput(); return input != null && input.getXModelObject() != null && !input.getXModelObject().isObjectEditable(); } public void setModified(boolean set) { if(set == support.isModified()) return; support.setModified(set); firePropertyChange(IEditorPart.PROP_DIRTY); } public boolean isModified() { return support.isModified(); } protected void doSetInput(IEditorInput input) throws CoreException { super.doSetInput(input); if(getSourceViewer() != null && getSourceViewer().getDocument() != null) { getSourceViewer().getDocument().removeDocumentListener(this); getSourceViewer().getDocument().addDocumentListener(this); } } public void save() { if(!isObjectNull && !support.canSave(false)) return; if(isObjectNull) super.doSave(null); else support.save(); } public void addFocusListener(FocusListener listener) { getSourceViewer().getTextWidget().addFocusListener(listener); } public void removeFocusListener(FocusListener listener) { getSourceViewer().getTextWidget().removeFocusListener(listener); } public void setCursor(int line, int position) { ISourceViewer sv = getSourceViewer(); if(sv == null) return; IDocument d = sv.getDocument(); if(d == null) return; try { int i = d.getLineOffset(line - 1) + position - 1; sv.setSelectedRange(i, 0); } catch (BadLocationException e) { ModelUIPlugin.getPluginLog().logError(e); } } public void doSaveAs() {} public void doSave(IProgressMonitor monitor){ if(isObjectNull) super.doSave(monitor); } private boolean textChangedLock = false; public void textChanged(TextEvent event) { if(textChangedLock) { firePropertyChange(IEditorPart.PROP_DIRTY); } else { setModified(true); } } public void setText(String text) { textChangedLock = true; try { if(getSourceViewer() == null || getSourceViewer().getDocument() == null) return; String txt = getSourceViewer().getDocument().get(); if(txt != null && txt.length() > 0) { if(!TextMerge.replace(getSourceViewer().getDocument(), text)) { getSourceViewer().getDocument().set(text); } } else { getSourceViewer().getDocument().set(text); } } finally { textChangedLock = false; } } public boolean isEqualText(String text) { return (getSourceViewer().getDocument() != null && text.equals(getText())); } public void doSanityCheckState(IEditorInput input) { super.safelySanityCheckState(input); if(isObjectNull) return; Display.getDefault().syncExec( new Runnable() { public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { //ignore } support.save(); } } ); } public void doRevertToSaved() { support.save(); support.revertToSaved(); } protected void createActions() { super.createActions(); ResourceAction action = new RevertToSavedAction3(this); action.setHelpContextId(IAbstractTextEditorHelpContextIds.REVERT_TO_SAVED_ACTION); action.setActionDefinitionId(ITextEditorActionDefinitionIds.REVERT_TO_SAVED); setAction(ITextEditorActionConstants.REVERT_TO_SAVED, action); action = new SaveAction3(this); action.setHelpContextId(IAbstractTextEditorHelpContextIds.SAVE_ACTION); action.setActionDefinitionId(ITextEditorActionDefinitionIds.SAVE); setAction(ITextEditorActionConstants.SAVE, action); markAsPropertyDependentAction(ITextEditorActionConstants.SAVE, true); } public void selectModelObject(XModelObject object) { String text = getText(); String name = object.getAttributeValue("name"); //$NON-NLS-1$ String dname = object.getAttributeValue("dirtyname"); //$NON-NLS-1$ String nvs = object.getAttributeValue("name-value-separator"); //$NON-NLS-1$ int i = text.indexOf(dname + nvs); if(i < 0) return; i = text.indexOf(name, i); int j = text.indexOf('\n', i); if(j < 0) j = text.length(); selectAndReveal(i, j - i); } public void selectModelObject(XModelObject object, String attribute) { selectModelObject(object); } protected void handleEditorInputChanged() { final IDocumentProvider provider= getDocumentProvider(); if (provider == null) { // fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=15066 close(false); return; } final IEditorInput input= getEditorInput(); if (provider.isDeleted(input)) { if (isSaveAsAllowed()) { if (true) { IProgressMonitor pm= getProgressMonitor(); performSaveAs(pm); if (pm.isCanceled()) handleEditorInputChanged(); } else { close(false); } } else { if (true) close(false); } } else { if (true) { try { if (provider instanceof IDocumentProviderExtension) { IDocumentProviderExtension extension= (IDocumentProviderExtension) provider; extension.synchronize(input); } else { doSetInput(input); } } catch (CoreException x) { ModelUIPlugin.getPluginLog().logError(x); } } } } public void documentAboutToBeChanged(DocumentEvent event) {} public void documentChanged(DocumentEvent event) { textChanged(null); } public void updateModification() { XModelObject object = support.getModelObject(); if(object != null && !object.isModified() && support.isModified()) { //external update setModified(false); } else { firePropertyChange(ITextEditor.PROP_DIRTY); } } public XModelObject findModelObjectAtCursor() { XModelObject o = getModelObject(); if(!PropertiesCompoundEditor.isPropertiesFile(o)) return null; ISelection selection = getSelectionProvider().getSelection(); if(!(selection instanceof ITextSelection)) return null; int offset = ((ITextSelection)selection).getOffset(); IDocument doc = getDocumentProvider().getDocument(getEditorInput()); try { int line = doc.getLineOfOffset(offset); int lineStart = doc.getLineOffset(line); int length = doc.getLineLength(line); String txt = doc.get(lineStart, length); XModelObject[] cs = o.getChildren(); String trimmed = txt.trim(); for (int i = 0; i < cs.length; i++) { String n = cs[i].getAttributeValue("name"); //$NON-NLS-1$ if(!trimmed.startsWith(n)) continue; String sep = cs[i].getAttributeValue("name-value-separator"); //$NON-NLS-1$ if(sep == null || sep.length() == 0) sep = "="; //$NON-NLS-1$ int q = trimmed.indexOf('='); if(q < 0) continue; String s = trimmed.substring(n.length(), q).trim(); if(s.length() > 0) continue; return cs[i]; } } catch (BadLocationException e) { e.printStackTrace(); } return null; } } class RevertToSavedAction3 extends RevertToSavedAction { PropertiesTextEditorComponent t; RevertToSavedAction3(PropertiesTextEditorComponent t) { super(ResourceBundle.getBundle("org.eclipse.ui.texteditor.ConstructedEditorMessages"), "Editor.Revert.", t); //$NON-NLS-1$ //$NON-NLS-2$ this.t = t; } public void update() { setEnabled(t != null && t.support != null && (t.support.canRevertToSaved() || t.isModified())); } } class SaveAction3 extends SaveAction { PropertiesTextEditorComponent t; SaveAction3(PropertiesTextEditorComponent t) { super(ResourceBundle.getBundle("org.eclipse.ui.texteditor.ConstructedEditorMessages"), "Editor.Save.", t); //$NON-NLS-1$ //$NON-NLS-2$ this.t = t; } public void update() { XModelObject o = (t == null) ? null : t.getModelObject(); setEnabled(o != null && o.isModified()); } public void run() { IEditorPart p = getTextEditor().getSite().getPage().findEditor(t.getEditorInput()); if(p != null) getTextEditor().getSite().getPage().saveEditor(p, false); } }