From: David ‘Bombe’ Roden Date: Fri, 30 May 2008 12:20:09 +0000 (+0200) Subject: fix display of default file X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=3964c896681793cb27a0c02c6482c5d7704d5d0c;p=jSite2.git fix display of default file --- diff --git a/src/net/pterodactylus/jsite/gui/FileManager.java b/src/net/pterodactylus/jsite/gui/FileManager.java index 0c714c5..6bd83fc 100644 --- a/src/net/pterodactylus/jsite/gui/FileManager.java +++ b/src/net/pterodactylus/jsite/gui/FileManager.java @@ -33,6 +33,8 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -46,6 +48,7 @@ import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JDialog; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; @@ -63,6 +66,7 @@ import net.pterodactylus.jsite.i18n.I18n; import net.pterodactylus.jsite.i18n.I18nable; import net.pterodactylus.jsite.i18n.gui.I18nAction; import net.pterodactylus.jsite.i18n.gui.I18nLabel; +import net.pterodactylus.jsite.project.FileOverride; import net.pterodactylus.jsite.project.Project; import net.pterodactylus.jsite.project.ProjectFile; import net.pterodactylus.util.logging.Logging; @@ -70,7 +74,7 @@ import net.pterodactylus.util.swing.SwingUtils; /** * Manages physical and virtual files in a project. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ public class FileManager extends JDialog implements I18nable, ActionListener, TreeSelectionListener, MouseListener { @@ -140,7 +144,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Creates a new file manager. - * + * * @param swingInterface * The Swing interface * @param project @@ -152,6 +156,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr this.swingInterface = swingInterface; this.project = project; fileTreeModel = new ProjectFileTreeModel(); + project.addPropertyChangeListener(fileTreeModel); fileCellRenderer = new FileCellRenderer(); initActions(); initComponents(); @@ -206,8 +211,25 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * {@inheritDoc} */ - public void actionPerformed(ActionEvent e) { - /* TODO */ + public void actionPerformed(ActionEvent actionEvent) { + TreePath selectedPath = fileTree.getSelectionPath(); + if (selectedPath == null) { + logger.log(Level.WARNING, "nothing selected!"); + return; + } + ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) selectedPath.getLastPathComponent(); + if (isHidden(projectFileWrapper)) { + /* TODO - i18n */ + JOptionPane.showMessageDialog(FileManager.this, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE); + return; + } + if (projectFileWrapper.getProjectFile().isDirectory()) { + /* TODO - i18n */ + JOptionPane.showMessageDialog(FileManager.this, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE); + return; + } + String completePath = projectFileWrapper.getProjectFile().getCompletePath(); + project.setDefaultFile(completePath); } }; insertAction = new I18nAction("fileManager.menu.item.insert") { @@ -241,7 +263,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Creates the main panel with the file tree and the file properties. - * + * * @return The mail panel */ private Component createFileManagerPanel() { @@ -311,7 +333,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Creates the button panel. - * + * * @return The button panel */ private Component createButtonPanel() { @@ -353,7 +375,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Checks whether the given mouse event is a popup trigger and occured over * a file. If so, the context menu is shown. - * + * * @param mouseEvent * The mouse event to check */ @@ -367,9 +389,26 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr return; } fileTree.setSelectionPath(clickedPath); + ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) clickedPath.getLastPathComponent(); + insertCheckBoxMenuItem.setSelected(!isHidden(projectFileWrapper)); treeContextMenu.show(fileTree, eventLocation.x, eventLocation.y); } + /** + * Finds whether the {@link ProjectFile} given by + * projectFileWrapper is hidden. + * + * @param projectFileWrapper + * The wrapped project file + * @return true if the file is hidden and should not be + * inserted, false otherwise + */ + private boolean isHidden(ProjectFileWrapper projectFileWrapper) { + ProjectFile projectFile = projectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverrides().get(projectFile.getCompletePath()); + return ((fileOverride == null) && projectFile.isHidden()) || ((fileOverride != null) && (fileOverride.isInsert())); + } + // // INTERFACE I18nable // @@ -393,7 +432,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr */ public void valueChanged(TreeSelectionEvent treeSelectionEvent) { TreePath[] selectedPaths = fileTree.getSelectionPaths(); - if (selectedPaths.length == 1) { + if ((selectedPaths != null) && (selectedPaths.length == 1)) { Object lastPathComponent = selectedPaths[0].getLastPathComponent(); if (!(lastPathComponent instanceof ProjectFileWrapper)) { logger.log(Level.SEVERE, "lastPathComponent is not a ProjectFileWrapper!"); @@ -461,7 +500,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Tree cell renderer that takes care of certain display properties for * project-specific stuff. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ private class FileCellRenderer extends DefaultTreeCellRenderer { @@ -492,15 +531,26 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) value; ProjectFile projectFile = projectFileWrapper.getProjectFile(); String completePath = projectFile.getCompletePath(); - if (projectFile.isHidden()) { + boolean paintBold = false; + boolean paintHalfColor = false; + if (projectFile.isFile() && projectFile.isHidden()) { /* TODO - check override */ + paintHalfColor = true; + } else if (completePath.equals(project.getDefaultFile())) { + paintBold = true; + } else if (projectFile.getParents().size() == 1) { + paintBold = true; + } + if (paintHalfColor) { + /* TODO - cache colors */ Color foreground = superCellRenderer.getForeground(); Color background = selected ? getBackgroundSelectionColor() : getBackgroundNonSelectionColor(); Color averageColor = new Color((foreground.getRed() + background.getRed()) / 2, (foreground.getGreen() + background.getGreen()) / 2, (foreground.getBlue() + background.getBlue()) / 2); superCellRenderer.setForeground(averageColor); - } else if (completePath.equals(project.getDefaultFile())) { - superCellRenderer.setFont(superCellRenderer.getFont().deriveFont(Font.BOLD)); - } else if (projectFile.getParents().size() == 1) { + } else { + superCellRenderer.setForeground(selected ? getTextSelectionColor() : getTextNonSelectionColor()); + } + if (paintBold) { superCellRenderer.setFont(superCellRenderer.getFont().deriveFont(Font.BOLD)); } else { superCellRenderer.setFont(superCellRenderer.getFont().deriveFont(Font.PLAIN)); @@ -512,10 +562,10 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * TreeModel that is based on {@link Project#getBaseFile()}. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ - private class ProjectFileTreeModel implements TreeModel { + private class ProjectFileTreeModel implements TreeModel, PropertyChangeListener { /** Tree model listeners. */ private final List treeModelListeners = Collections.synchronizedList(new ArrayList()); @@ -523,6 +573,9 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** The base project file. */ private ProjectFile baseProjectFile; + /** Maps path names to project files. */ + private final Map pathProjectFiles = Collections.synchronizedMap(new HashMap()); + /** Maps project files to wrappers. */ private final Map projectFileWrappers = Collections.synchronizedMap(new HashMap()); @@ -552,14 +605,35 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr } /** + * Notifies all listeners that a node has changed. + * + * @param changedProjectFileWrapper + * The wrapper around the changed project file + */ + protected void fireTreeNodesChanged(ProjectFileWrapper changedProjectFileWrapper) { + ProjectFile changedProjectFile = changedProjectFileWrapper.getProjectFile(); + ProjectFile changedProjectFileParent = changedProjectFile.getParent(); + ProjectFile currentProjectFileParent = changedProjectFile; + List parentProjectFileWrappers = new ArrayList(); + do { + parentProjectFileWrappers.add(0, projectFileWrappers.get(currentProjectFileParent)); + currentProjectFileParent = currentProjectFileParent.getParent(); + } while (currentProjectFileParent != null); + TreeModelEvent treeModelEvent = new TreeModelEvent(this, parentProjectFileWrappers.toArray(), new int[] { getIndexOfChild(projectFileWrappers.get(changedProjectFileParent), changedProjectFileWrapper) }, new Object[] { changedProjectFileWrapper }); + for (TreeModelListener treeModelListener : treeModelListeners) { + treeModelListener.treeNodesChanged(treeModelEvent); + } + } + + /** * Notifies all listeners that the tree structure has changed * significantly. - * + * * @see TreeModelListener#treeStructureChanged(TreeModelEvent) * @param newRootNode */ protected void fireTreeStructureChanged(ProjectFileWrapper newRootNode) { - for (TreeModelListener treeModelListener: treeModelListeners) { + for (TreeModelListener treeModelListener : treeModelListeners) { treeModelListener.treeStructureChanged(new TreeModelEvent(this, new Object[] { newRootNode })); } } @@ -570,7 +644,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Sets the new base project file. This causes the model to reload. - * + * * @param baseProjectFile * The new base project file */ @@ -578,6 +652,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr public synchronized void setBaseProjectFile(ProjectFile baseProjectFile) { this.baseProjectFile = baseProjectFile; projectFileWrappers.clear(); + pathProjectFiles.clear(); createWrappers(baseProjectFile); projectFileWrappers.get(baseProjectFile).setNameOverride(project.getName()); fireTreeStructureChanged(projectFileWrappers.get(baseProjectFile)); @@ -590,18 +665,20 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Creates {@link ProjectFileWrapper}s for all files below the given * project file. - * + * * @param projectFile * The base project file for all project files to create * wrappers for */ private void createWrappers(ProjectFile projectFile) { projectFileWrappers.put(projectFile, new ProjectFileWrapper(projectFile)); - for (ProjectFile projectFileChild: projectFile.getFiles()) { + pathProjectFiles.put(projectFile.getCompletePath(), projectFile); + for (ProjectFile projectFileChild : projectFile.getFiles()) { if (projectFileChild.isDirectory()) { createWrappers(projectFileChild); } projectFileWrappers.put(projectFileChild, new ProjectFileWrapper(projectFileChild)); + pathProjectFiles.put(projectFileChild.getCompletePath(), projectFileChild); } } @@ -683,12 +760,36 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /* ignore, items will not be modified in tree. */ } + // + // INTERFACE PropertyChangeListener + // + + /** + * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent propertyChangeEvent) { + if (Project.PROPERTY_DEFAULT_FILE.equals(propertyChangeEvent.getPropertyName())) { + String oldCompletePath = (String) propertyChangeEvent.getOldValue(); + String newCompletePath = (String) propertyChangeEvent.getNewValue(); + ProjectFile oldProjectFile = pathProjectFiles.get(oldCompletePath); + ProjectFile newProjectFile = pathProjectFiles.get(newCompletePath); + ProjectFileWrapper oldProjectFileWrapper = projectFileWrappers.get(oldProjectFile); + ProjectFileWrapper newProjectFileWrapper = projectFileWrappers.get(newProjectFile); + System.out.println("oldProjectFileWrapper: " + oldProjectFileWrapper); + System.out.println("newProjectFileWrapper: " + newProjectFileWrapper); + fireTreeNodesChanged(oldProjectFileWrapper); + fireTreeNodesChanged(newProjectFileWrapper); + /* HACK - swing sucks a bit. */ + fileTree.setShowsRootHandles(false); + } + } + } /** * Wrapper around a {@link ProjectFile} that overwrites * {@link Object#toString()} to return the project file’s name. - * + * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ private static class ProjectFileWrapper { @@ -701,7 +802,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Creates a new wrapper around a project file. - * + * * @param projectFile * The project file to wrap */ @@ -711,7 +812,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Returns the wrapped project file. - * + * * @return The wrapped project file */ public ProjectFile getProjectFile() { @@ -721,7 +822,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * Sets the name override. If the name override is not null * it will be shown insted of the project file’s name. - * + * * @param nameOverride * The name override */