| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // 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: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.richtext.actions; |
| |
| import java.io.File; |
| import java.net.URL; |
| import java.util.Stack; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.epf.common.serviceability.Logger; |
| import org.eclipse.epf.common.utils.ClipboardUtil; |
| import org.eclipse.epf.common.utils.FileUtil; |
| import org.eclipse.epf.common.utils.NetUtil; |
| import org.eclipse.epf.richtext.IRichText; |
| import org.eclipse.epf.richtext.RichTextCommand; |
| import org.eclipse.epf.richtext.RichTextEditor; |
| import org.eclipse.epf.richtext.RichTextImages; |
| import org.eclipse.epf.richtext.RichTextPlugin; |
| import org.eclipse.epf.richtext.RichTextResources; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.swt.custom.StyledText; |
| import org.eclipse.swt.dnd.Clipboard; |
| import org.eclipse.swt.dnd.HTMLTransfer; |
| import org.eclipse.swt.widgets.Display; |
| |
| /** |
| * Pastes text from the clipboard onto a rich text control. |
| * |
| * @author Kelvin Low |
| * @since 1.0 |
| */ |
| public class PasteAction extends RichTextAction { |
| |
| private static final String SOURCE_URL = "SourceURL:"; //$NON-NLS-1$ |
| |
| private static final String HTM_EXT = ".htm"; //$NON-NLS-1$ |
| |
| private static final String HTML_EXT = ".html"; //$NON-NLS-1$ |
| |
| private static final Pattern HREF_REFERENCES = Pattern |
| .compile( |
| "href\\s*=\\s*\"(.*?)\"", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$ |
| |
| protected static final Pattern p_image_ref = Pattern |
| .compile( |
| "(<(img|iframe).*?src\\s*=\\s*\")(.*?)(\")", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$ |
| |
| protected static String sourceURLStr = ""; //$NON-NLS-1$ |
| |
| private Logger logger; |
| |
| private static String RESOURCES = "resources"; //$NON-NLS-1$ |
| |
| /** |
| * Creates a new instance. |
| */ |
| public PasteAction(IRichText richText) { |
| super(richText, IAction.AS_PUSH_BUTTON); |
| setImageDescriptor(RichTextImages.IMG_DESC_PASTE); |
| setDisabledImageDescriptor(RichTextImages.DISABLED_IMG_DESC_PASTE); |
| setToolTipText(RichTextResources.pasteAction_toolTipText); |
| logger = RichTextPlugin.getDefault().getLogger(); |
| } |
| |
| /** |
| * Returns <code>true</code> if this action should be disabled when the |
| * rich text editor is in source edit mode. |
| */ |
| public boolean disableInSourceMode() { |
| return false; |
| } |
| |
| /** |
| * Executes the action. |
| * |
| * @param richText |
| * a rich text control |
| */ |
| public void execute(IRichText richText) { |
| if (richText != null) { |
| copyLinkResources(richText); |
| if (richText instanceof RichTextEditor |
| && ((RichTextEditor) richText).isHTMLTabSelected()) { |
| StyledText styledText = ((RichTextEditor) richText) |
| .getSourceEdit(); |
| styledText.paste(); |
| } else { |
| richText.executeCommand(RichTextCommand.PASTE, sourceURLStr); |
| } |
| } |
| } |
| |
| /** |
| * Copies the link resources. |
| * |
| * @param richText |
| * a rich text control |
| */ |
| protected void copyLinkResources(IRichText richText) { |
| try { |
| sourceURLStr = ClipboardUtil.getHTMLSourceURL(); |
| Clipboard clipboard = new Clipboard(Display.getCurrent()); |
| String html = (String) clipboard.getContents(HTMLTransfer |
| .getInstance()); |
| if (html != null && html.length() > 0) { |
| String basePath = richText.getBasePath(); |
| URL sourceURL = null; |
| if (sourceURLStr == null || sourceURLStr.length() == 0 |
| || sourceURLStr.equals("about:blank")) { //$NON-NLS-1$ |
| sourceURL = richText.getCopyURL(); |
| } else { |
| sourceURL = new URL(sourceURLStr); |
| } |
| |
| Matcher matcher = HREF_REFERENCES.matcher(html); |
| while (matcher.find()) { |
| String href = NetUtil.decodeURL(matcher.group(1)); |
| try { |
| URL hrefURL = new URL(sourceURL, href); |
| String scheme = hrefURL.getProtocol(); |
| if (scheme != null |
| && scheme |
| .equalsIgnoreCase(NetUtil.FILE_SCHEME)) { |
| String url = hrefURL.getPath(); |
| File srcFile = new File(url); |
| File tgtFile = null; |
| File tgtDir = null; |
| if (href.startsWith(RESOURCES) || href.startsWith("./" + RESOURCES)) { //$NON-NLS-1$ |
| tgtFile = new File(basePath, href); |
| tgtDir = tgtFile.getParentFile(); |
| } else { |
| String resPath = getSubdirectoryOfResources(href); |
| tgtFile = new File(basePath + RESOURCES, resPath); |
| tgtDir = tgtFile; |
| } |
| tgtDir.mkdirs(); |
| FileUtil.copyFile(srcFile, tgtDir); |
| } |
| } catch (Exception e) { |
| logger.logError(e); |
| } |
| } |
| |
| matcher = p_image_ref.matcher(html); |
| while (matcher.find()) { |
| String src = NetUtil.decodeURL(matcher.group(3)); |
| try { |
| URL srcURL = new URL(sourceURL, src); |
| String scheme = srcURL.getProtocol(); |
| if (scheme != null |
| && scheme.equalsIgnoreCase(NetUtil.FILE_SCHEME)) { |
| File srcFile = null; |
| String authority = srcURL.getAuthority(); |
| if (authority != null) { |
| srcFile = new File(authority + srcURL.getPath()); |
| } else { |
| srcFile = new File(srcURL.getPath()); |
| } |
| File tgtFile = null; |
| File tgtDir = null; |
| if (src.startsWith(RESOURCES) || src.startsWith("./" + RESOURCES)) { //$NON-NLS-1$ |
| tgtFile = new File(basePath, src); |
| tgtDir = tgtFile.getParentFile(); |
| } else { |
| String resPath = getSubdirectoryOfResources(src); |
| tgtFile = new File(basePath + RESOURCES, resPath); |
| tgtDir = tgtFile; |
| } |
| tgtDir.mkdirs(); |
| FileUtil.copyFile(srcFile, tgtDir); |
| } |
| } catch (Exception e) { |
| logger.logError(e); |
| } |
| } |
| } |
| } catch (Exception e) { |
| logger.logError(e); |
| } |
| } |
| |
| /** |
| * Parses the given HTML content from the clipboard and returns the source |
| * URL. |
| * |
| * @param htmlContent |
| * the HTML content from the clipboard |
| * @return the source URL or <code>null</code> |
| */ |
| protected String getSourceURL(String htmlContent) { |
| String sourceURL = null; |
| int sourceURLIndex = htmlContent.indexOf(SOURCE_URL); |
| if (sourceURLIndex > 0) { |
| sourceURL = htmlContent.substring(sourceURLIndex |
| + SOURCE_URL.length()); |
| sourceURL = sourceURL.substring(0, sourceURL |
| .indexOf(FileUtil.LINE_SEP)); |
| if (sourceURL.toLowerCase().endsWith(HTM_EXT) |
| || sourceURL.toLowerCase().endsWith(HTML_EXT)) { |
| sourceURL = sourceURL.substring(0, sourceURL.indexOf(FileUtil |
| .getFileName(sourceURL)) - 1); |
| sourceURL = sourceURL.replace('\\', '/'); |
| } |
| sourceURL = FileUtil.appendSeparator(sourceURL, "/"); //$NON-NLS-1$ |
| } |
| return sourceURL; |
| } |
| |
| protected String getSubdirectoryOfResources(String path) { |
| String result = ""; //$NON-NLS-1$ |
| int res_idx = path.indexOf(RESOURCES); |
| if (res_idx != -1) { |
| Stack stack = new Stack(); |
| File relative = new File(path).getParentFile(); |
| while (!relative.getName().equals(RESOURCES)) { |
| stack.push(relative.getName()); |
| relative = relative.getParentFile(); |
| } |
| while (!stack.isEmpty()) { |
| result = result + (String)stack.pop() + File.separator; |
| } |
| } |
| return result; |
| } |
| |
| } |