package org.freeplane.plugin.workspace.nodes;
import java.awt.Component;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.tree.DefaultTreeCellRenderer;
import org.freeplane.core.util.LogUtils;
import org.freeplane.core.util.TextUtils;
import org.freeplane.plugin.workspace.URIUtils;
import org.freeplane.plugin.workspace.WorkspaceController;
import org.freeplane.plugin.workspace.components.menu.WorkspacePopupMenu;
import org.freeplane.plugin.workspace.components.menu.WorkspacePopupMenuBuilder;
import org.freeplane.plugin.workspace.dnd.IWorkspaceTransferableCreator;
import org.freeplane.plugin.workspace.dnd.WorkspaceTransferable;
import org.freeplane.plugin.workspace.event.IWorkspaceNodeActionListener;
import org.freeplane.plugin.workspace.event.WorkspaceActionEvent;
import org.freeplane.plugin.workspace.io.IFileSystemRepresentation;
import org.freeplane.plugin.workspace.io.annotation.ExportAsAttribute;
import org.freeplane.plugin.workspace.model.AWorkspaceTreeNode;
import org.freeplane.plugin.workspace.model.IMutableLinkNode;
public class FolderLinkNode extends AFolderNode implements IWorkspaceNodeActionListener
, IWorkspaceTransferableCreator
, IFileSystemRepresentation
, IMutableLinkNode
, TreeExpansionListener {
private static final long serialVersionUID = 1L;
private static Icon FOLDER_OPEN_ICON = new ImageIcon(FolderLinkNode.class.getResource("/images/16x16/folder-orange_open.png"));
private static final Icon FOLDER_CLOSED_ICON = new ImageIcon(FolderLinkNode.class.getResource("/images/16x16/folder-orange.png"));
private static WorkspacePopupMenu popupMenu = null;
private URI folderPath;
private boolean doMonitoring = false;
private boolean orderDescending = false;
private boolean inRefresh;
public FolderLinkNode() {
this(AFolderNode.FOLDER_TYPE_PHYSICAL);
}
public FolderLinkNode(String id) {
super(id);
}
@ExportAsAttribute(name="path")
public URI getPath() {
return folderPath;
}
public void setPath(URI uri) {
if(isMonitoring()) {
enableMonitoring(false);
this.folderPath = uri;
createIfNeeded(getPath());
enableMonitoring(true);
}
else {
this.folderPath = uri;
createIfNeeded(getPath());
}
}
private void createIfNeeded(URI uri) {
File file = URIUtils.getAbsoluteFile(uri);
if (file != null && !file.exists()) {
file.mkdirs();
}
}
public void initializePopup() {
if (popupMenu == null) {
if (popupMenu == null) {
popupMenu = new WorkspacePopupMenu();
WorkspacePopupMenuBuilder.addActions(popupMenu, new String[] {
WorkspacePopupMenuBuilder.createSubMenu(TextUtils.getRawText("workspace.action.new.label")),
"workspace.action.node.new.folder",
"workspace.action.file.new.mindmap",
WorkspacePopupMenuBuilder.endSubMenu(),
WorkspacePopupMenuBuilder.SEPARATOR,
"workspace.action.node.open.location",
WorkspacePopupMenuBuilder.SEPARATOR,
"workspace.action.node.cut",
"workspace.action.node.copy",
"workspace.action.node.paste",
WorkspacePopupMenuBuilder.SEPARATOR,
"workspace.action.node.rename",
"workspace.action.node.remove",
"workspace.action.file.delete",
WorkspacePopupMenuBuilder.SEPARATOR,
"workspace.action.node.physical.sort",
WorkspacePopupMenuBuilder.SEPARATOR,
"workspace.action.node.refresh"
});
}
}
}
public void enableMonitoring(boolean enable) {
if(getPath() == null) {
this.doMonitoring = enable;
}
else {
if(enable != this.doMonitoring) {
this.doMonitoring = enable;
}
}
}
@ExportAsAttribute(name="monitor")
public boolean isMonitoring() {
return this.doMonitoring;
}
public void orderDescending(boolean enable) {
this.orderDescending = enable;
}
@ExportAsAttribute(name="orderDescending")
public boolean orderDescending() {
return orderDescending;
}
public void handleAction(WorkspaceActionEvent event) {
if (event.getType() == WorkspaceActionEvent.MOUSE_RIGHT_CLICK) {
showPopup( (Component) event.getBaggage(), event.getX(), event.getY());
event.consume();
}
}
public boolean setIcons(DefaultTreeCellRenderer renderer) {
renderer.setOpenIcon(FOLDER_OPEN_ICON);
renderer.setClosedIcon(FOLDER_CLOSED_ICON);
renderer.setLeafIcon(FOLDER_CLOSED_ICON);
return true;
}
public String toString() {
return this.getClass().getSimpleName() + "[id=" + this.getId() + ";name=" + this.getName() + ";path="
+ this.getPath() + "]";
}
public void refresh() {
File folder;
try {
inRefresh = true;
folder = URIUtils.getAbsoluteFile(getPath());
if (folder.isDirectory()) {
getModel().removeAllElements(this);
loadDirectoryFiles(folder);
getModel().reload(this);
}
}
catch (Exception e) {
LogUtils.severe(e);
}
finally {
inRefresh = false;
}
}
private void loadDirectoryFiles(File folder) {
if (folder != null && folder.isDirectory()) {
WorkspaceController.getFileSystemMgr().scanFileSystem(this, folder, false);
}
}
protected AWorkspaceTreeNode clone(FolderLinkNode node) {
node.setPath(getPath());
return super.clone(node);
}
/***********************************************************************************
* REQUIRED METHODS FOR INTERFACES
**********************************************************************************/
public WorkspacePopupMenu getContextMenu() {
if (popupMenu == null) {
initializePopup();
}
return popupMenu;
}
public AWorkspaceTreeNode clone() {
FolderLinkNode node = new FolderLinkNode(getType());
return clone(node);
}
public WorkspaceTransferable getTransferable() {
WorkspaceTransferable transferable = new WorkspaceTransferable();
try {
URI uri = URIUtils.getAbsoluteURI(getPath());
transferable.addData(WorkspaceTransferable.WORKSPACE_URI_LIST_FLAVOR, uri.toString());
List<File> fileList = new Vector<File>();
fileList.add(new File(uri));
transferable.addData(WorkspaceTransferable.WORKSPACE_FILE_LIST_FLAVOR, fileList);
if(!this.isSystem()) {
List<AWorkspaceTreeNode> objectList = new ArrayList<AWorkspaceTreeNode>();
objectList.add(this);
transferable.addData(WorkspaceTransferable.WORKSPACE_NODE_FLAVOR, objectList);
}
return transferable;
}
catch (Exception e) {
LogUtils.warn(e);
}
return null;
}
public File getFile() {
return URIUtils.getAbsoluteFile(this.getPath());
}
public boolean changeName(String newName, boolean renameLink) {
assert(newName != null);
assert(newName.trim().length() > 0);
if(renameLink) {
File oldFile = URIUtils.getAbsoluteFile(getPath());
try{
if(oldFile == null) {
throw new Exception("failed to resolve the file for"+getName());
}
File destFile = new File(oldFile.getParentFile(), newName);
if(oldFile.exists() && oldFile.renameTo(destFile)) {
//this.setName(newName);
try {
getModel().changeNodeName(this, newName);
return true;
}
catch(Exception ex) {
destFile.renameTo(oldFile);
return false;
}
}
else {
LogUtils.warn("cannot rename "+oldFile.getName());
}
}
catch (Exception e) {
LogUtils.warn("cannot rename "+oldFile.getName(), e);
}
}
else {
//this.setName(newName);
try {
getModel().changeNodeName(this, newName);
return true;
}
catch(Exception ex) {
// do nth.
}
}
return false;
}
public void treeExpanded(TreeExpansionEvent event) {
if(!inRefresh && getChildCount() <= 0) {
loadDirectoryFiles(getFile());
}
}
public void treeCollapsed(TreeExpansionEvent event) {
}
}