/* * Copyright 2016 Igor Maznitsa. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.igormaznitsa.sciareto.ui; import com.igormaznitsa.sciareto.ui.tabs.EditorTabPane; import com.igormaznitsa.sciareto.ui.tabs.TabTitle; import com.igormaznitsa.sciareto.preferences.PreferencesPanel; import com.igormaznitsa.sciareto.ui.tree.ExplorerTree; import com.igormaznitsa.sciareto.ui.misc.AboutPanel; import com.igormaznitsa.sciareto.ui.editors.PictureViewer; import com.igormaznitsa.sciareto.ui.editors.TextEditor; import com.igormaznitsa.sciareto.ui.editors.MMDEditor; import java.awt.BorderLayout; import java.awt.Component; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.KeyEventDispatcher; import java.awt.KeyboardFocusManager; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.concurrent.atomic.AtomicReference; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; import javax.swing.JSplitPane; import javax.swing.JWindow; import javax.swing.KeyStroke; import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import javax.swing.filechooser.FileView; import org.apache.commons.io.FilenameUtils; import com.igormaznitsa.meta.annotation.MayContainNull; import com.igormaznitsa.meta.annotation.MustNotContainNull; import com.igormaznitsa.mindmap.model.MindMap; import com.igormaznitsa.mindmap.model.logger.Logger; import com.igormaznitsa.mindmap.model.logger.LoggerFactory; import com.igormaznitsa.mindmap.swing.panel.utils.Utils; import com.igormaznitsa.sciareto.Context; import com.igormaznitsa.sciareto.Main; import com.igormaznitsa.sciareto.preferences.FileHistoryManager; import com.igormaznitsa.sciareto.preferences.PreferencesManager; import com.igormaznitsa.sciareto.ui.editors.AbstractEditor; import com.igormaznitsa.sciareto.ui.editors.EditorContentType; import com.igormaznitsa.sciareto.ui.editors.SourceTextEditor; import com.igormaznitsa.sciareto.ui.misc.DonateButton; import com.igormaznitsa.sciareto.ui.misc.FileLinkGraphPanel; import com.igormaznitsa.sciareto.ui.misc.GoToFilePanel; import com.igormaznitsa.sciareto.ui.platform.PlatformMenuAction; import com.igormaznitsa.sciareto.ui.platform.PlatformMenuEvent; import com.igormaznitsa.sciareto.ui.platform.PlatformProvider; import com.igormaznitsa.sciareto.ui.tabs.TabProvider; import com.igormaznitsa.sciareto.ui.tree.NodeFileOrFolder; import com.igormaznitsa.sciareto.ui.tree.NodeProject; import com.igormaznitsa.sciareto.ui.tree.NodeProjectGroup; public final class MainFrame extends javax.swing.JFrame implements Context, PlatformMenuAction { private static final long serialVersionUID = 3798040833406256900L; private static final Logger LOGGER = LoggerFactory.getLogger(MainFrame.class); private static final boolean DELETE_MOVING_FILE_TO_TRASH = true; private final EditorTabPane tabPane; private final ExplorerTree explorerTree; private final boolean stateless; private final AtomicReference<Runnable> taskToEndFullScreen = new AtomicReference<>(); private final JPanel stackPanel; private final JPanel mainPanel; private final AtomicReference<FindTextPanel> currentFindTextPanel = new AtomicReference<>(); public MainFrame(@Nonnull @MustNotContainNull final String... args) { super(); initComponents(); if (PlatformProvider.getPlatform().registerPlatformMenuEvent(com.igormaznitsa.sciareto.ui.platform.PlatformMenuEvent.ABOUT, this)) { this.menuHelp.setVisible(false); } if (PlatformProvider.getPlatform().registerPlatformMenuEvent(com.igormaznitsa.sciareto.ui.platform.PlatformMenuEvent.PREFERENCES, this)) { this.menuPreferences.setVisible(false); } if (PlatformProvider.getPlatform().registerPlatformMenuEvent(com.igormaznitsa.sciareto.ui.platform.PlatformMenuEvent.QUIT, this)) { this.separatorExitSection.setVisible(false); this.menuExit.setVisible(false); } PlatformProvider.getPlatform().registerPlatformMenuEvent(PlatformMenuEvent.REOPEN_APPLICATION, this); this.stackPanel = new JPanel(); this.stackPanel.setFocusable(false); this.stackPanel.setOpaque(false); this.stackPanel.setBorder(BorderFactory.createEmptyBorder(32, 32, 16, 32)); this.stackPanel.setLayout(new BoxLayout(this.stackPanel, BoxLayout.Y_AXIS)); final JPanel glassPanel = (JPanel) this.getGlassPane(); glassPanel.setOpaque(false); this.setGlassPane(glassPanel); glassPanel.setLayout(new BorderLayout(8, 8)); glassPanel.add(Box.createGlue(), BorderLayout.CENTER); final JPanel ppanel = new JPanel(new BorderLayout(0, 0)); ppanel.setFocusable(false); ppanel.setOpaque(false); ppanel.setCursor(null); ppanel.add(this.stackPanel, BorderLayout.SOUTH); glassPanel.add(ppanel, BorderLayout.EAST); this.stackPanel.add(Box.createGlue()); glassPanel.setVisible(false); this.setTitle("Scia Reto"); //NOI18N setIconImage(UiUtils.loadIcon("logo256x256.png")); //NOI18N this.stateless = args.length > 0; final MainFrame theInstance = this; this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(@Nonnull final WindowEvent e) { if (doClosing()) { dispose(); } } }); this.tabPane = new EditorTabPane(this); this.explorerTree = new ExplorerTree(this); final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(250); splitPane.setResizeWeight(0.0d); splitPane.setLeftComponent(this.explorerTree); this.mainPanel = new JPanel(new BorderLayout(0, 0)); this.mainPanel.add(this.tabPane, BorderLayout.CENTER); splitPane.setRightComponent(this.mainPanel); add(splitPane, BorderLayout.CENTER); this.menuOpenRecentProject.addMenuListener(new MenuListener() { @Override public void menuSelected(MenuEvent e) { final File[] lastOpenedProjects = FileHistoryManager.getInstance().getLastOpenedProjects(); if (lastOpenedProjects.length > 0) { for (final File folder : lastOpenedProjects) { final JMenuItem item = new JMenuItem(folder.getName()); item.setToolTipText(folder.getAbsolutePath()); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { openProject(folder, false); } }); menuOpenRecentProject.add(item); } } } @Override public void menuDeselected(MenuEvent e) { menuOpenRecentProject.removeAll(); } @Override public void menuCanceled(MenuEvent e) { } }); this.menuOpenRecentFile.addMenuListener(new MenuListener() { @Override public void menuSelected(MenuEvent e) { final File[] lastOpenedFiles = FileHistoryManager.getInstance().getLastOpenedFiles(); if (lastOpenedFiles.length > 0) { for (final File file : lastOpenedFiles) { final JMenuItem item = new JMenuItem(file.getName()); item.setToolTipText(file.getAbsolutePath()); item.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { openFileAsTab(file); } }); menuOpenRecentFile.add(item); } } } @Override public void menuDeselected(MenuEvent e) { menuOpenRecentFile.removeAll(); } @Override public void menuCanceled(MenuEvent e) { } }); if (!this.stateless) { restoreState(); } else { boolean openedProject = false; for (final String filePath : args) { final File file = new File(filePath); if (file.isDirectory()) { openedProject = true; openProject(file, true); } else if (file.isFile()) { openFileAsTab(file); } } if (!openedProject) { //TODO try to hide project panel! } } final LookAndFeel current = UIManager.getLookAndFeel(); final ButtonGroup lfGroup = new ButtonGroup(); final String currentLFClassName = current.getClass().getName(); for (final UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { final JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(info.getName()); lfGroup.add(menuItem); if (currentLFClassName.equals(info.getClassName())) { menuItem.setSelected(true); } menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(@Nonnull final ActionEvent e) { try { UIManager.setLookAndFeel(info.getClassName()); SwingUtilities.updateComponentTreeUI(theInstance); PreferencesManager.getInstance().getPreferences().put(Main.PROPERTY_LOOKANDFEEL, info.getClassName()); PreferencesManager.getInstance().flush(); } catch (Exception ex) { LOGGER.error("Can't change LF", ex); //NOI18N } } }); this.menuLookAndFeel.add(menuItem); } this.menuGoToFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | KeyEvent.SHIFT_MASK)); this.menuSaveAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); this.menuRedo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | KeyEvent.SHIFT_MASK)); this.menuUndo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); this.menuFindText.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); this.menuEditCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); this.menuEditPaste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); this.menuEditCut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); this.menuEditShowContextMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | KeyEvent.SHIFT_MASK)); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (tabPane.getTabCount() > 0) { tabPane.setSelectedIndex(0); processTabChanged(tabPane.getCurrentTitle()); } else { processTabChanged(null); } tabPane.setNotifyForTabChanged(true); } }); enableAllMenuItems(); this.explorerTree.focusToFirstElement(); } private void updateMenuItemsForProvider(@Nullable final TabProvider provider) { if (provider == null) { this.menuRedo.setEnabled(false); this.menuUndo.setEnabled(false); this.menuSave.setEnabled(false); this.menuSaveAs.setEnabled(false); this.menuEditCopy.setEnabled(false); this.menuEditPaste.setEnabled(false); this.menuEditCut.setEnabled(false); } else { if (provider.doesSupportCutCopyPaste()) { this.menuEditCopy.setEnabled(provider.isCopyAllowed()); this.menuEditPaste.setEnabled(provider.isPasteAllowed()); this.menuEditCut.setEnabled(provider.isCutAllowed()); } else { this.menuEditCopy.setEnabled(false); this.menuEditPaste.setEnabled(false); this.menuEditCut.setEnabled(false); } this.menuRedo.setEnabled(provider.isRedo()); this.menuUndo.setEnabled(provider.isUndo()); if (provider.isSaveable()) { this.menuSave.setEnabled(provider.getTabTitle().isChanged()); this.menuSaveAs.setEnabled(true); } else { this.menuSave.setEnabled(false); this.menuSaveAs.setEnabled(false); } } } public void processTabChanged(@Nullable final TabTitle title) { this.menuSaveAll.setEnabled(this.tabPane.hasEditableAndChangedDocument()); if (title != null && !this.tabPane.isEmpty() && title.getProvider().doesSupportPatternSearch()) { this.menuFindText.setEnabled(true); final FindTextPanel findTextPanel = this.currentFindTextPanel.get(); if (findTextPanel != null) { findTextPanel.updateUI(title); } } else { this.menuFindText.setEnabled(false); hideFindTextPane(); } enableAllMenuItems(); if (title != null) { title.visited(); } } @Override public void notifyUpdateRedoUndo() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { processTabChanged(tabPane.getCurrentTitle()); } }); } public JPanel getStackPanel() { return this.stackPanel; } @Override public boolean doPlatformMenuAction(@Nonnull final PlatformMenuEvent event, @Nullable @MayContainNull final Object... args) { boolean handled = false; switch (event) { case ABOUT: { this.menuAboutActionPerformed(new ActionEvent(this, 0, "about")); //NOI18N handled = true; } break; case QUIT: { handled = doClosing(); if (handled) { dispose(); } } break; case REOPEN_APPLICATION: { this.setVisible(true); handled = true; } break; case PREFERENCES: { editPreferences(); handled = true; } break; } return handled; } private boolean doClosing() { endFullScreenIfActive(); boolean hasUnsaved = false; for (final TabTitle t : tabPane) { hasUnsaved |= t.isChanged(); } if (hasUnsaved) { if (!DialogProviderManager.getInstance().getDialogProvider().msgConfirmOkCancel("Detected non-saved documents", "Detected unsaved documents! Close application?")) { return false; } } if (!this.stateless) { saveState(); } return true; } @Override public void notifyFileRenamed(@Nullable @MustNotContainNull final List<File> affectedFiles, @Nonnull final File oldFile, @Nonnull final File newFile) { this.tabPane.replaceFileLink(oldFile, newFile); if (affectedFiles != null) { for (final TabTitle t : this.tabPane) { final File tabFile = t.getAssociatedFile(); if (tabFile != null && affectedFiles.contains(tabFile)) { t.reload(true); } } } } @Override public boolean safeCloseEditorsForFile(@Nonnull final File file) { boolean changed = false; final List<TabTitle> list = new ArrayList<>(); for (final TabTitle t : this.tabPane) { if (t.belongFolderOrSame(file)) { list.add(t); changed |= t.isChanged(); } } if (changed && !DialogProviderManager.getInstance().getDialogProvider().msgConfirmOkCancel("Confirmation", "Some changed file will be affected! To close them?")) { return false; } closeTab(list.toArray(new TabTitle[list.size()])); return true; } private void restoreState() { try { final File[] activeProjects = FileHistoryManager.getInstance().getActiveProjects(); for (final File f : activeProjects) { if (f.isDirectory()) { openProject(f, true); } } final File[] activeFiles = FileHistoryManager.getInstance().getActiveFiles(); for (final File f : activeFiles) { if (f.isFile()) { openFileAsTab(f); } } } catch (IOException ex) { LOGGER.error("Can't restore state", ex); //NOI18N } } private void saveState() { try { final List<File> files = new ArrayList<>(); for (final NodeFileOrFolder p : this.explorerTree.getCurrentGroup()) { final File f = ((NodeProject) p).getFolder(); if (f.isDirectory()) { files.add(f); } } FileHistoryManager.getInstance().saveActiveProjects(files.toArray(new File[files.size()])); files.clear(); for (final TabTitle p : this.tabPane) { final File f = p.getAssociatedFile(); if (f != null && f.isFile()) { files.add(f); } } FileHistoryManager.getInstance().saveActiveFiles(files.toArray(new File[files.size()])); } catch (IOException ex) { LOGGER.error("Can't save state", ex); //NOI18N } } @Override public boolean openFileAsTab(@Nonnull final File file) { boolean result = false; if (file.isFile()) { if (this.tabPane.focusToFile(file)) { result = true; } else { final String ext = FilenameUtils.getExtension(file.getName()).toLowerCase(Locale.ENGLISH); if (ext.equals("mmd")) { //NOI18N try { final MMDEditor panel = new MMDEditor(this, file); this.tabPane.createTab(panel); result = true; } catch (IOException ex) { LOGGER.error("Can't load mind map", ex); //NOI18N } } else if (PictureViewer.SUPPORTED_FORMATS.contains(ext)) { try { final PictureViewer panel = new PictureViewer(this, file); this.tabPane.createTab(panel); result = true; } catch (IOException ex) { LOGGER.error("Can't load file as image", ex); //NOI18N } } else if (SourceTextEditor.SUPPORTED_EXTENSIONS.contains(ext)) { try { final SourceTextEditor panel = new SourceTextEditor(this, file); this.tabPane.createTab(panel); result = true; } catch (IOException ex) { LOGGER.error("Can't load file as sources", ex); //NOI18N } finally { processTabChange(); } } else { if (file.length() >= (2L * 1024L * 1024L) && !DialogProviderManager.getInstance().getDialogProvider().msgConfirmYesNo("Very big file", "It is a very big file! Are you sure to open it?")) { return true; } try { final TextEditor panel = new TextEditor(this, file); this.tabPane.createTab(panel); result = true; } catch (IOException ex) { LOGGER.error("Can't load file as text", ex); //NOI18N } finally { processTabChange(); } } } } if (result) { try { FileHistoryManager.getInstance().registerOpenedFile(file); } catch (IOException x) { LOGGER.error("Can't register last opened file", x); //NOI18N } finally { this.tabPane.focusToFile(file); } } return result; } @Override public void focusInTree(@Nonnull final TabTitle title) { final File file = title.getAssociatedFile(); if (file != null) { this.explorerTree.focusToFileItem(file); } } @Override public void focusInTree(@Nonnull final File file) { this.explorerTree.focusToFileItem(file); } @Override public void closeTab(@Nonnull final TabTitle... titles) { for (final TabTitle t : titles) { this.tabPane.removeTab(t); } processTabChange(); } private void processTabChange() { this.menuFindText.setEnabled(!this.tabPane.isEmpty() && this.tabPane.getCurrentTitle().getProvider().doesSupportPatternSearch()); if (this.tabPane.isEmpty() || !this.tabPane.getCurrentTitle().getProvider().doesSupportPatternSearch()) { hideFindTextPane(); } } @Override public void showFindTextPane(@Nullable final String text) { final TabTitle current = getFocusedTab(); if (current != null && this.tabPane.getCurrentTitle().getProvider().doesSupportPatternSearch()) { FindTextPanel panel = this.currentFindTextPanel.get(); if (panel == null) { panel = new FindTextPanel(this, text); panel.updateUI(current); this.mainPanel.add(panel, BorderLayout.SOUTH); } this.currentFindTextPanel.set(panel); this.mainPanel.revalidate(); this.mainPanel.repaint(); panel.requestFocus(); } } @Override public void hideFindTextPane() { final FindTextPanel panel = this.currentFindTextPanel.get(); if (panel != null) { this.currentFindTextPanel.set(null); this.mainPanel.remove(panel); this.mainPanel.revalidate(); this.mainPanel.repaint(); } } @Override @Nullable public NodeProject findProjectForFile(@Nonnull final File file) { return this.explorerTree.getCurrentGroup().findProjectForFile(file); } @Override public void notifyReloadConfig() { for (final TabTitle t : this.tabPane) { final AbstractEditor editor = t.getProvider().getEditor(); if (editor instanceof MMDEditor) { ((MMDEditor) editor).refreshConfig(); } } } @Override public void onCloseProject(@Nonnull final NodeProject project) { final File projectFolder = project.getFolder(); for (final TabTitle t : this.tabPane) { if (t.belongFolderOrSame(projectFolder)) { t.doSafeClose(); } } } @Override public boolean deleteTreeNode(@Nonnull final NodeFileOrFolder node) { final File file = node.makeFileForNode(); if (file != null && file.exists()) { final List<TabTitle> tabsToClose = this.tabPane.findListOfRelatedTabs(file); boolean hasUnsaved = false; for (final TabTitle t : tabsToClose) { hasUnsaved |= t.isChanged(); } if (hasUnsaved && !DialogProviderManager.getInstance().getDialogProvider().msgConfirmOkCancel("Confirmation", "Are you sure to delete changed unsaved file?")) { return false; } closeTab(tabsToClose.toArray(new TabTitle[tabsToClose.size()])); final NodeProject project = findProjectForFile(file); List<File> affectedFiles = project == null ? Collections.EMPTY_LIST : project.findAffectedFiles(file); final Iterator<File> iterator = affectedFiles.iterator(); final Path removingFile = file.toPath(); while (iterator.hasNext()) { if (iterator.next().toPath().startsWith(removingFile)) { iterator.remove(); } } if (!affectedFiles.isEmpty()) { affectedFiles = UiUtils.showSelectAffectedFiles(affectedFiles); if (affectedFiles == null) { return false; } } boolean ok = false; if (file.isDirectory()) { if (SystemUtils.deleteFile(file, DELETE_MOVING_FILE_TO_TRASH)) { ok = true; } else { DialogProviderManager.getInstance().getDialogProvider().msgError("Can't delete directory, see the log!"); } } else { ok = SystemUtils.deleteFile(file, DELETE_MOVING_FILE_TO_TRASH); if (!ok) { DialogProviderManager.getInstance().getDialogProvider().msgError("Can't delete file!"); } } if (ok) { explorerTree.deleteNode(node); } if (!affectedFiles.isEmpty() && project != null) { final List<File> changedFiles = project.deleteAllLinksToFile(affectedFiles, file); if (!changedFiles.isEmpty()) { for (final TabTitle t : tabPane) { final File associated = t.getAssociatedFile(); if (associated != null && changedFiles.contains(associated)) { t.reload(true); } } } } return ok; } return false; } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { mainMenu = new javax.swing.JMenuBar(); menuFile = new javax.swing.JMenu(); menuNewProject = new javax.swing.JMenuItem(); jSeparator2 = new javax.swing.JPopupMenu.Separator(); menuOpenProject = new javax.swing.JMenuItem(); menuOpenRecentProject = new javax.swing.JMenu(); menuOpenFile = new javax.swing.JMenuItem(); menuOpenRecentFile = new javax.swing.JMenu(); jSeparator3 = new javax.swing.JPopupMenu.Separator(); menuSave = new javax.swing.JMenuItem(); menuSaveAs = new javax.swing.JMenuItem(); menuSaveAll = new javax.swing.JMenuItem(); separatorExitSection = new javax.swing.JPopupMenu.Separator(); menuExit = new javax.swing.JMenuItem(); menuEdit = new javax.swing.JMenu(); menuEditShowContextMenu = new javax.swing.JMenuItem(); jSeparator7 = new javax.swing.JPopupMenu.Separator(); menuUndo = new javax.swing.JMenuItem(); menuRedo = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JPopupMenu.Separator(); menuEditCut = new javax.swing.JMenuItem(); menuEditCopy = new javax.swing.JMenuItem(); menuEditPaste = new javax.swing.JMenuItem(); jSeparator6 = new javax.swing.JPopupMenu.Separator(); menuFindText = new javax.swing.JMenuItem(); jSeparator5 = new javax.swing.JPopupMenu.Separator(); menuPreferences = new javax.swing.JMenuItem(); menuView = new javax.swing.JMenu(); menuFullScreen = new javax.swing.JMenuItem(); menuLookAndFeel = new javax.swing.JMenu(); menuNavigate = new javax.swing.JMenu(); menuGoToFile = new javax.swing.JMenuItem(); menuNavigateLinksGraph = new javax.swing.JMenuItem(); menuHelp = new javax.swing.JMenu(); menuAbout = new javax.swing.JMenuItem(); jSeparator4 = new javax.swing.JPopupMenu.Separator(); menuMakeDonation = new javax.swing.JMenuItem(); setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); setLocationByPlatform(true); menuFile.setMnemonic('f'); menuFile.setText("File"); menuFile.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { menuFileMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { menuFileMenuDeselected(evt); } public void menuCanceled(javax.swing.event.MenuEvent evt) { menuFileMenuCanceled(evt); } }); menuNewProject.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/box_closed.png"))); // NOI18N menuNewProject.setMnemonic('w'); menuNewProject.setText("New Project"); menuNewProject.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuNewProjectActionPerformed(evt); } }); menuFile.add(menuNewProject); menuFile.add(jSeparator2); menuOpenProject.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); menuOpenProject.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/open_folder.png"))); // NOI18N menuOpenProject.setMnemonic('e'); menuOpenProject.setText("Open Project"); menuOpenProject.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuOpenProjectActionPerformed(evt); } }); menuFile.add(menuOpenProject); menuOpenRecentProject.setMnemonic('j'); menuOpenRecentProject.setText("Open Recent Project"); menuFile.add(menuOpenRecentProject); menuOpenFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); menuOpenFile.setMnemonic('o'); menuOpenFile.setText("Open File"); menuOpenFile.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuOpenFileActionPerformed(evt); } }); menuFile.add(menuOpenFile); menuOpenRecentFile.setMnemonic('f'); menuOpenRecentFile.setText("Open Recent File"); menuFile.add(menuOpenRecentFile); menuFile.add(jSeparator3); menuSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/diskette.png"))); // NOI18N menuSave.setMnemonic('s'); menuSave.setText("Save"); menuSave.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuSaveActionPerformed(evt); } }); menuFile.add(menuSave); menuSaveAs.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/file_save_as.png"))); // NOI18N menuSaveAs.setMnemonic('v'); menuSaveAs.setText("Save As"); menuSaveAs.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuSaveAsActionPerformed(evt); } }); menuFile.add(menuSaveAs); menuSaveAll.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/disk_multiple.png"))); // NOI18N menuSaveAll.setMnemonic('a'); menuSaveAll.setText("Save All"); menuSaveAll.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuSaveAllActionPerformed(evt); } }); menuFile.add(menuSaveAll); menuFile.add(separatorExitSection); menuExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK)); menuExit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/door_in.png"))); // NOI18N menuExit.setMnemonic('x'); menuExit.setText("Exit"); menuExit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuExitActionPerformed(evt); } }); menuFile.add(menuExit); mainMenu.add(menuFile); menuEdit.setMnemonic('e'); menuEdit.setText("Edit"); menuEdit.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { menuEditMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { menuEditMenuDeselected(evt); } public void menuCanceled(javax.swing.event.MenuEvent evt) { menuEditMenuCanceled(evt); } }); menuEditShowContextMenu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/tree_list16.png"))); // NOI18N menuEditShowContextMenu.setMnemonic('t'); menuEditShowContextMenu.setText("Show Tree context menu"); menuEditShowContextMenu.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuEditShowContextMenuActionPerformed(evt); } }); menuEdit.add(menuEditShowContextMenu); menuEdit.add(jSeparator7); menuUndo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/undo.png"))); // NOI18N menuUndo.setMnemonic('u'); menuUndo.setText("Undo"); menuUndo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuUndoActionPerformed(evt); } }); menuEdit.add(menuUndo); menuRedo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/redo.png"))); // NOI18N menuRedo.setMnemonic('r'); menuRedo.setText("Redo"); menuRedo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuRedoActionPerformed(evt); } }); menuEdit.add(menuRedo); menuEdit.add(jSeparator1); menuEditCut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/cut16.png"))); // NOI18N menuEditCut.setMnemonic('t'); menuEditCut.setText("Cut"); menuEditCut.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuEditCutActionPerformed(evt); } }); menuEdit.add(menuEditCut); menuEditCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/page_copy16.png"))); // NOI18N menuEditCopy.setMnemonic('y'); menuEditCopy.setText("Copy"); // NOI18N menuEditCopy.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuEditCopyActionPerformed(evt); } }); menuEdit.add(menuEditCopy); menuEditPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/paste_plain16.png"))); // NOI18N menuEditPaste.setMnemonic('p'); menuEditPaste.setText("Paste"); // NOI18N menuEditPaste.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuEditPasteActionPerformed(evt); } }); menuEdit.add(menuEditPaste); menuEdit.add(jSeparator6); menuFindText.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/find16.png"))); // NOI18N menuFindText.setMnemonic('n'); menuFindText.setText("Find text"); menuFindText.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuFindTextActionPerformed(evt); } }); menuEdit.add(menuFindText); menuEdit.add(jSeparator5); menuPreferences.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/setting_tools.png"))); // NOI18N menuPreferences.setMnemonic('e'); menuPreferences.setText("Preferences"); menuPreferences.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuPreferencesActionPerformed(evt); } }); menuEdit.add(menuPreferences); mainMenu.add(menuEdit); menuView.setMnemonic('v'); menuView.setText("View"); menuFullScreen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F11, 0)); menuFullScreen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/monitor.png"))); // NOI18N menuFullScreen.setText("Full screen"); menuFullScreen.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuFullScreenActionPerformed(evt); } }); menuView.add(menuFullScreen); menuLookAndFeel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/application.png"))); // NOI18N menuLookAndFeel.setText("Look and Feel"); menuView.add(menuLookAndFeel); mainMenu.add(menuView); menuNavigate.setMnemonic('n'); menuNavigate.setText("Navigate"); menuNavigate.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { menuNavigateMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { } public void menuCanceled(javax.swing.event.MenuEvent evt) { } }); menuGoToFile.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/rocket.png"))); // NOI18N menuGoToFile.setMnemonic('f'); menuGoToFile.setText("Go to File"); menuGoToFile.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuGoToFileActionPerformed(evt); } }); menuNavigate.add(menuGoToFile); menuNavigateLinksGraph.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/graph16.png"))); // NOI18N menuNavigateLinksGraph.setText("Build File links graph"); menuNavigateLinksGraph.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuNavigateLinksGraphActionPerformed(evt); } }); menuNavigate.add(menuNavigateLinksGraph); mainMenu.add(menuNavigate); menuHelp.setMnemonic('h'); menuHelp.setText("Help"); menuAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/menu_icons/information.png"))); // NOI18N menuAbout.setMnemonic('a'); menuAbout.setText("About"); menuAbout.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuAboutActionPerformed(evt); } }); menuHelp.add(menuAbout); menuHelp.add(jSeparator4); menuMakeDonation.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/coins_in_hand16.png"))); // NOI18N menuMakeDonation.setMnemonic('m'); menuMakeDonation.setText("Make donation"); menuMakeDonation.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuMakeDonationActionPerformed(evt); } }); menuHelp.add(menuMakeDonation); mainMenu.add(menuHelp); setJMenuBar(mainMenu); pack(); }// </editor-fold>//GEN-END:initComponents private void menuAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuAboutActionPerformed JOptionPane.showMessageDialog(Main.getApplicationFrame(), new AboutPanel(), "About", JOptionPane.PLAIN_MESSAGE); }//GEN-LAST:event_menuAboutActionPerformed private void menuOpenProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuOpenProjectActionPerformed final JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileView(new FileView() { private Icon KNOWLEDGE_FOLDER_ICO = null; @Override public Icon getIcon(final File f) { if (f.isDirectory()) { final File knowledge = new File(f, Context.KNOWLEDGE_FOLDER); if (knowledge.isDirectory()) { if (KNOWLEDGE_FOLDER_ICO == null) { final Icon icon = UIManager.getIcon("FileView.directoryIcon"); //NOI18N if (icon != null) { KNOWLEDGE_FOLDER_ICO = new ImageIcon(UiUtils.makeBadgedRightBottom(UiUtils.iconToImage(fileChooser, icon), Icons.MMDBADGE.getIcon().getImage())); } } return KNOWLEDGE_FOLDER_ICO; } else { return super.getIcon(f); } } else if (f.isFile() && f.getName().toLowerCase(Locale.ENGLISH).endsWith(".mmd")) { //NOI18N return Icons.DOCUMENT.getIcon(); } else { return super.getIcon(f); } } }); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fileChooser.setMultiSelectionEnabled(false); fileChooser.setDialogTitle("Open project folder"); if (fileChooser.showOpenDialog(Main.getApplicationFrame()) == JFileChooser.APPROVE_OPTION) { openProject(fileChooser.getSelectedFile(), false); } }//GEN-LAST:event_menuOpenProjectActionPerformed @Override public boolean openProject(@Nonnull final File folder, final boolean enforceSeparatedProject) { boolean result = false; if (folder.isDirectory()) { final NodeProject alreadyOpened = findProjectForFile(folder); if (alreadyOpened == null || enforceSeparatedProject) { final boolean firstProject = this.explorerTree.getCurrentGroup().getChildCount() == 0; final NodeProject node = this.explorerTree.getCurrentGroup().addProjectFolder(folder); if (firstProject) { this.explorerTree.unfoldProject(node); } try { FileHistoryManager.getInstance().registerOpenedProject(folder); } catch (IOException ex) { LOGGER.error("Can't register last opened project", ex); //NOI18N } } else { this.focusInTree(folder); } result = true; } else { LOGGER.error("Can't find folder : " + folder); //NOI18N DialogProviderManager.getInstance().getDialogProvider().msgError("Can't find project folder!"); } return result; } @Override public void editPreferences() { final PreferencesPanel configPanel = new PreferencesPanel(this); configPanel.load(PreferencesManager.getInstance().getPreferences()); if (DialogProviderManager.getInstance().getDialogProvider().msgOkCancel("Preferences", configPanel)) { configPanel.save(); for (final TabTitle t : this.tabPane) { t.getProvider().updateConfiguration(); } } } private void menuSaveAllActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSaveAllActionPerformed for (final TabTitle t : this.tabPane) { try { t.save(); } catch (IOException ex) { LOGGER.error("Can't save file", ex); //NOI18N DialogProviderManager.getInstance().getDialogProvider().msgError("Can't save document, may be it is read-only! See log!"); } } }//GEN-LAST:event_menuSaveAllActionPerformed private void menuPreferencesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuPreferencesActionPerformed editPreferences(); }//GEN-LAST:event_menuPreferencesActionPerformed private void menuOpenFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuOpenFileActionPerformed final File file = DialogProviderManager.getInstance().getDialogProvider().msgOpenFileDialog("open-file", "Open file", null, true, MMDEditor.MMD_FILE_FILTER, "Open"); if (file != null) { if (openFileAsTab(file)) { try { FileHistoryManager.getInstance().registerOpenedProject(file); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { centerRootTopicIfFocusedMMD(); } }); } catch (IOException ex) { LOGGER.error("Can't register last opened file", ex); //NOI18N } } } }//GEN-LAST:event_menuOpenFileActionPerformed @Override public boolean centerRootTopicIfFocusedMMD() { boolean result = false; final TabTitle title = this.getFocusedTab(); if (title != null && title.getProvider().getEditor().getEditorContentType() == EditorContentType.MINDMAP) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { ((MMDEditor) title.getProvider().getEditor()).rootToCentre(); } }); result = true; } return result; } private void menuSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSaveActionPerformed final int index = this.tabPane.getSelectedIndex(); if (index >= 0) { try { ((TabTitle) this.tabPane.getTabComponentAt(index)).save(); } catch (IOException ex) { LOGGER.error("Can't save file", ex); //NOI18N DialogProviderManager.getInstance().getDialogProvider().msgError("Can't save document, may be it is read-only! See log!"); } } }//GEN-LAST:event_menuSaveActionPerformed private void menuSaveAsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuSaveAsActionPerformed final int index = this.tabPane.getSelectedIndex(); if (index >= 0) { try { ((TabTitle) this.tabPane.getTabComponentAt(index)).saveAs(); } catch (IOException ex) { LOGGER.error("Can't save file", ex); //NOI18N DialogProviderManager.getInstance().getDialogProvider().msgError("Can't save document, may be it is read-only! See log!"); } } }//GEN-LAST:event_menuSaveAsActionPerformed private void menuExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuExitActionPerformed if (doClosing()) { dispose(); } }//GEN-LAST:event_menuExitActionPerformed private boolean createKnowledgeFolder(@Nonnull final File folder) { boolean result = false; if (PreferencesManager.getInstance().getPreferences().getBoolean(PreferencesPanel.PREFERENCE_KEY_KNOWLEDGEFOLDER_ALLOWED, true)) { final File knowledgeFolder = new File(folder, Context.KNOWLEDGE_FOLDER); if (knowledgeFolder.mkdirs()) { result = true; } else { LOGGER.warn("Can't create folder : "+Context.KNOWLEDGE_FOLDER); //NOI18N } } return result; } private boolean prepareAndOpenProjectFolder(@Nonnull final File folder) { boolean result = false; createKnowledgeFolder(folder); if (openProject(folder, true)) { result = true; this.focusInTree(folder); } return result; } private void menuNewProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuNewProjectActionPerformed final JFileChooser folderChooser = new JFileChooser(); folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); folderChooser.setDialogTitle("Create project folder"); folderChooser.setDialogType(JFileChooser.SAVE_DIALOG); folderChooser.setApproveButtonText("Create"); folderChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); if (folderChooser.showSaveDialog(Main.getApplicationFrame()) == JFileChooser.APPROVE_OPTION) { final File file = folderChooser.getSelectedFile(); if (file.isDirectory()) { if (file.list().length > 0) { DialogProviderManager.getInstance().getDialogProvider().msgError("File '" + file.getName() + "' already exists and non-empty!"); } else { prepareAndOpenProjectFolder(file); } } else if (file.mkdirs()) { prepareAndOpenProjectFolder(file); } else { LOGGER.error("Can't create folder : " + file); //NOI18N DialogProviderManager.getInstance().getDialogProvider().msgError("Can't create folder: " + file); } } }//GEN-LAST:event_menuNewProjectActionPerformed private void menuFullScreenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuFullScreenActionPerformed final AbstractEditor selectedEditor = this.tabPane.getCurrentEditor(); if (selectedEditor != null) { final GraphicsConfiguration gconfig = this.getGraphicsConfiguration(); if (gconfig != null) { final GraphicsDevice device = gconfig.getDevice(); if (device.isFullScreenSupported()) { if (device.getFullScreenWindow() == null) { final JLabel label = new JLabel("Opened in full screen"); final int tabIndex = this.tabPane.getSelectedIndex(); this.tabPane.setComponentAt(tabIndex, label); final JWindow window = new JWindow(Main.getApplicationFrame()); window.setAlwaysOnTop(true); window.setAutoRequestFocus(true); window.setContentPane(selectedEditor.getContainerToShow()); endFullScreenIfActive(); final KeyEventDispatcher fullScreenEscCatcher = new KeyEventDispatcher() { @Override public boolean dispatchKeyEvent(@Nonnull final KeyEvent e) { if (e.getID() == KeyEvent.KEY_PRESSED && (e.getKeyCode() == KeyEvent.VK_ESCAPE || e.getKeyCode() == KeyEvent.VK_F11)) { endFullScreenIfActive(); return true; } return false; } }; if (this.taskToEndFullScreen.compareAndSet(null, new Runnable() { @Override public void run() { try { window.dispose(); } finally { tabPane.setComponentAt(tabIndex, selectedEditor.getContainerToShow()); device.setFullScreenWindow(null); KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(fullScreenEscCatcher); } } })) { try { KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(fullScreenEscCatcher); device.setFullScreenWindow(window); } catch (Exception ex) { LOGGER.error("Can't turn on full screen", ex); //NOI18N endFullScreenIfActive(); KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(fullScreenEscCatcher); } } else { LOGGER.error("Unexpected state, processor is not null!"); //NOI18N } } else { LOGGER.warn("Attempt to full screen device which already in full screen!"); //NOI18N } } else { LOGGER.warn("Device doesn's support full screen"); //NOI18N DialogProviderManager.getInstance().getDialogProvider().msgWarn("The Device doesn't support full-screen mode!"); } } else { LOGGER.warn("Can't find graphics config for the frame"); //NOI18N } } }//GEN-LAST:event_menuFullScreenActionPerformed private void menuMakeDonationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuMakeDonationActionPerformed new DonateButton().doClick(); }//GEN-LAST:event_menuMakeDonationActionPerformed private void menuGoToFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuGoToFileActionPerformed final GoToFilePanel panel = new GoToFilePanel(this.explorerTree); if (DialogProviderManager.getInstance().getDialogProvider().msgOkCancel("Go To File", panel)) { final NodeFileOrFolder selected = panel.getSelected(); if (selected != null) { final File file = selected.makeFileForNode(); if (file != null) { this.focusInTree(file); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { explorerTree.requestFocus(); } }); } } } }//GEN-LAST:event_menuGoToFileActionPerformed private void menuUndoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuUndoActionPerformed final TabTitle title = this.getFocusedTab(); if (title != null) { this.menuUndo.setEnabled(title.getProvider().undo()); this.menuRedo.setEnabled(title.getProvider().isRedo()); } }//GEN-LAST:event_menuUndoActionPerformed private void menuRedoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuRedoActionPerformed final TabTitle title = this.getFocusedTab(); if (title != null) { this.menuRedo.setEnabled(title.getProvider().redo()); this.menuUndo.setEnabled(title.getProvider().isUndo()); } }//GEN-LAST:event_menuRedoActionPerformed private void menuFindTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuFindTextActionPerformed showFindTextPane(""); //NOI18N }//GEN-LAST:event_menuFindTextActionPerformed private void menuEditMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_menuEditMenuSelected final TabTitle title = this.getFocusedTab(); updateMenuItemsForProvider(title == null ? null : title.getProvider()); this.menuEditShowContextMenu.setEnabled(this.explorerTree.hasSelectedItem()); }//GEN-LAST:event_menuEditMenuSelected private void menuEditMenuCanceled(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_menuEditMenuCanceled enableAllMenuItems(); }//GEN-LAST:event_menuEditMenuCanceled private void menuEditMenuDeselected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_menuEditMenuDeselected enableAllMenuItems(); }//GEN-LAST:event_menuEditMenuDeselected private void menuFileMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_menuFileMenuSelected final TabTitle title = this.getFocusedTab(); updateMenuItemsForProvider(title == null ? null : title.getProvider()); }//GEN-LAST:event_menuFileMenuSelected private void menuFileMenuCanceled(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_menuFileMenuCanceled enableAllMenuItems(); }//GEN-LAST:event_menuFileMenuCanceled private void menuFileMenuDeselected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_menuFileMenuDeselected enableAllMenuItems(); }//GEN-LAST:event_menuFileMenuDeselected private void menuEditCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuEditCopyActionPerformed final TabTitle title = this.getFocusedTab(); if (title != null && title.getProvider().doesSupportCutCopyPaste()) { title.getProvider().doCopy(); } updateMenuItemsForProvider(title == null ? null : title.getProvider()); }//GEN-LAST:event_menuEditCopyActionPerformed private void menuEditPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuEditPasteActionPerformed final TabTitle title = this.getFocusedTab(); if (title != null && title.getProvider().doesSupportCutCopyPaste()) { title.getProvider().doPaste(); } updateMenuItemsForProvider(title == null ? null : title.getProvider()); }//GEN-LAST:event_menuEditPasteActionPerformed private void menuEditCutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuEditCutActionPerformed final TabTitle title = this.getFocusedTab(); if (title != null && title.getProvider().doesSupportCutCopyPaste()) { title.getProvider().doCut(); } updateMenuItemsForProvider(title == null ? null : title.getProvider()); }//GEN-LAST:event_menuEditCutActionPerformed @Override public boolean showGraphMindMapFileLinksDialog(@Nullable final File projectFolder, @Nullable final File initialMindMapFile, final boolean openIfSelected) { Utils.assertSwingDispatchThread(); boolean result = false; if (projectFolder != null || initialMindMapFile != null) { File projectFolderToUse = projectFolder; if (projectFolderToUse == null) { final NodeProject foundProject = findProjectForFile(initialMindMapFile); if (foundProject != null) { projectFolderToUse = foundProject.getFolder(); } } final FileLinkGraphPanel graph = new FileLinkGraphPanel(projectFolderToUse, initialMindMapFile); JOptionPane.showMessageDialog(this, graph, "Graph of Mind Map file links", JOptionPane.PLAIN_MESSAGE); final FileLinkGraphPanel.FileVertex selected = graph.getSelectedFile(); final File fileToOpen = selected == null ? null : selected.getFile(); if (openIfSelected && fileToOpen != null) { result = true; boolean cantFind = true; if (fileToOpen.exists()) { if (fileToOpen.isFile()) { if (openFileAsTab(fileToOpen)) { cantFind = false; } } else if (fileToOpen.isDirectory()) { focusInTree(fileToOpen); cantFind = false; } } if (cantFind) { DialogProviderManager.getInstance().getDialogProvider().msgWarn("Can't open file \'" + fileToOpen.getAbsolutePath() + "\'!"); result = false; } } } return result; } private void menuNavigateLinksGraphActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuNavigateLinksGraphActionPerformed final File file = this.getFocusedTab().getAssociatedFile(); final NodeProject project = findProjectForFile(file); showGraphMindMapFileLinksDialog(project == null ? null : project.getFolder(), file, true); }//GEN-LAST:event_menuNavigateLinksGraphActionPerformed private void menuNavigateMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_menuNavigateMenuSelected final TabTitle title = getFocusedTab(); this.menuNavigateLinksGraph.setEnabled(title != null && title.getProvider().getEditor().getEditorContentType() == EditorContentType.MINDMAP); }//GEN-LAST:event_menuNavigateMenuSelected private void menuEditShowContextMenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuEditShowContextMenuActionPerformed this.explorerTree.showPopUpForSelectedItem(); }//GEN-LAST:event_menuEditShowContextMenuActionPerformed private void enableMenu(final JMenu menu) { menu.setEnabled(true); for (final Component c : menu.getMenuComponents()) { if (c instanceof JMenu) { enableMenu((JMenu) c); } else if (c instanceof JMenuItem) { ((JMenuItem) c).setEnabled(true); } } } private void enableAllMenuItems() { for (int i = 0; i < this.mainMenu.getMenuCount(); i++) { enableMenu(this.mainMenu.getMenu(i)); } } public void endFullScreenIfActive() { final Runnable runnable = this.taskToEndFullScreen.getAndSet(null); if (runnable != null) { Utils.safeSwingCall(runnable); } } @Override public boolean hasUnsavedDocument() { return this.tabPane.hasEditableAndChangedDocument(); } @Override @Nullable public TabTitle getFocusedTab() { return this.tabPane.getCurrentTitle(); } @Override @Nonnull public NodeProjectGroup getCurrentGroup() { return this.explorerTree.getCurrentGroup(); } @Nullable @Override public File createMindMapFile(@Nullable final File folder) { final JFileChooser chooser = new JFileChooser(folder); chooser.setDialogTitle("Create new Mind Map"); chooser.setFileFilter(MMDEditor.MMD_FILE_FILTER); chooser.setMultiSelectionEnabled(false); chooser.setApproveButtonText("Create"); File result = null; if (chooser.showSaveDialog(Main.getApplicationFrame()) == JFileChooser.APPROVE_OPTION) { File file = chooser.getSelectedFile(); if (!file.getName().endsWith(".mmd")) { //NOI18N file = new File(file.getAbsolutePath() + ".mmd"); //NOI18N } if (file.exists()) { DialogProviderManager.getInstance().getDialogProvider().msgError("File '" + file + "' already exists!"); } else { try { final MindMap mindMap = new MindMap(null, true); final String text = mindMap.write(new StringWriter()).toString(); SystemUtils.saveUTFText(file, text); result = file; } catch (IOException ex) { DialogProviderManager.getInstance().getDialogProvider().msgError("Can't save mind map into file '" + file.getName() + "'"); } } } return result; } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPopupMenu.Separator jSeparator1; private javax.swing.JPopupMenu.Separator jSeparator2; private javax.swing.JPopupMenu.Separator jSeparator3; private javax.swing.JPopupMenu.Separator jSeparator4; private javax.swing.JPopupMenu.Separator jSeparator5; private javax.swing.JPopupMenu.Separator jSeparator6; private javax.swing.JPopupMenu.Separator jSeparator7; private javax.swing.JMenuBar mainMenu; private javax.swing.JMenuItem menuAbout; private javax.swing.JMenu menuEdit; private javax.swing.JMenuItem menuEditCopy; private javax.swing.JMenuItem menuEditCut; private javax.swing.JMenuItem menuEditPaste; private javax.swing.JMenuItem menuEditShowContextMenu; private javax.swing.JMenuItem menuExit; private javax.swing.JMenu menuFile; private javax.swing.JMenuItem menuFindText; private javax.swing.JMenuItem menuFullScreen; private javax.swing.JMenuItem menuGoToFile; private javax.swing.JMenu menuHelp; private javax.swing.JMenu menuLookAndFeel; private javax.swing.JMenuItem menuMakeDonation; private javax.swing.JMenu menuNavigate; private javax.swing.JMenuItem menuNavigateLinksGraph; private javax.swing.JMenuItem menuNewProject; private javax.swing.JMenuItem menuOpenFile; private javax.swing.JMenuItem menuOpenProject; private javax.swing.JMenu menuOpenRecentFile; private javax.swing.JMenu menuOpenRecentProject; private javax.swing.JMenuItem menuPreferences; private javax.swing.JMenuItem menuRedo; private javax.swing.JMenuItem menuSave; private javax.swing.JMenuItem menuSaveAll; private javax.swing.JMenuItem menuSaveAs; private javax.swing.JMenuItem menuUndo; private javax.swing.JMenu menuView; private javax.swing.JPopupMenu.Separator separatorExitSection; // End of variables declaration//GEN-END:variables }