package org.xmind.ui.internal.mindmap;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.xmind.core.Core;
import org.xmind.core.IFileEntry;
import org.xmind.core.ITopic;
import org.xmind.core.event.CoreEvent;
import org.xmind.core.event.ICoreEventRegister;
import org.xmind.core.event.ICoreEventSupport;
import org.xmind.core.util.FileUtils;
import org.xmind.core.util.HyperlinkUtils;
import org.xmind.gef.EditDomain;
import org.xmind.gef.GEF;
import org.xmind.gef.Request;
import org.xmind.gef.ui.editor.IGraphicalEditor;
import org.xmind.gef.ui.editor.IGraphicalEditorPage;
import org.xmind.ui.actions.MindMapActionFactory;
import org.xmind.ui.internal.MindMapMessages;
import org.xmind.ui.internal.actions.ModifyHyperlinkAction;
import org.xmind.ui.internal.dialogs.DialogMessages;
import org.xmind.ui.mindmap.AbstractInfoItemContributor;
import org.xmind.ui.mindmap.IInfoPart;
import org.xmind.ui.mindmap.ITopicPart;
import org.xmind.ui.mindmap.MindMapUI;
public class HyperlinkInfoItemContributor extends AbstractInfoItemContributor {
public IAction createAction(ITopicPart topicPart, ITopic topic) {
String hyperlink = topic.getHyperlink();
if (hyperlink == null)
return null;
IAction action = MindMapUI.getProtocolManager()
.createOpenHyperlinkAction(topicPart, hyperlink);
if (action != null) {
action.setId(MindMapActionFactory.OPEN_HYPERLINK.getId());
}
return action;
}
public String getContent(ITopic topic) {
return topic.getHyperlink();
}
@Override
public boolean isCardModeAvailable(ITopic topic, ITopicPart topicPart) {
return isLinkToWeb(topic.getHyperlink()) && !isIconTipOnly(topicPart);
}
private boolean isLinkToWeb(String hyperlink) {
return hyperlink != null && !hyperlink.startsWith("xap:") //$NON-NLS-1$
&& !hyperlink.startsWith("xmind:") //$NON-NLS-1$
&& !hyperlink.startsWith("file:"); //$NON-NLS-1$
}
@Override
protected void registerTopicEvent(ITopicPart topicPart, ITopic topic,
ICoreEventRegister register) {
register.register(Core.TopicHyperlink);
register.setNextSupport((ICoreEventSupport) topic.getOwnedWorkbook()
.getAdapter(ICoreEventSupport.class));
register.register(Core.TopicAdd);
register.register(Core.TopicRemove);
register.register(Core.TitleText);
}
@Override
protected void handleTopicEvent(IInfoPart infoPart, CoreEvent event) {
if (Core.TopicAdd.equals(event.getType())
|| Core.TopicRemove.equals(event.getType())
|| Core.TitleText.equals(event.getType())) {
String hyperlink = infoPart.getTopicPart().getTopic()
.getHyperlink();
if (HyperlinkUtils.isInternalURL(hyperlink)) {
Object target = HyperlinkUtils.findElement(hyperlink,
infoPart.getTopicPart().getTopic().getOwnedWorkbook());
if (target == event.getTarget()) {
infoPart.refresh();
infoPart.getTopicPart().refresh();
}
if (Core.TitleText.equals(event.getType()) && target != null) {
infoPart.refresh();
infoPart.getTopicPart().refresh();
}
}
} else {
infoPart.refresh();
infoPart.getTopicPart().refresh();
}
}
@Override
protected void handleTopicEvent(ITopicPart topicPart, CoreEvent event) {
if (Core.TopicAdd.equals(event.getType())
|| Core.TopicRemove.equals(event.getType())
|| Core.TitleText.equals(event.getType())) {
String hyperlink = topicPart.getTopic().getHyperlink();
if (HyperlinkUtils.isInternalURL(hyperlink)) {
Object target = HyperlinkUtils.findElement(hyperlink,
topicPart.getTopic().getOwnedWorkbook());
if (target == event.getTarget()) {
topicPart.refresh();
}
}
} else {
topicPart.refresh();
}
}
public void removeHyperlink(ITopic topic) {
IGraphicalEditorPage page = getPage();
if (page == null)
return;
Request request = new Request(MindMapUI.REQ_MODIFY_HYPERLINK)
.setParameter(GEF.PARAM_TEXT, null);
request.setViewer(page.getViewer());
EditDomain domain = page.getEditDomain();
if (domain != null) {
domain.handleRequest(request);
}
}
@Override
public List<IAction> getPopupMenuActions(ITopicPart topicPart,
final ITopic topic) {
IGraphicalEditorPage page = getPage();
if (page == null)
return Collections.emptyList();
List<IAction> actions = new ArrayList<IAction>();
String url = topic.getHyperlink();
if (!HyperlinkUtils.isAttachmentURL(url)) {
IAction modifyHyperlinkAction = new ModifyHyperlinkAction(page);
modifyHyperlinkAction.setText(MindMapMessages.InfoItem_Modify_text);
modifyHyperlinkAction.setImageDescriptor(null);
actions.add(modifyHyperlinkAction);
} else {
IAction saveAttchmentAsAction = new Action(
MindMapMessages.InfoItem_SaveAttachment_text) {
@Override
public void run() {
saveAttachmentAs(topic);
}
};
actions.add(saveAttchmentAsAction);
}
IAction deleteHyperlinkAction = new Action(
MindMapMessages.InfoItem_Delete_text) {
@Override
public void run() {
HyperlinkInfoItemContributor.this.removeHyperlink(topic);
}
};
deleteHyperlinkAction.setId("org.xmind.ui.removeHyperlink"); //$NON-NLS-1$
deleteHyperlinkAction.setImageDescriptor(null);
actions.add(deleteHyperlinkAction);
return actions;
}
private IGraphicalEditorPage getPage() {
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
if (window == null)
return null;
IGraphicalEditor editor = (IGraphicalEditor) window.getActivePage()
.getActiveEditor();
if (editor == null)
return null;
return editor.getActivePageInstance();
}
private Object saveAttachmentAs(ITopic sourceTopic) {
if (sourceTopic == null)
return null;
String url = sourceTopic.getHyperlink();
if (!HyperlinkUtils.isAttachmentURL(url))
return null;
final String entryPath = HyperlinkUtils.toAttachmentPath(url);
final IFileEntry entry = sourceTopic.getOwnedWorkbook().getManifest()
.getFileEntry(entryPath);
if (entry == null)
return null;
final InputStream is = entry.getInputStream();
if (is == null)
return null;
try {
String ext = FileUtils.getExtension(entryPath);
FileDialog dialog = new FileDialog(
Display.getCurrent().getActiveShell(), SWT.SAVE);
dialog.setFilterExtensions(new String[] { "*" + ext, "*.*" }); //$NON-NLS-1$//$NON-NLS-2$
String extension = ext;
if (ext != null) {
Program p = Program.findProgram(ext);
if (p != null) {
extension = p.getName();
}
}
dialog.setFilterNames(
new String[] { extension, NLS.bind("{0} (*.*)", //$NON-NLS-1$
DialogMessages.AllFilesFilterName) });
String name = sourceTopic.getTitleText();
if (name != null && !name.endsWith(ext)) {
name += ext;
}
if (name != null) {
dialog.setFileName(name);
}
dialog.setOverwrite(true);
final String targetPath = dialog.open();
if (targetPath == null)
return null;
SafeRunner.run(new SafeRunnable() {
public void run() throws Exception {
FileOutputStream os = new FileOutputStream(targetPath);
FileUtils.transfer(is, os, true);
}
});
} finally {
try {
is.close();
} catch (IOException e) {
}
}
return null;
}
}