X-Git-Url: https://git.pterodactylus.net/?p=jSite2.git;a=blobdiff_plain;f=src%2Fnet%2Fpterodactylus%2Fjsite%2Fgui%2FFileManager.java;h=1d81bd88746cd152cbc09cf375acf29b1bed5510;hp=6bd83fc1f6c97c662eec38f11587e918796de1ed;hb=2293cd9e21873f7ce21a1046cb66052c55543a45;hpb=3964c896681793cb27a0c02c6482c5d7704d5d0c diff --git a/src/net/pterodactylus/jsite/gui/FileManager.java b/src/net/pterodactylus/jsite/gui/FileManager.java index 6bd83fc..1d81bd8 100644 --- a/src/net/pterodactylus/jsite/gui/FileManager.java +++ b/src/net/pterodactylus/jsite/gui/FileManager.java @@ -28,13 +28,12 @@ import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.awt.Point; 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.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -43,17 +42,28 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; import javax.swing.BorderFactory; +import javax.swing.DefaultComboBoxModel; +import javax.swing.DefaultListCellRenderer; import javax.swing.JButton; -import javax.swing.JCheckBoxMenuItem; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JSplitPane; import javax.swing.JTextField; import javax.swing.JTree; +import javax.swing.SwingConstants; +import javax.swing.border.EmptyBorder; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; @@ -62,13 +72,15 @@ import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; +import net.pterodactylus.jsite.core.FileOverride; +import net.pterodactylus.jsite.core.Project; +import net.pterodactylus.jsite.core.ProjectFile; 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.jsite.i18n.gui.I18nMenu; +import net.pterodactylus.util.io.MimeTypes; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.swing.SwingUtils; @@ -77,7 +89,7 @@ import net.pterodactylus.util.swing.SwingUtils; * * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ -public class FileManager extends JDialog implements I18nable, ActionListener, TreeSelectionListener, MouseListener { +public class FileManager extends JDialog implements I18nable, TreeSelectionListener, MouseListener { /** Logger. */ private static final Logger logger = Logging.getLogger(FileManager.class.getName()); @@ -103,9 +115,6 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** The “set default file” action. */ private I18nAction setDefaultFileAction; - /** The “insert” action. */ - private I18nAction insertAction; - /** The “project files” label. */ private I18nLabel projectFilesLabel; @@ -136,11 +145,62 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** The “file size” text field. */ private JTextField fileSizeTextField; + /** The “insert settings” label. */ + private I18nLabel insertSettingsLabel; + + /** The “insert default” label. */ + private I18nLabel insertDefaultLabel; + + /** The “insert default” checkbox. */ + private JCheckBox insertDefaultCheckBox; + + /** The “override insert default” action. */ + private I18nAction overrideInsertDefaultAction; + + /** The “override insert default” checkbox. */ + private JCheckBox overrideInsertDefaultCheckBox; + + /** The “override insert” action. */ + private Action insertOverrideAction; + + /** The “override insert” checkbox. */ + private JCheckBox insertOverrideCheckBox; + + /** The “content type settings” label. */ + private I18nLabel contentTypeSettingsLabel; + + /** The “content type default” label. */ + private I18nLabel contentTypeDefaultLabel; + + /** The “content type default” text field. */ + private JTextField contentTypeDefaultTextField; + + /** The “override content type default” action. */ + private I18nAction overrideContentTypeDefaultAction; + + /** The “override content type default” checkbox. */ + private JCheckBox overrideContentTypeDefaultCheckBox; + + /** The “content type override” action. */ + private Action contentTypeOverrideAction; + + /** The “content type override” combo box. */ + private JComboBox contentTypeOverrideComboBox; + /** The context menu for the tree. */ private JPopupMenu treeContextMenu; - /** The “insert” checkbox. */ - private JCheckBoxMenuItem insertCheckBoxMenuItem; + /** The “apply override” menu. */ + private I18nMenu overrideMenu; + + /** The “apply insert override” action. */ + private I18nAction applyInsertOverrideAction; + + /** The “apply mime type override” action. */ + private I18nAction applyMimeTypeOverrideAction; + + /** The “remove override” action. */ + private I18nAction removeOverrideAction; /** * Creates a new file manager. @@ -192,7 +252,19 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * {@inheritDoc} */ + @SuppressWarnings("synthetic-access") public void actionPerformed(ActionEvent e) { + String defaultFile = project.getDefaultFile(); + if ((defaultFile == null) || (defaultFile.length() == 0)) { + /* TODO - i18n */ + JOptionPane.showMessageDialog(FileManager.this, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE); + return; + } + ProjectFile projectFile = project.getFile(defaultFile); + if (projectFile == null) { + JOptionPane.showMessageDialog(FileManager.this, I18n.get(""), I18n.get(""), JOptionPane.ERROR_MESSAGE); + return; + } setVisible(false); } }; @@ -211,6 +283,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * {@inheritDoc} */ + @SuppressWarnings("synthetic-access") public void actionPerformed(ActionEvent actionEvent) { TreePath selectedPath = fileTree.getSelectionPath(); if (selectedPath == null) { @@ -230,17 +303,148 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr } String completePath = projectFileWrapper.getProjectFile().getCompletePath(); project.setDefaultFile(completePath); + fileTree.setShowsRootHandles(false); + fileTree.repaint(); } }; - insertAction = new I18nAction("fileManager.menu.item.insert") { + applyInsertOverrideAction = new I18nAction("fileManager.menu.item.applyInsertOverride") { /** * {@inheritDoc} */ - public void actionPerformed(ActionEvent e) { - /* TODO */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent actionEvent) { + applyInsertOverride(); + } + }; + applyMimeTypeOverrideAction = new I18nAction("fileManager.menu.item.applyMimeTypeOverride") { + + /** + * {@inheritDoc} + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent actionEvent) { + applyMimeTypeOverride(); + } + }; + removeOverrideAction = new I18nAction("fileManager.menu.item.removeOverride") { + + /** + * {@inheritDoc} + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent actionEvent) { + removeOverride(); } }; + overrideInsertDefaultAction = new I18nAction("fileManager.checkbox.overrideInsertDefault") { + + /** + * {@inheritDoc} + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent actionEvent) { + boolean overrideInsert = overrideInsertDefaultCheckBox.isSelected(); + insertOverrideAction.setEnabled(overrideInsert); + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + ProjectFileWrapper projectFileWrapper = selectedProjectFileWrappers.get(0); + ProjectFile projectFile = projectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverride(projectFile); + if (overrideInsert) { + if (fileOverride == null) { + fileOverride = new FileOverride(); + project.addFileOverride(projectFile, fileOverride); + fileOverride.setInsert(!projectFile.isHidden()); + } + } else { + fileOverride.setInsert(null); + if (fileOverride.isEmpty()) { + project.removeFileOverride(projectFile); + } + } + fileTree.setShowsRootHandles(false); + fileTree.repaint(); + } + }; + overrideInsertDefaultAction.setEnabled(false); + insertOverrideAction = new AbstractAction() { + + /** + * {@inheritDoc} + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent actionEvent) { + boolean insertOverride = insertOverrideCheckBox.isSelected(); + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + ProjectFileWrapper projectFileWrapper = selectedProjectFileWrappers.get(0); + ProjectFile projectFile = projectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverride(projectFile); + fileOverride.setInsert(insertOverride); + fileTree.setShowsRootHandles(false); + fileTree.repaint(); + } + }; + insertOverrideAction.setEnabled(false); + overrideContentTypeDefaultAction = new I18nAction("fileManager.checkbox.overrideContentTypeDefault") { + + /** + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent actionEvent) { + boolean contentTypeOverrideEnabled = overrideContentTypeDefaultCheckBox.isSelected(); + contentTypeOverrideComboBox.setEnabled(contentTypeOverrideEnabled); + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + ProjectFileWrapper projectFileWrapper = selectedProjectFileWrappers.get(0); + ProjectFile projectFile = projectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverride(projectFile); + if (contentTypeOverrideEnabled) { + if (fileOverride == null) { + fileOverride = new FileOverride(); + project.addFileOverride(projectFile, fileOverride); + } + String projectFileName = projectFile.getName(); + String mimeType = MimeTypes.getMimeType(getFileExtension(projectFileName)); + fileOverride.setContentType(mimeType); + fillComboBox(projectFileName); + contentTypeOverrideComboBox.setSelectedItem(mimeType); + } else { + fileOverride.setContentType(null); + if (fileOverride.isEmpty()) { + project.removeFileOverride(projectFile); + } + } + } + }; + overrideContentTypeDefaultAction.setEnabled(false); + contentTypeOverrideAction = new AbstractAction() { + + /** + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + @SuppressWarnings("synthetic-access") + public void actionPerformed(ActionEvent actionEvent) { + if (!contentTypeOverrideComboBox.isEnabled()) { + return; + } + String selectedContentType = (String) contentTypeOverrideComboBox.getSelectedItem(); + logger.log(Level.FINEST, "selectedContentType: " + selectedContentType); + if ("--".equals(selectedContentType)) { + return; + } + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + for (ProjectFileWrapper projectFileWrapper : selectedProjectFileWrappers) { + ProjectFile projectFile = projectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverride(projectFile); + if (fileOverride == null) { + fileOverride = new FileOverride(); + project.addFileOverride(projectFile, fileOverride); + } + fileOverride.setContentType(selectedContentType); + } + } + }; + contentTypeOverrideAction.setEnabled(false); } /** @@ -249,8 +453,14 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr private void initComponents() { treeContextMenu = new JPopupMenu(); treeContextMenu.add(setDefaultFileAction); - insertCheckBoxMenuItem = new JCheckBoxMenuItem(insertAction); - treeContextMenu.add(insertCheckBoxMenuItem); + + overrideMenu = new I18nMenu("fileManager.menu.override"); + treeContextMenu.add(overrideMenu); + + overrideMenu.add(applyInsertOverrideAction); + overrideMenu.add(applyMimeTypeOverrideAction); + overrideMenu.addSeparator(); + overrideMenu.add(removeOverrideAction); JPanel contentPanel = new JPanel(new BorderLayout(12, 12)); contentPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12)); @@ -267,11 +477,13 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr * @return The mail panel */ private Component createFileManagerPanel() { - JPanel fileManagerPanel = new JPanel(new BorderLayout(12, 12)); + JSplitPane fileManagerPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true); + fileManagerPanel.setBorder(null); /* file tree panel */ JPanel fileTreePanel = new JPanel(new BorderLayout(12, 12)); - fileManagerPanel.add(fileTreePanel, BorderLayout.LINE_START); + fileTreePanel.setBorder(new EmptyBorder(0, 0, 0, 12)); + fileManagerPanel.setLeftComponent(fileTreePanel); fileTree = new JTree(fileTreeModel); fileTree.setShowsRootHandles(false); @@ -279,7 +491,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr fileTree.addMouseListener(this); fileTree.setCellRenderer(fileCellRenderer); fileTreePanel.add(fileScrollPane = new JScrollPane(fileTree), BorderLayout.CENTER); - fileScrollPane.setPreferredSize(new Dimension(250, 400)); + fileScrollPane.setPreferredSize(new Dimension(200, 350)); projectFilesLabel = new I18nLabel("fileManager.label.projectFiles", fileTree); JPanel projectFilesLabelPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0)); @@ -288,12 +500,14 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /* the right panel */ JPanel rightPanel = new JPanel(new BorderLayout(12, 12)); - fileManagerPanel.add(rightPanel, BorderLayout.CENTER); + rightPanel.setBorder(new EmptyBorder(0, 12, 0, 0)); + fileManagerPanel.setRightComponent(rightPanel); /* properties panel */ JPanel propertiesPanel = new JPanel(new GridBagLayout()); rightPanel.add(propertiesPanel, BorderLayout.CENTER); propertiesPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(12, 12, 12, 12))); + propertiesPanel.setPreferredSize(new Dimension(500, 350)); filePropertiesLabel = new I18nLabel("fileManager.label.fileProperties"); filePropertiesLabel.setFont(filePropertiesLabel.getFont().deriveFont(Font.BOLD)); @@ -303,22 +517,55 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr filePathTextField = new JTextField(); filePathTextField.setEditable(false); propertiesPanel.add(filePathLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 24, 0, 0), 0, 0)); - propertiesPanel.add(filePathTextField, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); + propertiesPanel.add(filePathTextField, new GridBagConstraints(1, 1, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); fileNameLabel = new I18nLabel("fileManager.label.fileName"); fileNameTextField = new JTextField(); fileNameTextField.setEditable(false); propertiesPanel.add(fileNameLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 24, 0, 0), 0, 0)); - propertiesPanel.add(fileNameTextField, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); + propertiesPanel.add(fileNameTextField, new GridBagConstraints(1, 2, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); fileSizeLabel = new I18nLabel("fileManager.label.fileSize"); fileSizeTextField = new JTextField(); fileSizeTextField.setEditable(false); propertiesPanel.add(fileSizeLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 24, 0, 0), 0, 0)); - propertiesPanel.add(fileSizeTextField, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); + propertiesPanel.add(fileSizeTextField, new GridBagConstraints(1, 3, 3, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); + + /* file settings. */ + insertSettingsLabel = new I18nLabel("fileManager.label.insertSetting"); + insertSettingsLabel.setFont(insertSettingsLabel.getFont().deriveFont(Font.BOLD)); + propertiesPanel.add(insertSettingsLabel, new GridBagConstraints(0, 4, 2, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(24, 0, 0, 0), 0, 0)); + + insertDefaultLabel = new I18nLabel("fileManager.label.insertDefault"); + propertiesPanel.add(insertDefaultLabel, new GridBagConstraints(0, 5, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 24, 0, 0), 0, 0)); + insertDefaultCheckBox = new JCheckBox(); + insertDefaultCheckBox.setEnabled(false); + propertiesPanel.add(insertDefaultCheckBox, new GridBagConstraints(1, 5, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); + overrideInsertDefaultCheckBox = new JCheckBox(overrideInsertDefaultAction); + propertiesPanel.add(overrideInsertDefaultCheckBox, new GridBagConstraints(0, 6, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 24, 0, 0), 0, 0)); + insertOverrideCheckBox = new JCheckBox(insertOverrideAction); + propertiesPanel.add(insertOverrideCheckBox, new GridBagConstraints(1, 6, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); + + /* content type settings. */ + contentTypeSettingsLabel = new I18nLabel("fileManager.label.contentTypeSetting"); + contentTypeSettingsLabel.setFont(contentTypeSettingsLabel.getFont().deriveFont(Font.BOLD)); + propertiesPanel.add(contentTypeSettingsLabel, new GridBagConstraints(0, 7, 2, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(24, 0, 0, 0), 0, 0)); + + contentTypeDefaultLabel = new I18nLabel("fileManager.label.contentTypeDefault"); + propertiesPanel.add(contentTypeDefaultLabel, new GridBagConstraints(0, 8, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 24, 0, 0), 0, 0)); + contentTypeDefaultTextField = new JTextField(); + contentTypeDefaultTextField.setEditable(false); + propertiesPanel.add(contentTypeDefaultTextField, new GridBagConstraints(1, 8, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); + overrideContentTypeDefaultCheckBox = new JCheckBox(overrideContentTypeDefaultAction); + propertiesPanel.add(overrideContentTypeDefaultCheckBox, new GridBagConstraints(0, 9, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 24, 0, 0), 0, 0)); + contentTypeOverrideComboBox = new JComboBox(new DefaultComboBoxModel()); + contentTypeOverrideComboBox.setRenderer(new MimeTypeComboBoxRenderer()); + contentTypeOverrideComboBox.addActionListener(contentTypeOverrideAction); + contentTypeOverrideComboBox.setEnabled(false); + propertiesPanel.add(contentTypeOverrideComboBox, new GridBagConstraints(1, 9, 1, 1, 1.0, 0.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(12, 12, 0, 0), 0, 0)); /* glue panel. */ - propertiesPanel.add(new JPanel(), new GridBagConstraints(0, 4, 2, 1, 1.0, 1.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); + propertiesPanel.add(new JPanel(), new GridBagConstraints(0, 10, 2, 1, 1.0, 1.0, GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); /* action button panel */ JPanel actionButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 12, 12)); @@ -383,15 +630,23 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr if (!mouseEvent.isPopupTrigger()) { return; } - Point eventLocation = mouseEvent.getPoint(); - TreePath clickedPath = fileTree.getPathForLocation(eventLocation.x, eventLocation.y); - if (clickedPath == null) { - return; + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(false); + TreePath clickedPath = fileTree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY()); + ProjectFileWrapper clickedProjectFileWrapper = (ProjectFileWrapper) clickedPath.getLastPathComponent(); + if (!selectedProjectFileWrappers.contains(clickedProjectFileWrapper)) { + fileTree.setSelectionPath(clickedPath); + selectedProjectFileWrappers = getSelectedProjectFileWrappers(false); } - fileTree.setSelectionPath(clickedPath); - ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) clickedPath.getLastPathComponent(); - insertCheckBoxMenuItem.setSelected(!isHidden(projectFileWrapper)); - treeContextMenu.show(fileTree, eventLocation.x, eventLocation.y); + logger.log(Level.FINEST, "selectedProjectFileWrappers.size(): " + selectedProjectFileWrappers.size()); + if (selectedProjectFileWrappers.size() == 1) { + ProjectFileWrapper projectFileWrapper = selectedProjectFileWrappers.get(0); + ProjectFile projectFile = projectFileWrapper.getProjectFile(); + setDefaultFileAction.setEnabled(!isHidden(projectFileWrapper) && projectFile.isFile() && !projectFile.getCompletePath().equals(project.getDefaultFile())); + } else { + setDefaultFileAction.setEnabled(false); + } + overrideMenu.setVisible(selectedProjectFileWrappers.size() > 1); + treeContextMenu.show(fileTree, mouseEvent.getX(), mouseEvent.getY()); } /** @@ -406,7 +661,169 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr 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())); + logger.log(Level.FINEST, "fileOverride: " + fileOverride); + return ((fileOverride == null) && projectFile.isHidden()) || ((fileOverride != null) && (fileOverride.isInsert() == null) && projectFile.isHidden()) || ((fileOverride != null) && (fileOverride.isInsert() != null) && (Boolean.FALSE.equals(fileOverride.isInsert()))); + } + + /** + * Opens the “apply insert override” dialog and lets the user apply an + * override for the “insert” setting for multiple files. + */ + private void applyInsertOverride() { + JCheckBox insertCheckBox = new JCheckBox(I18n.get("fileManager.menu.item.insert.name")); + String okString = I18n.get("general.button.okay.name"); + String cancelString = I18n.get("general.button.cancel.name"); + int choice = JOptionPane.showOptionDialog(this, new Object[] { I18n.get("fileManager.dialog.insertOverride.message"), insertCheckBox }, I18n.get("fileManager.dialog.insertOverride.title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] { okString, cancelString }, okString); + logger.log(Level.FINEST, "choice: " + choice); + if ((choice == JOptionPane.CLOSED_OPTION) || (choice == 1)) { + return; + } + logger.log(Level.INFO, "selected insert override: " + insertCheckBox.isSelected()); + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + for (ProjectFileWrapper selectedProjectFileWrapper : selectedProjectFileWrappers) { + ProjectFile projectFile = selectedProjectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverride(projectFile); + if (fileOverride == null) { + fileOverride = new FileOverride(); + project.addFileOverride(projectFile, fileOverride); + } + fileOverride.setInsert(insertCheckBox.isSelected()); + } + /* HACK - Swing sucks a bit */ + fileTree.setShowsRootHandles(false); + } + + /** + * Opens the “apply mime type override” dialog and lets the user apply an + * override for the “mime type” setting for multiple files. + */ + private void applyMimeTypeOverride() { + List allMimeTypes = MimeTypes.getAllMimeTypes(); + allMimeTypes.add(0, null); + JComboBox mimeTypeComboBox = new JComboBox(allMimeTypes.toArray()); + String okString = I18n.get("general.button.okay.name"); + String cancelString = I18n.get("general.button.cancel.name"); + int choice = JOptionPane.showOptionDialog(this, new Object[] { I18n.get("fileManager.dialog.mimeTypeOverride.message"), mimeTypeComboBox }, I18n.get("fileManager.dialog.mimeTypeOverride.title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] { okString, cancelString }, okString); + if ((choice == JOptionPane.CLOSED_OPTION) || (choice == 1)) { + return; + } + logger.log(Level.FINE, "selected mime type: " + mimeTypeComboBox.getSelectedItem()); + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + for (ProjectFileWrapper selectedProjectFileWrapper : selectedProjectFileWrappers) { + ProjectFile projectFile = selectedProjectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverride(projectFile); + if (fileOverride == null) { + fileOverride = new FileOverride(); + project.addFileOverride(projectFile, fileOverride); + } + fileOverride.setContentType((String) mimeTypeComboBox.getSelectedItem()); + } + } + + /** + * Removes the overrides of all selected files. + */ + private void removeOverride() { + String continueString = I18n.get("general.button.continue.name"); + String cancelString = I18n.get("general.button.cancel.name"); + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + int choice = JOptionPane.showOptionDialog(this, I18n.get("fileManager.dialog.removeOverride.message", selectedProjectFileWrappers.size()), I18n.get("fileManager.dialog.removeOverride.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, new Object[] { continueString, cancelString }, continueString); + if ((choice == JOptionPane.CLOSED_OPTION) || (choice == 1)) { + return; + } + for (ProjectFileWrapper selectedProjectFileWrapper : selectedProjectFileWrappers) { + project.removeFileOverride(selectedProjectFileWrapper.getProjectFile()); + } + } + + /** + * Returns all currently selected {@link ProjectFileWrapper}s. + * + * @param filesOnly + * true to return only selected files, + * false to include directories + * @return All selected project file wrappers + */ + private List getSelectedProjectFileWrappers(boolean filesOnly) { + List selectedProjectFileWrappers = new ArrayList(); + TreePath[] selectedPaths = fileTree.getSelectionPaths(); + if (selectedPaths != null) { + for (TreePath selectedPath : selectedPaths) { + ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) selectedPath.getLastPathComponent(); + if (filesOnly && !projectFileWrapper.getProjectFile().isFile()) { + continue; + } + selectedProjectFileWrappers.add(projectFileWrapper); + } + } + return selectedProjectFileWrappers; + } + + /** + * Sets the given action’s enabled state to the given enabled state if the + * action’s current enabled state is not the given enabled state. + * + * @param action + * The action to set the enabled state on + * @param enabled + * The new enabled state of the action + */ + private void setEnabled(Action action, boolean enabled) { + if (action.isEnabled() != enabled) { + action.setEnabled(enabled); + } + } + + /** + * Sets the given button’s selected state to the given selected state if the + * button’s current selected state is not the given selected state. + * + * @param button + * The button to set the selected state on + * @param selected + * The new selected state of the button + */ + private void setSelected(AbstractButton button, boolean selected) { + if (button.isSelected() != selected) { + button.setSelected(selected); + } + } + + /** + * Returns the extension of the given filename. If the file name does not + * have an extension, the name of the file (without any path components) is + * returned. + * + * @param fileName + * The name of the file + * @return The extension of the file + */ + private String getFileExtension(String fileName) { + String lastComponent = fileName.substring(fileName.lastIndexOf(File.separator) + 1); + return lastComponent.substring(lastComponent.lastIndexOf('.') + 1); + } + + /** + * Repopulates the content type combo box with all content types, putting + * the most probably ones to the front of the list. + * + * @param fileName + * The name of the file + */ + private void fillComboBox(String fileName) { + String fileExtension = getFileExtension(fileName); + List allMimeTypes = MimeTypes.getAllMimeTypes(); + List eligibleMimeTypes = MimeTypes.getMimeTypes(fileExtension); + for (String mimeType : eligibleMimeTypes) { + allMimeTypes.remove(mimeType); + allMimeTypes.add(eligibleMimeTypes.indexOf(mimeType), mimeType); + } + allMimeTypes.add(eligibleMimeTypes.size(), "--"); + DefaultComboBoxModel contentTypeOverrideComboBoxModel = (DefaultComboBoxModel) contentTypeOverrideComboBox.getModel(); + contentTypeOverrideComboBoxModel.removeAllElements(); + for (String mimeType : allMimeTypes) { + contentTypeOverrideComboBoxModel.addElement(mimeType); + } } // @@ -431,31 +848,66 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr * {@inheritDoc} */ public void valueChanged(TreeSelectionEvent treeSelectionEvent) { - TreePath[] selectedPaths = fileTree.getSelectionPaths(); - if ((selectedPaths != null) && (selectedPaths.length == 1)) { - Object lastPathComponent = selectedPaths[0].getLastPathComponent(); - if (!(lastPathComponent instanceof ProjectFileWrapper)) { - logger.log(Level.SEVERE, "lastPathComponent is not a ProjectFileWrapper!"); - return; - } - ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) lastPathComponent; + List selectedProjectFileWrappers = getSelectedProjectFileWrappers(true); + String filePathText = ""; + String fileNameText = ""; + String fileSizeText = ""; + boolean insertDefaultSelected = false; + boolean overrideInsertEnabled = false; + boolean overrideInsertSelected = false; + boolean insertOverrideEnabled = false; + boolean insertOverrideSelected = false; + String defaultContentType = ""; + boolean overrideContentTypeEnabled = false; + boolean overrideContentTypeSelected = false; + boolean contentTypeOverrideEnabled = false; + String contentTypeOverride = "--"; + if (selectedProjectFileWrappers.size() == 1) { + ProjectFileWrapper projectFileWrapper = selectedProjectFileWrappers.get(0); ProjectFile projectFile = projectFileWrapper.getProjectFile(); if (projectFile.isFile()) { - fileNameTextField.setText(projectFile.getName()); - fileSizeTextField.setText(String.valueOf(projectFile.getSize())); + String completePath = projectFile.getCompletePath(); + int lastSeparator = completePath.lastIndexOf(File.separatorChar); + if (lastSeparator != -1) { + filePathText = completePath.substring(0, lastSeparator); + } + fileNameText = projectFile.getName(); + fileSizeText = String.valueOf(projectFile.getSize()); + insertDefaultSelected = !projectFile.isHidden(); + overrideInsertEnabled = true; + overrideContentTypeEnabled = true; + defaultContentType = MimeTypes.getMimeType(getFileExtension(projectFile.getName())); + FileOverride fileOverride = project.getFileOverride(projectFile); + if (fileOverride != null) { + Boolean overrideInsert = fileOverride.isInsert(); + overrideInsertSelected = overrideInsert != null; + insertOverrideEnabled = overrideInsertSelected; + insertOverrideSelected = overrideInsertSelected ? overrideInsert : !projectFile.isHidden(); + String contentType = fileOverride.getContentType(); + if (contentType != null) { + contentTypeOverride = contentType; + overrideContentTypeSelected = true; + contentTypeOverrideEnabled = true; + } + } + fillComboBox(projectFile.getName()); } + } else if (selectedProjectFileWrappers.size() > 1) { + /* TODO */ } - } - - // - // INTERFACE ActionListener - // - - /** - * {@inheritDoc} - */ - public void actionPerformed(ActionEvent actionEvent) { - /* TODO */ + filePathTextField.setText(filePathText); + fileNameTextField.setText(fileNameText); + fileSizeTextField.setText(fileSizeText); + setSelected(insertDefaultCheckBox, insertDefaultSelected); + setEnabled(overrideInsertDefaultAction, overrideInsertEnabled); + setSelected(overrideInsertDefaultCheckBox, overrideInsertSelected); + setEnabled(insertOverrideAction, insertOverrideEnabled); + setSelected(insertOverrideCheckBox, insertOverrideSelected); + contentTypeDefaultTextField.setText(defaultContentType); + overrideContentTypeDefaultAction.setEnabled(overrideContentTypeEnabled); + overrideContentTypeDefaultCheckBox.setSelected(overrideContentTypeSelected); + contentTypeOverrideComboBox.setEnabled(contentTypeOverrideEnabled); + contentTypeOverrideComboBox.setSelectedItem(contentTypeOverride); } // @@ -530,11 +982,18 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr } ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) value; ProjectFile projectFile = projectFileWrapper.getProjectFile(); + FileOverride fileOverride = project.getFileOverride(projectFile); String completePath = projectFile.getCompletePath(); boolean paintBold = false; boolean paintHalfColor = false; - if (projectFile.isFile() && projectFile.isHidden()) { - /* TODO - check override */ + boolean showFile = !projectFile.isHidden(); + if (fileOverride != null) { + Boolean insertOverride = fileOverride.isInsert(); + if (insertOverride != null) { + showFile = insertOverride; + } + } + if (projectFile.isFile() && !showFile) { paintHalfColor = true; } else if (completePath.equals(project.getDefaultFile())) { paintBold = true; @@ -749,8 +1208,7 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr return true; } ProjectFileWrapper projectFileWrapper = (ProjectFileWrapper) node; - ProjectFile projectFile = projectFileWrapper.getProjectFile(); - return projectFile.getFiles().isEmpty(); + return projectFileWrapper.getProjectFile().isFile(); } /** @@ -767,17 +1225,22 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr /** * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ + @SuppressWarnings("synthetic-access") public void propertyChange(PropertyChangeEvent propertyChangeEvent) { if (Project.PROPERTY_DEFAULT_FILE.equals(propertyChangeEvent.getPropertyName())) { - String oldCompletePath = (String) propertyChangeEvent.getOldValue(); + if (propertyChangeEvent.getOldValue() != null) { + String oldCompletePath = (String) propertyChangeEvent.getOldValue(); + logger.log(Level.FINEST, "oldCompletePath: " + oldCompletePath); + ProjectFile oldProjectFile = pathProjectFiles.get(oldCompletePath); + logger.log(Level.FINEST, "oldProjectFile: " + oldProjectFile); + ProjectFileWrapper oldProjectFileWrapper = projectFileWrappers.get(oldProjectFile); + logger.log(Level.FINEST, "oldProjectFileWrapper: " + oldProjectFileWrapper); + fireTreeNodesChanged(oldProjectFileWrapper); + } 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); @@ -840,4 +1303,38 @@ public class FileManager extends JDialog implements I18nable, ActionListener, Tr } + /** + * A cell renderer for combo boxes that converts the string “--” to a + * separator. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + */ + private class MimeTypeComboBoxRenderer extends DefaultListCellRenderer { + + /** The separator component. */ + private final JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL); + + /** + * Empty constructor. + */ + MimeTypeComboBoxRenderer() { + /* do nothing. */ + } + + /** + * {@inheritDoc} + */ + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + if ("--".equals(value)) { + return separator; + } + if (value == null) { + return super.getListCellRendererComponent(list, "\u00a0", index, isSelected, cellHasFocus); + } + return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + } + + } + }