package tk.eclipse.plugin.htmleditor.editors; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.jrcs.diff.AddDelta; import org.apache.commons.jrcs.diff.ChangeDelta; import org.apache.commons.jrcs.diff.DeleteDelta; import org.apache.commons.jrcs.diff.Delta; import org.apache.commons.jrcs.diff.Diff; import org.apache.commons.jrcs.diff.Revision; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewerExtension2; import org.eclipse.jface.text.contentassist.ContentAssistant; import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.MatchingCharacterPainter; import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; import org.eclipse.jface.text.source.projection.ProjectionSupport; import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; import org.eclipse.ui.texteditor.ChainedPreferenceStore; import org.eclipse.ui.texteditor.ContentAssistAction; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.objectstyle.wolips.wodclipse.core.util.CursorPositionSupport; import org.objectstyle.wolips.wodclipse.core.util.ICursorPositionListener; import tk.eclipse.plugin.htmleditor.ColorProvider; import tk.eclipse.plugin.htmleditor.HTMLHyperlinkDetector; import tk.eclipse.plugin.htmleditor.HTMLPlugin; import tk.eclipse.plugin.htmleditor.HTMLProjectParams; import tk.eclipse.plugin.htmleditor.HTMLUtil; import tk.eclipse.plugin.htmleditor.assist.HTMLAssistProcessor; import tk.eclipse.plugin.htmleditor.assist.InnerJavaScriptAssistProcessor; /** * HTML source editor. */ public class HTMLSourceEditor extends TextEditor { private CursorPositionSupport _cursorPositionSupport; private ColorProvider _colorProvider; private IHTMLOutlinePage _outlinePage; private HTMLCharacterPairMatcher _pairMatcher; private SoftTabVerifyListener _softTabListener; public static final String GROUP_HTML = "_html"; public static final String ACTION_ESCAPE_HTML = "_escape_html"; public static final String ACTION_COMMENT = "_comment"; public static final String ACTION_OPEN_PALETTE = "_open_palette"; public static final String ACTION_CHOOSE_COLOR = "_choose_color"; public static final String ACTION_COMPLETION = "ContentAssistProposal"; // private boolean useSoftTab; // private String softTab; private boolean validation = true; public HTMLSourceEditor(HTMLConfiguration config) { super(); config.setEditorPart(this); _colorProvider = HTMLPlugin.getDefault().getColorProvider(); setSourceViewerConfiguration(config); setPreferenceStore(new ChainedPreferenceStore(new IPreferenceStore[] { getPreferenceStore(), HTMLPlugin.getDefault().getPreferenceStore() })); setAction(ACTION_ESCAPE_HTML, new EscapeHTMLAction()); //setAction(ACTION_OPEN_PALETTE, new OpenPaletteAction()); //setAction(ACTION_CHOOSE_COLOR, new ChooseColorAction(this)); IPreferenceStore store = HTMLPlugin.getDefault().getPreferenceStore(); _softTabListener = new SoftTabVerifyListener(); _softTabListener.setUseSoftTab(store.getBoolean(HTMLPlugin.PREF_USE_SOFTTAB)); _softTabListener.setSoftTabWidth(store.getInt(HTMLPlugin.PREF_SOFTTAB_WIDTH)); _outlinePage = createOutlinePage(); _cursorPositionSupport = new CursorPositionSupport(this); } protected HTMLCharacterPairMatcher getPairMatcher() { return this._pairMatcher; } public void setValidation(boolean validation) { this.validation = validation; } public boolean getValidation() { return this.validation; } protected IHTMLOutlinePage createOutlinePage() { return new HTMLOutlinePage(this); } /** * TODO Move to SourceViewerConfiguration!! */ protected final HTMLHyperlinkDetector createHyperlinkSupport() { return new HTMLHyperlinkDetector(); } private ProjectionSupport fProjectionSupport; @Override protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), true, styles); getSourceViewerDecorationSupport(viewer); viewer.getTextWidget().addVerifyListener(_softTabListener); return viewer; } @Override public IOverviewRuler getOverviewRuler() { return super.getOverviewRuler(); } public ISourceViewer getViewer() { return this.getSourceViewer(); } public synchronized void addCursorPositionListener(ICursorPositionListener listener) { _cursorPositionSupport.addCursorPositionListener(listener); } public synchronized void removeCursorPositionListener(ICursorPositionListener listener) { _cursorPositionSupport.removeCursorPositionListener(listener); } @Override protected void handleCursorPositionChanged() { super.handleCursorPositionChanged(); _cursorPositionSupport.cursorPositionChanged(getViewer().getSelectedRange()); } @Override public void createPartControl(Composite parent) { super.createPartControl(parent); ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); fProjectionSupport.install(); projectionViewer.doOperation(ProjectionViewer.TOGGLE); projectionViewer.getTextWidget().setTabs(getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH)); // projectionViewer.setHyperlinkDetectors(new IHyperlinkDetector[]{ // new URLHyperlinkDetector(projectionViewer), // createHyperlinkSupport() // }, SWT.CTRL); ITextViewerExtension2 extension = (ITextViewerExtension2) getSourceViewer(); _pairMatcher = new HTMLCharacterPairMatcher(); _pairMatcher.setEnable(getPreferenceStore().getBoolean(HTMLPlugin.PREF_PAIR_CHAR)); MatchingCharacterPainter painter = new MatchingCharacterPainter(getSourceViewer(), _pairMatcher); painter.setColor(Display.getDefault().getSystemColor(SWT.COLOR_GRAY)); extension.addPainter(painter); getSourceViewer().getTextWidget().getParent().setBackground(parent.getBackground()); update(); } // public void addTextListener(ITextListener l){ // getSourceViewer().addTextListener(l); // } // // public void removeTextListener(ITextListener l){ // getSourceViewer().removeTextListener(l); // } /** This method is called when configuration is changed. */ @Override protected boolean affectsTextPresentation(PropertyChangeEvent event) { return super.affectsTextPresentation(event) || _colorProvider.affectsTextPresentation(event); } /** This method is called when configuration is changed. */ @Override protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { _colorProvider.handlePreferenceStoreChanged(event); updateAssistProperties(event); _softTabListener.preferenceChanged(event); String key = event.getProperty(); if (key.equals(HTMLPlugin.PREF_PAIR_CHAR)) { Object value = event.getNewValue(); boolean enable = false; if (value instanceof String) { enable = Boolean.valueOf((String) value).booleanValue(); } else if (value instanceof Boolean) { enable = ((Boolean) value).booleanValue(); } _pairMatcher.setEnable(enable); } super.handlePreferenceStoreChanged(event); } private void updateAssistProperties(PropertyChangeEvent event) { String key = event.getProperty(); try { // auto activation delay if (key.equals(HTMLPlugin.PREF_ASSIST_TIMES)) { ContentAssistant assistant = (ContentAssistant) getSourceViewerConfiguration().getContentAssistant(null); assistant.setAutoActivationDelay(Integer.parseInt((String) event.getNewValue())); // auto activation trigger } else if (key.equals(HTMLPlugin.PREF_ASSIST_CHARS)) { ContentAssistant assistant = (ContentAssistant) getSourceViewerConfiguration().getContentAssistant(null); HTMLAssistProcessor processor = (HTMLAssistProcessor) assistant.getContentAssistProcessor(IDocument.DEFAULT_CONTENT_TYPE); processor.setAutoAssistChars(((String) event.getNewValue()).toCharArray()); // completion close tag } else if (key.equals(HTMLPlugin.PREF_ASSIST_CLOSE)) { ContentAssistant assistant = (ContentAssistant) getSourceViewerConfiguration().getContentAssistant(null); HTMLAssistProcessor processor = (HTMLAssistProcessor) assistant.getContentAssistProcessor(IDocument.DEFAULT_CONTENT_TYPE); processor.setAssistCloseTag(((Boolean) event.getNewValue()).booleanValue()); // enable auto activation or not } else if (key.equals(HTMLPlugin.PREF_ASSIST_AUTO)) { ContentAssistant assistant = (ContentAssistant) getSourceViewerConfiguration().getContentAssistant(null); assistant.enableAutoActivation(((Boolean) event.getNewValue()).booleanValue()); } } catch (Exception ex) { HTMLPlugin.logException(ex); } } /** * Adds actions to the context menu. * <p> * If you want to customize the context menu, * you can override this method in the sub-class * instead of editorContextMenuAboutToShow(), * * @param menu IMenuManager */ protected void addContextMenuActions(IMenuManager menu) { menu.add(new Separator(GROUP_HTML)); //addAction(menu, GROUP_HTML, ACTION_CHOOSE_COLOR); //addAction(menu, GROUP_HTML, ACTION_OPEN_PALETTE); addAction(menu, GROUP_HTML, ACTION_ESCAPE_HTML); addAction(menu, GROUP_HTML, ACTION_COMMENT); } @Override protected void editorContextMenuAboutToShow(IMenuManager menu) { super.editorContextMenuAboutToShow(menu); addContextMenuActions(menu); } @Override protected void updateSelectionDependentActions() { super.updateSelectionDependentActions(); ITextSelection sel = (ITextSelection) getSelectionProvider().getSelection(); if (sel.getText().equals("")) { getAction(ACTION_COMMENT).setEnabled(false); getAction(ACTION_ESCAPE_HTML).setEnabled(false); } else { getAction(ACTION_COMMENT).setEnabled(true); getAction(ACTION_ESCAPE_HTML).setEnabled(true); } } /** * Validates HTML document. * If the editor provides other validation, do override at the subclass. */ protected void doValidate() { try { ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { try { IFileEditorInput input = (IFileEditorInput) getEditorInput(); IFile file = input.getFile(); file.deleteMarkers(IMarker.PROBLEM, false, 0); HTMLProjectParams params = new HTMLProjectParams(file.getProject()); if (params.getValidateHTML()) { new HTMLValidator(input.getFile()).doValidate(); } } catch (Exception ex) { //HTMLPlugin.logException(ex); } } }, null); } catch (Exception ex) { HTMLPlugin.logException(ex); } } /** * Returns HTML source which can be parse by FuzzyXML. * * @return HTML source */ public String getHTMLSource() { return getDocumentProvider().getDocument(getEditorInput()).get(); } /** * This method is called in the following timing: * <ul> * <li>Initialize editor</li> * <li>Save document</li> * </ul> * And do the following sequence. * <ul> * <li>invoke {@link HTMLSourceEditor#updateFolding()}</li> * <li>invoke {@link HTMLSourceEditor#updateAssist()}</li> * <li>invoke {@link HTMLOutlinePage#update()}</li> * <li>update {@link HTMLHyperlinkSupport} * <li>invoke {@link HTMLSourceEditor#doValidate()()} (only getValidation() returns true)</li> * </ul> * If it's required to update some information about the editor, * do override at the subclass. */ public void update() { updateFolding(); updateAssist(); _outlinePage.update(); if (validation && isFileEditorInput()) { doValidate(); } HTMLHyperlinkDetector hyperlinkDetector = ((HTMLConfiguration) getSourceViewerConfiguration()).getHyperlinkDetector(); hyperlinkDetector.setEditor(this); } /** * Update informations about code-completion. */ protected void updateAssist() { String html = getDocumentProvider().getDocument(getEditorInput()).get(); // Update AssistProcessors HTMLAssistProcessor processor = ((HTMLConfiguration) getSourceViewerConfiguration()).getAssistProcessor(); processor.update(this, html); if (!isFileEditorInput()) { return; } InnerJavaScriptAssistProcessor jsProcessor = ((HTMLConfiguration) getSourceViewerConfiguration()).getJavaScriptAssistProcessor(); jsProcessor.update(((IFileEditorInput) getEditorInput()).getFile()); } /* protected void initializeDragAndDrop(ISourceViewer viewer) { super.initializeDragAndDrop(viewer); DropTarget target = new DropTarget(viewer.getTextWidget(),DND.DROP_DEFAULT|DND.DROP_COPY); LocalSelectionTransfer selTransfer = LocalSelectionTransfer.getInstance(); // FileTransfer fileTransfer = FileTransfer.getInstance(); // TextTransfer textTransfer = TextTransfer.getInstance(); // Transfer[] types = new Transfer[]{fileTransfer,textTransfer}; Transfer[] types = new Transfer[]{selTransfer}; target.setTransfer(types); target.addDropListener(new HTMLDropListener()); // getSourceViewer().getTextWidget().addMouseMoveListener(new HTMLDropMouseMoveListener()); } */ @Override public void dispose() { if (isFileEditorInput() && validation) { try { ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { try { IFileEditorInput input = (IFileEditorInput) getEditorInput(); HTMLProjectParams params = new HTMLProjectParams(input.getFile().getProject()); if (params.getRemoveMarkers()) { input.getFile().deleteMarkers(IMarker.PROBLEM, false, 0); } } catch (Exception ex) { } } }, null); } catch (Exception ex) { } } fProjectionSupport.dispose(); _pairMatcher.dispose(); super.dispose(); } public ProjectionSupport getProjectionSupport() { return fProjectionSupport; } /** * Returns a java.io.File object that is editing in this editor. */ public File getFile() { IFile file = ((FileEditorInput) this.getEditorInput()).getFile(); return file.getLocation().makeAbsolute().toFile(); } /** * Returns a java.io.File object of a temporary file for preview. */ public File getTempFile() { IFile file = ((FileEditorInput) this.getEditorInput()).getFile(); return new File(file.getLocation().makeAbsolute().toFile().getParentFile(), "." + file.getName()); } @Override protected void createActions() { super.createActions(); // add content assist action IAction action = new ContentAssistAction(HTMLPlugin.getDefault().getResourceBundle(), "ContentAssistProposal", this); action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); setAction(ACTION_COMPLETION, action); setAction(ACTION_COMMENT, new CommentAction()); } @Override public Object getAdapter(Class adapter) { if (IContentOutlinePage.class.equals(adapter)) { return _outlinePage; } if (ProjectionAnnotationModel.class.equals(adapter) && fProjectionSupport != null) { Object obj = fProjectionSupport.getAdapter(getSourceViewer(), adapter); if (obj != null) { return obj; } } if (IDocumentProvider.class.equals(adapter)) { return getDocumentProvider(); } if (ISelectionProvider.class.equals(adapter)) { return getSelectionProvider(); } return super.getAdapter(adapter); } protected IDocumentProvider createDocumentProvider(IEditorInput input) { if (input instanceof IFileEditorInput) { return new HTMLTextDocumentProvider(); } else if (input instanceof IStorageEditorInput) { return new HTMLFileDocumentProvider(); } else { return new HTMLTextDocumentProvider(); } } @Override protected void doSetInput(IEditorInput input) throws CoreException { setDocumentProvider(createDocumentProvider(input)); if (input instanceof IFileEditorInput) { IFile file = ((IFileEditorInput) input).getFile(); if (file.getName().endsWith(".xhtml")) { HTMLConfiguration config = (HTMLConfiguration) getSourceViewerConfiguration(); config.getAssistProcessor().setXHTMLMode(true); } } super.doSetInput(input); } @Override public void doSave(IProgressMonitor progressMonitor) { super.doSave(progressMonitor); update(); } @Override public void doSaveAs() { super.doSaveAs(); update(); } public void setDiff(String text) { // apply the graphical editor contents to the source editor IEditorInput input = getEditorInput(); IDocument doc = getDocumentProvider().getDocument(input); getSourceViewer().getTextWidget().setRedraw(false); String[] text1 = doc.get().split("\n"); String[] text2 = text.split("\n"); try { Revision rev = Diff.diff(text1, text2); int count1 = 0; int count2 = 0; int index = 0; for (int i = 0; i < rev.size(); i++) { Delta delta = rev.getDelta(i); Range orgRange = new Range(delta.getOriginal().rangeString()); Range revRange = new Range(delta.getRevised().rangeString()); // matched while (count1 != orgRange.getFrom() - 1) { index = index + text1[count1].length() + 1; count1++; } count1 = orgRange.getFrom() - 1; count2 = revRange.getFrom() - 1; // added if (delta instanceof AddDelta) { while (count2 != revRange.getTo()) { doc.replace(index, 0, text2[count2] + "\n"); index = index + text2[count2].length() + 1; count2++; } // removed } else if (delta instanceof DeleteDelta) { while (count1 != orgRange.getTo()) { doc.replace(index, text1[count1].length() + 1, ""); count1++; } // replaced } else if (delta instanceof ChangeDelta) { while (count1 != orgRange.getTo()) { doc.replace(index, text1[count1].length() + 1, ""); count1++; } while (count2 != revRange.getTo()) { doc.replace(index, 0, text2[count2] + "\n"); index = index + text2[count2].length() + 1; count2++; } } count1 = orgRange.getTo(); count2 = revRange.getTo(); } } catch (Exception ex) { doc.set(text); } getSourceViewer().getTextWidget().setRedraw(true); } /** This class is used in setDiff(). */ private class Range { private int from; private int to; public Range(String rangeString) { if (rangeString.indexOf(",") != -1) { String[] dim = rangeString.split(","); from = Integer.parseInt(dim[0]); to = Integer.parseInt(dim[1]); } else { from = Integer.parseInt(rangeString); to = Integer.parseInt(rangeString); } } public int getFrom() { return this.from; } public int getTo() { return to; } } /** Regular expression to search tags. */ private Pattern tagPattern = Pattern.compile("<([^<]*?)>"); private Pattern valuePattern = Pattern.compile("\".*?\""); /** * Update folding informations. */ private void updateFolding() { try { ProjectionViewer viewer = (ProjectionViewer) getSourceViewer(); if (viewer == null) { return; } ProjectionAnnotationModel model = viewer.getProjectionAnnotationModel(); if (model == null) { return; } List<FoldingInfo> list = new ArrayList<FoldingInfo>(); Stack<FoldingInfo> stack = new Stack<FoldingInfo>(); IDocument doc = getDocumentProvider().getDocument(getEditorInput()); String xml = HTMLUtil.scriptlet2space(HTMLUtil.comment2space(doc.get(), true), true); // trim attribute values Matcher matcher = valuePattern.matcher(xml); while (matcher.find()) { int start = matcher.start(0); int length = matcher.group(0).length(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { sb.append(" "); } xml = xml.substring(0, start) + sb.toString() + xml.substring(start + length); } matcher = tagPattern.matcher(xml); while (matcher.find()) { String text = matcher.group(1).trim(); // skip XML declaration if (text.startsWith("?")) { continue; } // DOCTYPE declaration if (text.startsWith("!DOCTYPE")) { // Don't fold if start offset and end offset are same line if (doc.getLineOfOffset(matcher.start()) != doc.getLineOfOffset(matcher.end())) { FoldingInfo info = new FoldingInfo(matcher.start(), matcher.end(), "!DOCTYPE"); info.setEnd(info.getEnd() + FoldingInfo.countUpLineDelimiter(xml, matcher.end())); list.add(info); } continue; } // JSP (I think this shouldn't process in here) if (text.startsWith("%")) { // Don't fold if start offset and end offset are same line if (doc.getLineOfOffset(matcher.start()) != doc.getLineOfOffset(matcher.end())) { FoldingInfo info = new FoldingInfo(matcher.start(), matcher.end(), "%"); info.setEnd(info.getEnd() + FoldingInfo.countUpLineDelimiter(xml, matcher.end())); list.add(info); } continue; } // comment if (text.startsWith("!--")) { // Don't fold if start offset and end offset are same line if (doc.getLineOfOffset(matcher.start()) != doc.getLineOfOffset(matcher.end())) { FoldingInfo info = new FoldingInfo(matcher.start(), matcher.end(), "!--"); info.setEnd(info.getEnd() + FoldingInfo.countUpLineDelimiter(xml, matcher.end())); list.add(info); } continue; } // close tag if (text.startsWith("/")) { text = text.substring(1, text.length()); while (stack.size() != 0) { FoldingInfo info = stack.pop(); if (info.getType().equalsIgnoreCase(text) || (info.getType().toLowerCase().startsWith("tb:") && text.toLowerCase().startsWith("tb")) || (info.getType().toLowerCase().startsWith("wo:") && text.toLowerCase().startsWith("wo"))) { info.setEnd(matcher.end()); // Don't fold if start offset and end offset are same line if (doc.getLineOfOffset(info.getStart()) != doc.getLineOfOffset(info.getEnd())) { info.setEnd(info.getEnd() + FoldingInfo.countUpLineDelimiter(xml, matcher.end())); list.add(info); } break; } } continue; } // empty tag if (text.endsWith("/")) { // Don't fold if start offset and end offset are same line if (doc.getLineOfOffset(matcher.start()) != doc.getLineOfOffset(matcher.end())) { text.substring(0, text.length() - 1); if (text.indexOf(" ") != -1) { text = text.substring(0, text.indexOf(" ")); } FoldingInfo info = new FoldingInfo(matcher.start(), matcher.end(), text); info.setEnd(info.getEnd() + FoldingInfo.countUpLineDelimiter(xml, matcher.end())); list.add(info); } continue; } // start tag (put to the stack) text = text.replaceAll("[\\s\r\n]+", " "); if (text.indexOf(" ") != -1) { text = text.substring(0, text.indexOf(" ")); } stack.push(new FoldingInfo(matcher.start(), 0, text)); } FoldingInfo.applyModifiedAnnotations(model, list); } catch (Exception ex) { HTMLPlugin.logException(ex); } } //////////////////////////////////////////////////////////////////////////// // Drag & Drop //////////////////////////////////////////////////////////////////////////// /* private class HTMLDropListener extends DropTargetAdapter { public void dragEnter(DropTargetEvent evt){ evt.detail = DND.DROP_COPY; setFocus(); } // public void dragLeave(DropTargetEvent event) { // } private Point calcLocation(Composite composite,Point point){ Point compPoint = composite.getLocation(); Point nextPoint = new Point(compPoint.x + point.x ,compPoint.y + point.y); Composite parent = composite.getParent(); if(parent!=null){ Point result = calcLocation(parent,nextPoint); return result; } else { return new Point(nextPoint.x + 30, nextPoint.y + 48); } } public void dragOver(DropTargetEvent event) { try { Point point = calcLocation(getSourceViewer().getTextWidget().getParent(),new Point(0,0)); int x = event.x - point.x; int y = event.y - point.y; int offset = getSourceViewer().getTextWidget().getOffsetAtLocation(new Point(x,y)); getSourceViewer().getTextWidget().setCaretOffset(offset); } catch(Exception ex){ } } public void drop(DropTargetEvent evt){ for(int i=0;i<evt.dataTypes.length;i++){ if (TextTransfer.getInstance().isSupportedType(evt.dataTypes[i])){ String text = (String)evt.data; } else if (FileTransfer.getInstance().isSupportedType(evt.dataTypes[i])){ String[] files = (String[])evt.data; for(int j=0;j<files.length;j++){ File file = new File(files[j]); } } else if (LocalSelectionTransfer.getInstance().isSupportedType(evt.dataTypes[i])){ IStructuredSelection sel = (IStructuredSelection)evt.data; Object obj = sel.getFirstElement(); if(obj instanceof IPaletteItem){ ((IPaletteItem)obj).execute(HTMLSourceEditor.this); } } } } } */ public boolean isFileEditorInput() { if (getEditorInput() instanceof IFileEditorInput) { return true; } return false; } //////////////////////////////////////////////////////////////////////////// // actions //////////////////////////////////////////////////////////////////////////// /** The action to escape HTML tags in the selection. */ private class EscapeHTMLAction extends Action { public EscapeHTMLAction() { super(HTMLPlugin.getResourceString("HTMLEditor.EscapeAction")); setEnabled(false); setAccelerator(SWT.CTRL | '\\'); } @Override public void run() { ITextSelection sel = (ITextSelection) getSelectionProvider().getSelection(); IDocument doc = getDocumentProvider().getDocument(getEditorInput()); try { doc.replace(sel.getOffset(), sel.getLength(), HTMLUtil.escapeHTML(sel.getText())); } catch (BadLocationException e) { HTMLPlugin.logException(e); } } } /** The action to comment out selection range. */ private class CommentAction extends Action { public CommentAction() { super(HTMLPlugin.getResourceString("HTMLEditor.CommentAction")); setActionDefinitionId("tk.eclipse.plugin.htmleditor.comment"); } @Override public void run() { ITextSelection sel = (ITextSelection) getSelectionProvider().getSelection(); IDocument doc = getDocumentProvider().getDocument(getEditorInput()); String text = sel.getText().trim(); try { if (text.startsWith("<!--") && text.indexOf("-->") > 3) { text = sel.getText().replaceFirst("<!--", ""); text = text.replaceFirst("-->", ""); doc.replace(sel.getOffset(), sel.getLength(), text); } else { doc.replace(sel.getOffset(), sel.getLength(), "<!--" + sel.getText() + "-->"); } } catch (BadLocationException e) { HTMLPlugin.logException(e); } } } /** The action to open the palette view. */ private class OpenPaletteAction extends Action { public OpenPaletteAction() { super(HTMLPlugin.getResourceString("HTMLEditor.OpenPaletteAction"), HTMLPlugin.getDefault().getImageRegistry().getDescriptor(HTMLPlugin.ICON_PALETTE)); setEnabled(true); } @Override public void run() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); try { window.getActivePage().showView("tk.eclipse.plugin.htmleditor.views.PaletteView"); } catch (Exception ex) { HTMLPlugin.openAlertDialog(ex.toString()); } } } }