OmegaT のメニューバーにフォルダーツリー参照用のメニューを追加します。
change package name
| @@ -1,226 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu; | |
| 18 | - | |
| 19 | -import java.awt.Component; | |
| 20 | -import java.awt.event.ActionEvent; | |
| 21 | -import java.awt.event.ActionListener; | |
| 22 | -import java.awt.event.KeyEvent; | |
| 23 | -import java.awt.event.MouseEvent; | |
| 24 | -import java.awt.event.MouseListener; | |
| 25 | -import java.io.File; | |
| 26 | -import java.io.FileFilter; | |
| 27 | -import java.util.Comparator; | |
| 28 | -import javax.swing.Icon; | |
| 29 | -import javax.swing.JMenu; | |
| 30 | -import javax.swing.JMenuItem; | |
| 31 | -import javax.swing.MenuElement; | |
| 32 | -import javax.swing.MenuSelectionManager; | |
| 33 | -import javax.swing.event.MenuEvent; | |
| 34 | -import javax.swing.event.MenuKeyEvent; | |
| 35 | -import javax.swing.event.MenuKeyListener; | |
| 36 | -import javax.swing.event.MenuListener; | |
| 37 | -import javax.swing.filechooser.FileSystemView; | |
| 38 | - | |
| 39 | -/** | |
| 40 | - * | |
| 41 | - * @author Yu-Tang | |
| 42 | - */ | |
| 43 | -public class MenuHelper { | |
| 44 | - | |
| 45 | - static { | |
| 46 | - fs = FileSystemView.getFileSystemView(); | |
| 47 | - ff = new FileFilter() { | |
| 48 | - | |
| 49 | - @Override | |
| 50 | - public boolean accept(File file) { | |
| 51 | - // except dot started named files (i.e. ".svn") and hidden files | |
| 52 | - return !file.getName().startsWith(".") && !file.isHidden(); | |
| 53 | - } | |
| 54 | - | |
| 55 | - }; | |
| 56 | - | |
| 57 | - al = new ActionListener() { | |
| 58 | - | |
| 59 | - @Override | |
| 60 | - public void actionPerformed(ActionEvent e) { $(e).open(); } | |
| 61 | - | |
| 62 | - }; | |
| 63 | - | |
| 64 | - mkl = new MenuKeyListener() { | |
| 65 | - | |
| 66 | - @Override | |
| 67 | - public void menuKeyTyped(MenuKeyEvent e) { /* do nothing */ } | |
| 68 | - | |
| 69 | - @Override | |
| 70 | - public void menuKeyPressed(MenuKeyEvent e) { | |
| 71 | - if (e.getKeyCode() == KeyEvent.VK_ENTER) { | |
| 72 | - MenuSelectionManager manager = e.getMenuSelectionManager(); | |
| 73 | - MenuElement[] selectedPath = manager.getSelectedPath(); | |
| 74 | - MenuElement selection = selectedPath[selectedPath.length-1]; | |
| 75 | - if (selection instanceof JMenu) { | |
| 76 | - JMenu menu = (JMenu) selection; | |
| 77 | - if (menu.isEnabled()) { | |
| 78 | - manager.clearSelectedPath(); | |
| 79 | - $(menu).open(); | |
| 80 | - } | |
| 81 | - } | |
| 82 | - } | |
| 83 | - } | |
| 84 | - | |
| 85 | - @Override | |
| 86 | - public void menuKeyReleased(MenuKeyEvent e) { /* do nothing */ } | |
| 87 | - | |
| 88 | - }; | |
| 89 | - | |
| 90 | - mol = new MouseListener() { | |
| 91 | - | |
| 92 | - @Override | |
| 93 | - public void mouseClicked(MouseEvent e) { $(e).open(); } | |
| 94 | - | |
| 95 | - @Override | |
| 96 | - public void mousePressed(MouseEvent e) { /* do nothing */ } | |
| 97 | - | |
| 98 | - @Override | |
| 99 | - public void mouseReleased(MouseEvent e) { /* do nothing */ } | |
| 100 | - | |
| 101 | - @Override | |
| 102 | - public void mouseEntered(MouseEvent e) { /* do nothing */ } | |
| 103 | - | |
| 104 | - @Override | |
| 105 | - public void mouseExited(MouseEvent e) { /* do nothing */ } | |
| 106 | - | |
| 107 | - }; | |
| 108 | - | |
| 109 | - mel = new MenuListener() { | |
| 110 | - | |
| 111 | - @Override | |
| 112 | - public void menuSelected(MenuEvent e) { | |
| 113 | - // Lazy create submenus | |
| 114 | - $(e).createChildren(); | |
| 115 | - } | |
| 116 | - | |
| 117 | - @Override | |
| 118 | - public void menuDeselected(MenuEvent e) { /* do nothing */ } | |
| 119 | - | |
| 120 | - @Override | |
| 121 | - public void menuCanceled(MenuEvent e) { /* do nothing */ } | |
| 122 | - | |
| 123 | - }; | |
| 124 | - | |
| 125 | - /* for Folders root menu only */ | |
| 126 | - melRoot = new MenuListener() { | |
| 127 | - | |
| 128 | - @Override | |
| 129 | - public void menuSelected(MenuEvent e) { /* do nothing */ } | |
| 130 | - | |
| 131 | - @Override | |
| 132 | - public void menuDeselected(MenuEvent e) { | |
| 133 | - // remove children's all menuitems | |
| 134 | - JMenu menu = (JMenu) e.getSource(); | |
| 135 | - for (Component c: menu.getMenuComponents()) { | |
| 136 | - if (c instanceof JMenu) { | |
| 137 | - JMenu m = (JMenu) c; | |
| 138 | - if (m.isEnabled()) | |
| 139 | - m.removeAll(); | |
| 140 | - } | |
| 141 | - } | |
| 142 | - } | |
| 143 | - | |
| 144 | - @Override | |
| 145 | - public void menuCanceled(MenuEvent e) { /* do nothing */ } | |
| 146 | - | |
| 147 | - }; | |
| 148 | - | |
| 149 | - comp = new Comparator<File>() { | |
| 150 | - | |
| 151 | - @Override | |
| 152 | - public int compare(File f1, File f2) { | |
| 153 | - if (f1.isFile() == f2.isFile()) { | |
| 154 | - return f1.getName().compareToIgnoreCase(f2.getName()); | |
| 155 | - } else { | |
| 156 | - return f1.isFile() ? 1 : -1; | |
| 157 | - } | |
| 158 | - } | |
| 159 | - | |
| 160 | - }; | |
| 161 | - } | |
| 162 | - | |
| 163 | - private MenuHelper() {} // no instanciation, static only. | |
| 164 | - | |
| 165 | - public static Icon getIcon(File file) { | |
| 166 | - return fs.getSystemIcon(file); | |
| 167 | - } | |
| 168 | - | |
| 169 | - public static File[] getFilteredListFiles(File folder) { | |
| 170 | - return folder.listFiles(ff); | |
| 171 | - } | |
| 172 | - | |
| 173 | - public static ActionListener getActionListener() { | |
| 174 | - return al; | |
| 175 | - } | |
| 176 | - | |
| 177 | - public static MenuKeyListener getMenuKeyListener() { | |
| 178 | - return mkl; | |
| 179 | - } | |
| 180 | - | |
| 181 | - public static MouseListener getMouseListener() { | |
| 182 | - return mol; | |
| 183 | - } | |
| 184 | - | |
| 185 | - public static MenuListener getMenuListener() { | |
| 186 | - return mel; | |
| 187 | - } | |
| 188 | - | |
| 189 | - public static MenuListener getRootMenuListener() { | |
| 190 | - return melRoot; | |
| 191 | - } | |
| 192 | - | |
| 193 | - public static Comparator<File> getComparator() { | |
| 194 | - return comp; | |
| 195 | - } | |
| 196 | - | |
| 197 | - private static ShellLinkMenuItem $(JMenuItem mi) { | |
| 198 | - return new ShellLinkMenuItem(mi); | |
| 199 | - } | |
| 200 | - | |
| 201 | - private static ShellLinkMenu $(JMenu m) { | |
| 202 | - return new ShellLinkMenu(m); | |
| 203 | - } | |
| 204 | - | |
| 205 | - private static ShellLinkMenuItem $(ActionEvent e) { | |
| 206 | - return new ShellLinkMenuItem((JMenuItem) e.getSource()); | |
| 207 | - } | |
| 208 | - | |
| 209 | - private static ShellLinkMenu $(MouseEvent e) { | |
| 210 | - return new ShellLinkMenu((JMenu) e.getSource()); | |
| 211 | - } | |
| 212 | - | |
| 213 | - private static ShellLinkMenu $(MenuEvent e) { | |
| 214 | - return new ShellLinkMenu((JMenu) e.getSource()); | |
| 215 | - } | |
| 216 | - | |
| 217 | - private static final FileSystemView fs; | |
| 218 | - private static final FileFilter ff; | |
| 219 | - private static final ActionListener al; | |
| 220 | - private static final MenuKeyListener mkl; | |
| 221 | - private static final MouseListener mol; | |
| 222 | - private static final MenuListener mel; | |
| 223 | - private static final MenuListener melRoot; | |
| 224 | - private static final Comparator<File> comp; | |
| 225 | - | |
| 226 | -} |
| @@ -1,94 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu; | |
| 18 | - | |
| 19 | -import java.awt.Desktop; | |
| 20 | -import java.io.File; | |
| 21 | -import java.io.IOException; | |
| 22 | -import javax.swing.JMenuItem; | |
| 23 | -import org.omegat.core.Core; | |
| 24 | -import static org.omegat.plugin.foldermenu.MenuHelper.getActionListener; | |
| 25 | -import static org.omegat.plugin.foldermenu.MenuHelper.getIcon; | |
| 26 | -import org.omegat.plugin.foldermenu.filepreview.FilePreview; | |
| 27 | -import org.omegat.util.Log; | |
| 28 | -import static org.omegat.util.Platform.OsType.MAC32; | |
| 29 | -import static org.omegat.util.Platform.OsType.MAC64; | |
| 30 | -import static org.omegat.util.Platform.OsType.WIN32; | |
| 31 | -import static org.omegat.util.Platform.OsType.WIN64; | |
| 32 | -import static org.omegat.util.Platform.getOsType; | |
| 33 | -import org.omegat.util.StaticUtils; | |
| 34 | - | |
| 35 | -/** | |
| 36 | - * | |
| 37 | - * @author Yu-Tang | |
| 38 | - */ | |
| 39 | -public class ShellLinkMenuItem { | |
| 40 | - | |
| 41 | - protected JMenuItem menuItem; | |
| 42 | - | |
| 43 | - public ShellLinkMenuItem() { | |
| 44 | - menuItem = new JMenuItem(); | |
| 45 | - } | |
| 46 | - | |
| 47 | - public ShellLinkMenuItem(JMenuItem mi) { | |
| 48 | - menuItem = mi; | |
| 49 | - } | |
| 50 | - | |
| 51 | - public ShellLinkMenuItem(File file) throws IOException { | |
| 52 | - JMenuItem m = new JMenuItem(file.getName(), getIcon(file)); | |
| 53 | - m.setActionCommand(file.getCanonicalPath()); | |
| 54 | - m.addActionListener(getActionListener()); | |
| 55 | - menuItem = m; | |
| 56 | - } | |
| 57 | - | |
| 58 | - public boolean isEnabled() { | |
| 59 | - return menuItem.isEnabled(); | |
| 60 | - } | |
| 61 | - | |
| 62 | - public JMenuItem getMenuItem() { | |
| 63 | - return menuItem; | |
| 64 | - } | |
| 65 | - | |
| 66 | - public void open() { | |
| 67 | - if (! menuItem.isEnabled()) | |
| 68 | - return; | |
| 69 | - | |
| 70 | - String path = menuItem.getActionCommand(); | |
| 71 | - try { | |
| 72 | - switch (getOsType()) { | |
| 73 | - case WIN64: | |
| 74 | - case WIN32: | |
| 75 | - File file = new File(path); | |
| 76 | - if (! FilePreview.open(file)) { | |
| 77 | - Desktop.getDesktop().open(file); | |
| 78 | - } | |
| 79 | - break; | |
| 80 | - case MAC64: | |
| 81 | - case MAC32: | |
| 82 | - new ProcessBuilder("open", path).start(); | |
| 83 | - break; | |
| 84 | - default: // Linux and others | |
| 85 | - new ProcessBuilder("xdg-open", path).start(); | |
| 86 | - break; | |
| 87 | - } | |
| 88 | - } catch (IOException ex) { | |
| 89 | - Log.log(ex); | |
| 90 | - Core.getMainWindow().showMessageDialog(StaticUtils.format( | |
| 91 | - L10n.getErrMsgFileHasNoAssoc(), path)); | |
| 92 | - } | |
| 93 | - } | |
| 94 | -} |
| @@ -1,59 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu; | |
| 18 | - | |
| 19 | -import java.util.ResourceBundle; | |
| 20 | - | |
| 21 | -/** | |
| 22 | - * | |
| 23 | - * @author Yu-Tang | |
| 24 | - */ | |
| 25 | -public class L10n { | |
| 26 | - | |
| 27 | - private static final ResourceBundle bundle; | |
| 28 | - | |
| 29 | - static { | |
| 30 | - bundle = ResourceBundle.getBundle("org/omegat/plugin/foldermenu/Bundle"); | |
| 31 | - } | |
| 32 | - | |
| 33 | - // for menu | |
| 34 | - | |
| 35 | - public static String getFoldersMenuLabel() { | |
| 36 | - return bundle.getString("FOLDERS_MENU_LABEL"); | |
| 37 | - } | |
| 38 | - | |
| 39 | - public static String getProjectRootMenuLabel() { | |
| 40 | - return bundle.getString("PROJECT_ROOT_MENU_LABEL"); | |
| 41 | - } | |
| 42 | - | |
| 43 | - public static String getUserConfigMenuLabel() { | |
| 44 | - return bundle.getString("USER_CONFIG_MENU_LABEL"); | |
| 45 | - } | |
| 46 | - | |
| 47 | - // for Word | |
| 48 | - | |
| 49 | - public static String getWordWindowCaption() { | |
| 50 | - return bundle.getString("WORD_WINDOW_CAPTION"); | |
| 51 | - } | |
| 52 | - | |
| 53 | - // for error | |
| 54 | - | |
| 55 | - public static String getErrMsgFileHasNoAssoc() { | |
| 56 | - return bundle.getString("ERROR_FILE_HAS_NO_ASSOC"); | |
| 57 | - } | |
| 58 | - | |
| 59 | -} |
| @@ -1,114 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu; | |
| 18 | - | |
| 19 | -import java.io.File; | |
| 20 | -import java.io.IOException; | |
| 21 | -import java.util.Arrays; | |
| 22 | -import javax.swing.JMenu; | |
| 23 | -import static org.omegat.plugin.foldermenu.MenuHelper.getComparator; | |
| 24 | -import static org.omegat.plugin.foldermenu.MenuHelper.getFilteredListFiles; | |
| 25 | -import static org.omegat.plugin.foldermenu.MenuHelper.getIcon; | |
| 26 | -import static org.omegat.plugin.foldermenu.MenuHelper.getMenuListener; | |
| 27 | -import static org.omegat.plugin.foldermenu.MenuHelper.getMouseListener; | |
| 28 | -import org.omegat.util.Log; | |
| 29 | -import org.openide.awt.Mnemonics; | |
| 30 | - | |
| 31 | -/** | |
| 32 | - * | |
| 33 | - * @author Yu-Tang | |
| 34 | - */ | |
| 35 | -public class ShellLinkMenu extends ShellLinkMenuItem { | |
| 36 | - | |
| 37 | - public ShellLinkMenu(JMenu m) { | |
| 38 | - super(m); | |
| 39 | - } | |
| 40 | - | |
| 41 | - public ShellLinkMenu(File folder) throws IOException { | |
| 42 | - this(folder, null); | |
| 43 | - } | |
| 44 | - | |
| 45 | - public ShellLinkMenu(String label) throws IOException { | |
| 46 | - this(null, label); | |
| 47 | - } | |
| 48 | - | |
| 49 | - public ShellLinkMenu(File folder, String label) throws IOException { | |
| 50 | - JMenu m; | |
| 51 | - if (label == null) { | |
| 52 | - m = new JMenu(folder.getName()); | |
| 53 | - } else { | |
| 54 | - m = new JMenu(); | |
| 55 | - Mnemonics.setLocalizedText(m, label); | |
| 56 | - } | |
| 57 | - | |
| 58 | - m.addMenuListener(getMenuListener()); | |
| 59 | - m.addMouseListener(getMouseListener()); | |
| 60 | - | |
| 61 | - if (folder != null) { | |
| 62 | - m.setIcon(getIcon(folder)); | |
| 63 | - m.setActionCommand(folder.getCanonicalPath()); | |
| 64 | - } else { | |
| 65 | - m.setEnabled(false); | |
| 66 | - } | |
| 67 | - | |
| 68 | - menuItem = m; | |
| 69 | - } | |
| 70 | - | |
| 71 | - public void createChildren() { | |
| 72 | - JMenu menu = (JMenu) menuItem; | |
| 73 | - if (menu.isEnabled() && menu.getItemCount() == 0) { | |
| 74 | - File folder = new File(menu.getActionCommand()); | |
| 75 | - File[] filteredListFiles = getFilteredListFiles(folder); | |
| 76 | - Arrays.sort(filteredListFiles, getComparator()); | |
| 77 | - | |
| 78 | - for (File file : filteredListFiles) { | |
| 79 | - try { | |
| 80 | - if (file.isDirectory() && hasChildren(file)) { | |
| 81 | - menu.add(new ShellLinkMenu(file).getMenuItem()); | |
| 82 | - } else { | |
| 83 | - menu.add(new ShellLinkMenuItem(file).getMenuItem()); | |
| 84 | - } | |
| 85 | - } catch (IOException ex) { | |
| 86 | - Log.log(ex); | |
| 87 | - } | |
| 88 | - } | |
| 89 | - } | |
| 90 | - } | |
| 91 | - | |
| 92 | - public JMenu getMenu() { | |
| 93 | - return (JMenu) menuItem; | |
| 94 | - } | |
| 95 | - | |
| 96 | - public void link(File folder) throws IOException { | |
| 97 | - JMenu menu = (JMenu) menuItem; | |
| 98 | - menu.setActionCommand(folder.getCanonicalPath()); | |
| 99 | - menu.setIcon(getIcon(folder)); | |
| 100 | - menu.setEnabled(true); | |
| 101 | - } | |
| 102 | - | |
| 103 | - public void unlink() { | |
| 104 | - JMenu menu = (JMenu) menuItem; | |
| 105 | - menu.setEnabled(false); | |
| 106 | - menu.removeAll(); | |
| 107 | - menu.setActionCommand(""); | |
| 108 | - menu.setIcon(null); | |
| 109 | - } | |
| 110 | - | |
| 111 | - private boolean hasChildren(File folder) { | |
| 112 | - return getFilteredListFiles(folder).length > 0; | |
| 113 | - } | |
| 114 | -} |
| @@ -1,82 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu; | |
| 18 | - | |
| 19 | -import java.io.File; | |
| 20 | -import java.io.IOException; | |
| 21 | -import javax.swing.JMenu; | |
| 22 | -import javax.swing.JMenuBar; | |
| 23 | -import org.omegat.core.Core; | |
| 24 | -import org.omegat.util.Log; | |
| 25 | -import org.omegat.util.StaticUtils; | |
| 26 | -import org.openide.awt.Mnemonics; | |
| 27 | - | |
| 28 | -/** | |
| 29 | - * | |
| 30 | - * @author Yu-Tang | |
| 31 | - */ | |
| 32 | -public class MenuManager { | |
| 33 | - | |
| 34 | - private JMenu root; | |
| 35 | - private JMenu currentProject; | |
| 36 | - private JMenu userConfig; | |
| 37 | - | |
| 38 | - public MenuManager() { | |
| 39 | - root = createLocalizedMenu(L10n.getFoldersMenuLabel()); // Folders menu | |
| 40 | - root.addMenuKeyListener(MenuHelper.getMenuKeyListener()); // for opening folder with enter key | |
| 41 | - root.addMenuListener(MenuHelper.getRootMenuListener()); | |
| 42 | - | |
| 43 | - // ProjectRoot | |
| 44 | - try { | |
| 45 | - root.add(currentProject = new ShellLinkMenu(L10n.getProjectRootMenuLabel()).getMenu()); | |
| 46 | - } catch (IOException ex) { | |
| 47 | - Log.log(ex); | |
| 48 | - return; | |
| 49 | - } | |
| 50 | - | |
| 51 | - // User Config | |
| 52 | - try { | |
| 53 | - File confDir = new File(StaticUtils.getConfigDir()); | |
| 54 | - root.add(userConfig = new ShellLinkMenu(confDir, L10n.getUserConfigMenuLabel()).getMenu()); | |
| 55 | - } catch (IOException ex) { | |
| 56 | - Log.log(ex); | |
| 57 | - } | |
| 58 | - | |
| 59 | - // insert Files menu before the last menu (Help menu.) | |
| 60 | - JMenuBar mainMenuBar = (JMenuBar) Core.getMainWindow().getMainMenu().getOptionsMenu().getParent(); | |
| 61 | - mainMenuBar.add(root, mainMenuBar.getMenuCount() - 1); | |
| 62 | - } | |
| 63 | - | |
| 64 | - public void createProjectItems() { | |
| 65 | - File rootDir = new File(Core.getProject().getProjectProperties().getProjectRoot()); | |
| 66 | - try { | |
| 67 | - new ShellLinkMenu(currentProject).link(rootDir); | |
| 68 | - } catch (IOException ex) { | |
| 69 | - Log.log(ex); | |
| 70 | - } | |
| 71 | - } | |
| 72 | - | |
| 73 | - public void removeAllProjectItems() { | |
| 74 | - new ShellLinkMenu(currentProject).unlink(); | |
| 75 | - } | |
| 76 | - | |
| 77 | - private JMenu createLocalizedMenu(String labelString) { | |
| 78 | - JMenu m = new JMenu(); | |
| 79 | - Mnemonics.setLocalizedText(m, labelString); | |
| 80 | - return m; | |
| 81 | - } | |
| 82 | -} | |
| \ No newline at end of file |
| @@ -1,62 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu; | |
| 18 | - | |
| 19 | -import org.omegat.core.CoreEvents; | |
| 20 | -import org.omegat.core.events.IApplicationEventListener; | |
| 21 | -import org.omegat.core.events.IProjectEventListener; | |
| 22 | -import org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE.*; | |
| 23 | -import org.omegat.plugin.foldermenu.filepreview.FilePreview; | |
| 24 | - | |
| 25 | -/** | |
| 26 | - * easy access to project folders from menu | |
| 27 | - * | |
| 28 | - * @author Yu Tang | |
| 29 | - */ | |
| 30 | -public class FolderMenu implements IApplicationEventListener, IProjectEventListener { | |
| 31 | - | |
| 32 | - private MenuManager menuManager; | |
| 33 | - | |
| 34 | - @SuppressWarnings("LeakingThisInConstructor") | |
| 35 | - public FolderMenu() { | |
| 36 | - CoreEvents.registerApplicationEventListener(this); | |
| 37 | - CoreEvents.registerProjectChangeListener(this); | |
| 38 | - } | |
| 39 | - | |
| 40 | - @Override | |
| 41 | - public void onApplicationStartup() { | |
| 42 | - menuManager = new MenuManager(); | |
| 43 | - FilePreview.init(); | |
| 44 | - } | |
| 45 | - | |
| 46 | - @Override | |
| 47 | - public void onApplicationShutdown() { /* do nothing */ } | |
| 48 | - | |
| 49 | - @Override | |
| 50 | - public void onProjectChanged(PROJECT_CHANGE_TYPE eventType) { | |
| 51 | - switch (eventType) { | |
| 52 | - case CREATE: | |
| 53 | - case LOAD: | |
| 54 | - menuManager.createProjectItems(); | |
| 55 | - break; | |
| 56 | - case CLOSE: | |
| 57 | - menuManager.removeAllProjectItems(); | |
| 58 | - break; | |
| 59 | - } | |
| 60 | - } | |
| 61 | - | |
| 62 | -} | |
| \ No newline at end of file |
| @@ -1,390 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu.filepreview; | |
| 18 | - | |
| 19 | -import java.io.File; | |
| 20 | -import java.io.IOException; | |
| 21 | -import java.io.InputStream; | |
| 22 | -import java.util.ArrayList; | |
| 23 | -import java.util.Arrays; | |
| 24 | -import java.util.List; | |
| 25 | -import org.omegat.plugin.foldermenu.L10n; | |
| 26 | -import org.omegat.util.LFileCopy; | |
| 27 | -import org.omegat.util.Log; | |
| 28 | -import static org.omegat.util.Platform.OsType.WIN32; | |
| 29 | -import static org.omegat.util.Platform.OsType.WIN64; | |
| 30 | -import static org.omegat.util.Platform.getOsType; | |
| 31 | -import org.omegat.util.StaticUtils; | |
| 32 | - | |
| 33 | -/** | |
| 34 | - * Word 文書をプレビュー用に開きます。 | |
| 35 | - * | |
| 36 | - * | |
| 37 | - * @author Yu-Tang | |
| 38 | - */ | |
| 39 | -public class WordPreview implements IPreview { | |
| 40 | - | |
| 41 | - private static final String WSF_NAME = "WordPreview.wsf"; | |
| 42 | - private static boolean _isMSWordAvailable; | |
| 43 | - private static File _wsf; | |
| 44 | - | |
| 45 | - private final File originalFile; | |
| 46 | - private long originalFileLastModified; // will update at each every time compiling target docs | |
| 47 | - private final String windowTitle; | |
| 48 | - private final File temporaryFile; // Primary temp file | |
| 49 | - private final File temporaryFile2; // Secondary temp file | |
| 50 | - | |
| 51 | - public WordPreview(final File originalFile) throws IOException { | |
| 52 | - this.originalFile = originalFile; | |
| 53 | - this.originalFileLastModified = originalFile.lastModified(); | |
| 54 | - this.temporaryFile = getTempFile(originalFile); | |
| 55 | - this.windowTitle = StaticUtils.format( | |
| 56 | - L10n.getWordWindowCaption(), | |
| 57 | - originalFile.getName()); | |
| 58 | - this.temporaryFile2 = getTempFile2(this.temporaryFile); | |
| 59 | - } | |
| 60 | - | |
| 61 | - static { | |
| 62 | - // _isMSWordAvailable | |
| 63 | - switch (getOsType()) { | |
| 64 | - case WIN64: | |
| 65 | - case WIN32: | |
| 66 | - new Thread() { | |
| 67 | - @Override | |
| 68 | - public void run() { | |
| 69 | - _isMSWordAvailable = getMSWordAvailable(); | |
| 70 | - Log.log("_isMSWordAvailable = " + _isMSWordAvailable); | |
| 71 | - } | |
| 72 | - }.start(); | |
| 73 | - break; | |
| 74 | - default: // Mac, Linux and others | |
| 75 | - _isMSWordAvailable = false; | |
| 76 | - break; | |
| 77 | - } | |
| 78 | - | |
| 79 | - // _wsf | |
| 80 | - File tempDir = new File(System.getProperty("java.io.tmpdir")); | |
| 81 | - _wsf = new File(tempDir, WSF_NAME); | |
| 82 | - } | |
| 83 | - | |
| 84 | - public static boolean isAvailable(File file) { | |
| 85 | - return isAvailable() && | |
| 86 | - file.isFile() && | |
| 87 | - file.getName().toLowerCase().endsWith(".docx"); | |
| 88 | - } | |
| 89 | - | |
| 90 | - public static boolean isAvailable() { | |
| 91 | - return _isMSWordAvailable; | |
| 92 | - } | |
| 93 | - | |
| 94 | - public static void init() { | |
| 95 | - // force executing static initializer | |
| 96 | - } | |
| 97 | - | |
| 98 | - private static boolean getMSWordAvailable() { | |
| 99 | - final int RET_OK = 0; | |
| 100 | - try { | |
| 101 | - Command command = new Command(); | |
| 102 | - String s; | |
| 103 | - if (RET_OK == command.execDOS("assoc", ".docx")) { | |
| 104 | - s = command.getStdout(); | |
| 105 | - // s's data example) | |
| 106 | - // ----------------------------------------------------- | |
| 107 | - //.docx=Word.Document.12 | |
| 108 | - //<-(\r\n) | |
| 109 | - // ----------------------------------------------------- | |
| 110 | - // 末尾に空行が入るので注意。 | |
| 111 | - if (s.toLowerCase().startsWith(".docx=word.document.")) { | |
| 112 | - String classString = s.substring(".docx=".length()).replaceAll("\\r\\n", ""); | |
| 113 | - if (RET_OK == command.exec("reg", "query", "HKCR\\" + classString + "\\shell\\open\\command", "/ve")) { | |
| 114 | - s = command.getStdout(); | |
| 115 | - // s's data example) | |
| 116 | - // ----------------------------------------------------- | |
| 117 | - //<-(\r\n) | |
| 118 | - //HKEY_CLASSES_ROOT\Word.document.12\shell\open\command | |
| 119 | - //(既定) REG_SZ "C:\PROGRA~2\MICROS~4\OFFICE11\WINWORD.EXE" /n /dde | |
| 120 | - //<-(\r\n) | |
| 121 | - // ----------------------------------------------------- | |
| 122 | - // 前後に空行が入るので注意。 | |
| 123 | - return s.toUpperCase().indexOf("\\WINWORD.EXE") > -1; | |
| 124 | - } | |
| 125 | - } | |
| 126 | - } | |
| 127 | - } catch (Exception ex) { | |
| 128 | - Log.log(ex); | |
| 129 | - } | |
| 130 | - return false; | |
| 131 | - } | |
| 132 | - | |
| 133 | - private static File getWSF() throws IOException { | |
| 134 | - if (! _wsf.exists()) { | |
| 135 | - InputStream in = WordPreview.class.getResourceAsStream(WSF_NAME); | |
| 136 | - try { | |
| 137 | - LFileCopy.copy(in, _wsf); | |
| 138 | - } finally { | |
| 139 | - in.close(); | |
| 140 | - } | |
| 141 | - _wsf.deleteOnExit(); | |
| 142 | - } | |
| 143 | - return _wsf; | |
| 144 | - } | |
| 145 | - | |
| 146 | - @Override | |
| 147 | - public String[] getTempFiles() { | |
| 148 | - // ここでは、残留する可能性のある一時ファイルをすべて申告します。 | |
| 149 | - String[] paths = new String[3]; | |
| 150 | - try { | |
| 151 | - paths[0] = this.temporaryFile.getCanonicalPath(); | |
| 152 | - paths[1] = this.temporaryFile2.getCanonicalPath(); | |
| 153 | - | |
| 154 | - // MS Word が作成する(プレビュー用ファイルの)一時ファイルも、強制 | |
| 155 | - // 終了時などには残留する可能性があるため、ここで申告しておきます。 | |
| 156 | - final String PREFIX = "~$"; | |
| 157 | - String parent = this.temporaryFile.getParent(); | |
| 158 | - String name = this.temporaryFile.getName(); | |
| 159 | - paths[2] = (new File(parent, PREFIX + name.substring(2))).getCanonicalPath(); | |
| 160 | - } catch (IOException ex) { | |
| 161 | - Log.log(ex); | |
| 162 | - } | |
| 163 | - return paths; | |
| 164 | - } | |
| 165 | - | |
| 166 | - @Override | |
| 167 | - public void activate() { | |
| 168 | - try { | |
| 169 | - final Command command = new Command(); | |
| 170 | - final String job = "activate"; | |
| 171 | - final int ret = command.execWSF(job, this.windowTitle); | |
| 172 | - } catch (IOException ex) { | |
| 173 | - Log.log(ex); | |
| 174 | - } catch (InterruptedException ex) { | |
| 175 | - Log.log(ex); | |
| 176 | - } | |
| 177 | - } | |
| 178 | - | |
| 179 | - @Override | |
| 180 | - public void open() { | |
| 181 | - | |
| 182 | - // 以下の処理は少し時間がかかるため、別スレッドに処理を委譲します。 | |
| 183 | - new Thread() { | |
| 184 | - @Override | |
| 185 | - public void run() { | |
| 186 | - try { | |
| 187 | - // 起動前にファイルをコピーする。 | |
| 188 | - // OmegaT は訳文ファイルの作成時に、既存の訳文ファイルを上書きする。 | |
| 189 | - // そのため、オリジナルのファイルをそのまま開くとファイルがロックされ、 | |
| 190 | - // 次回のコンパイル時に上書きできずに失敗する。それを避けるために、 | |
| 191 | - // プレビュー専用の一時ファイルをコピーして、そちらを開く。 | |
| 192 | - // コピー先は、temp フォルダーではなく、オリジナルと同じフォルダー内に | |
| 193 | - // コピーする。文書に相対パスで画像リンクなどが張られている場合のリンク | |
| 194 | - // 切れを防ぐため。 | |
| 195 | - // そのままコピーすると FolderMenu プラグインのメニュー上で一時ファイル | |
| 196 | - // が見えてしまうため、hidden 属性を付けておく。 | |
| 197 | - LFileCopy.copy(originalFile, temporaryFile); | |
| 198 | - | |
| 199 | - // make temp file hidden on Windows | |
| 200 | - addHiddenFileAttribute(temporaryFile); | |
| 201 | - | |
| 202 | - // Desktop.getDesktop().open(temp); | |
| 203 | - // 上記のようにして一時ファイルを開くと、場合によっては Word | |
| 204 | - // の MRU に一時ファイルを開いた履歴が大量に残ってしまう。 | |
| 205 | - // これを回避するため、WSH を経由して COM オートメーションで | |
| 206 | - // 処理する。 | |
| 207 | - | |
| 208 | - // open the document | |
| 209 | - Command command = new Command(); | |
| 210 | - String document = temporaryFile.getCanonicalPath(); | |
| 211 | - String document2 = temporaryFile2.getCanonicalPath(); | |
| 212 | - String job = "open"; | |
| 213 | - int ret = command.execWSF(job, document, document2, windowTitle); | |
| 214 | - | |
| 215 | - if (! command.stderr.isEmpty()) { | |
| 216 | - Log.log("Word error(" + ret + "): " + command.stderr); | |
| 217 | - } | |
| 218 | - onWordApplicationQuit(ret); | |
| 219 | - } catch (IOException ex) { | |
| 220 | - Log.log(ex); | |
| 221 | - } catch (InterruptedException ex) { | |
| 222 | - Log.log(ex); | |
| 223 | - } | |
| 224 | - } | |
| 225 | - }.start(); | |
| 226 | - } | |
| 227 | - | |
| 228 | - private File getTempFile(final File originalFile) throws IOException { | |
| 229 | - String prefix = "_WordPreview"; | |
| 230 | - String name = originalFile.getName(); | |
| 231 | - String suffix = name.substring(name.lastIndexOf(".")); | |
| 232 | - File parentFolder = originalFile.getParentFile(); | |
| 233 | - File tempFile = File.createTempFile(prefix, suffix, parentFolder); | |
| 234 | - tempFile.deleteOnExit(); | |
| 235 | - return tempFile; | |
| 236 | - } | |
| 237 | - | |
| 238 | - // foo.ext => foo(2).ext | |
| 239 | - private File getTempFile2(final File primaryTempFile) throws IOException { | |
| 240 | - String name = primaryTempFile.getName(); | |
| 241 | - int lastDotPos = name.lastIndexOf("."); | |
| 242 | - String baseName = name.substring(0, lastDotPos); | |
| 243 | - String extension = name.substring(lastDotPos); | |
| 244 | - String fileName = baseName + "(2)" + extension; | |
| 245 | - File parentFolder = primaryTempFile.getParentFile(); | |
| 246 | - File tempFile2 = new File(parentFolder, fileName); | |
| 247 | - tempFile2.deleteOnExit(); | |
| 248 | - return tempFile2; | |
| 249 | - } | |
| 250 | - | |
| 251 | - private void addHiddenFileAttribute(File file) { | |
| 252 | - try { | |
| 253 | - new ProcessBuilder("attrib","+H", file.getCanonicalPath()).start(); | |
| 254 | - } catch (IOException ex) { | |
| 255 | - Log.log(ex); | |
| 256 | - } | |
| 257 | - } | |
| 258 | - | |
| 259 | - private void onWordApplicationQuit(final int returnCode) { | |
| 260 | - try { | |
| 261 | - // remove this from Previews collection | |
| 262 | - FilePreview.delete(originalFile); | |
| 263 | - | |
| 264 | - // try to delete temporary file | |
| 265 | - temporaryFile.delete(); | |
| 266 | - | |
| 267 | - // try to delete WSF file | |
| 268 | - if (FilePreview.size(WordPreview.class) == 0) | |
| 269 | - _wsf.delete(); | |
| 270 | - | |
| 271 | - } catch (IOException ex) { | |
| 272 | - Log.log(ex); | |
| 273 | - } | |
| 274 | - } | |
| 275 | - | |
| 276 | - @Override | |
| 277 | - public void close() { | |
| 278 | - try { | |
| 279 | - // close the document | |
| 280 | - final Command command = new Command(); | |
| 281 | - final String job = "close"; | |
| 282 | - final String document = temporaryFile.getCanonicalPath(); | |
| 283 | - command.execWSF(job, document); | |
| 284 | - } catch (IOException ex) { | |
| 285 | - Log.log(ex); | |
| 286 | - } catch (InterruptedException ex) { | |
| 287 | - Log.log(ex); | |
| 288 | - } | |
| 289 | - } | |
| 290 | - | |
| 291 | - @Override | |
| 292 | - public void reload() { | |
| 293 | - if (! isOriginalFileUpdated()) { | |
| 294 | - return; | |
| 295 | - } | |
| 296 | - | |
| 297 | - try { | |
| 298 | - File temp = getTempFile(originalFile); | |
| 299 | - | |
| 300 | - // copy the file to avoid locking the file unnecessarily | |
| 301 | - LFileCopy.copy(originalFile, temp); | |
| 302 | - | |
| 303 | - // rename to secondary temp file (and pass it to WSF) | |
| 304 | - temp.renameTo(temporaryFile2); | |
| 305 | - | |
| 306 | - // make temp file hidden on Windows | |
| 307 | - addHiddenFileAttribute(temporaryFile2); | |
| 308 | - | |
| 309 | - // update lastModified value | |
| 310 | - this.originalFileLastModified = originalFile.lastModified(); | |
| 311 | - } catch (IOException ex) { | |
| 312 | - Log.log(ex); | |
| 313 | - } | |
| 314 | - } | |
| 315 | - | |
| 316 | - private boolean isOriginalFileUpdated() { | |
| 317 | - return this.originalFileLastModified != this.originalFile.lastModified(); | |
| 318 | - } | |
| 319 | - | |
| 320 | - // バッファあふれ非対応のため、少量のテキスト(だいたい 500文字ていど)が | |
| 321 | - // 予想される場合のみ利用してください。 | |
| 322 | - // また同期実行です。プロセスの終了を待機してから制御を返します。 | |
| 323 | - protected static class Command { | |
| 324 | - | |
| 325 | - private int exitCode = 0; | |
| 326 | - private String stdout = ""; | |
| 327 | - private String stderr = ""; | |
| 328 | - | |
| 329 | - public int getExitCode() { | |
| 330 | - return exitCode; | |
| 331 | - } | |
| 332 | - | |
| 333 | - public String getStdout() { | |
| 334 | - return stdout; | |
| 335 | - } | |
| 336 | - | |
| 337 | - public String getStderr() { | |
| 338 | - return stderr; | |
| 339 | - } | |
| 340 | - | |
| 341 | - public int exec(String... command) | |
| 342 | - throws IOException, InterruptedException { | |
| 343 | - return startProcessAndWait(Arrays.asList(command)); | |
| 344 | - } | |
| 345 | - | |
| 346 | - public int execDOS(String... command) | |
| 347 | - throws IOException, InterruptedException { | |
| 348 | - List<String> commands = new ArrayList<String>(command.length + 2); | |
| 349 | - commands.add("cmd.exe"); | |
| 350 | - commands.add("/c"); | |
| 351 | - commands.addAll(Arrays.asList(command)); | |
| 352 | - | |
| 353 | - return startProcessAndWait(commands); | |
| 354 | - } | |
| 355 | - | |
| 356 | - public int execWSF(String job, String... command) | |
| 357 | - throws IOException, InterruptedException { | |
| 358 | - String script = getWSF().getCanonicalPath(); | |
| 359 | - List<String> commands = new ArrayList<String>(command.length + 4); | |
| 360 | - commands.add("cscript.exe"); | |
| 361 | - commands.add("//nologo"); | |
| 362 | - commands.add("//Job:" + job); | |
| 363 | - commands.add(script); | |
| 364 | - commands.addAll(Arrays.asList(command)); | |
| 365 | - | |
| 366 | - return startProcessAndWait(commands); | |
| 367 | - } | |
| 368 | - | |
| 369 | - private int startProcessAndWait(List<String> command) | |
| 370 | - throws IOException, InterruptedException { | |
| 371 | - ProcessBuilder pb = new ProcessBuilder(command); | |
| 372 | - Process process = pb.start(); | |
| 373 | - exitCode = process.waitFor(); // 0: succeed | |
| 374 | - stdout = getString(process.getInputStream()); | |
| 375 | - stderr = getString(process.getErrorStream()); | |
| 376 | - return exitCode; | |
| 377 | - } | |
| 378 | - | |
| 379 | - private String getString(InputStream is) throws IOException { | |
| 380 | - byte[] b = new byte[1024]; | |
| 381 | - int size = is.read(b); | |
| 382 | - if (size > 0) { | |
| 383 | - return new String(b, 0, size); | |
| 384 | - } else { | |
| 385 | - return ""; | |
| 386 | - } | |
| 387 | - } | |
| 388 | - | |
| 389 | - } | |
| 390 | -} |
| @@ -1,102 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu.filepreview; | |
| 18 | - | |
| 19 | -import java.io.File; | |
| 20 | -import java.io.IOException; | |
| 21 | -import org.omegat.util.FileUtil; | |
| 22 | -import org.omegat.util.Log; | |
| 23 | -import org.omegat.util.StaticUtils; | |
| 24 | - | |
| 25 | -/** | |
| 26 | - * Cleanup temp files | |
| 27 | - * | |
| 28 | - * @author Yu-Tang | |
| 29 | - */ | |
| 30 | -public class TempFileCleaner { | |
| 31 | - | |
| 32 | - private static final String LOG_FILE_NAME = "FilePreviewTempFiles.log"; | |
| 33 | - private static final File logFile; | |
| 34 | - | |
| 35 | - private TempFileCleaner() { /* not allow instanciation. static only. */ } | |
| 36 | - | |
| 37 | - static { | |
| 38 | - logFile = new File(StaticUtils.getConfigDir(), LOG_FILE_NAME); | |
| 39 | - } | |
| 40 | - | |
| 41 | - public static void cleanup() { | |
| 42 | - // load temp file list from log file | |
| 43 | - String[] list = readTempFileList().split("\\n"); | |
| 44 | - String content = ""; | |
| 45 | - | |
| 46 | - // try to delete them | |
| 47 | - for (String path: list) { | |
| 48 | - if (! path.isEmpty()) { | |
| 49 | - File f = new File(path); | |
| 50 | - if (f.isFile()) { | |
| 51 | - if (! f.delete()) { | |
| 52 | - f.deleteOnExit(); | |
| 53 | - content += path + "\n"; | |
| 54 | - } | |
| 55 | - } | |
| 56 | - } | |
| 57 | - } | |
| 58 | - | |
| 59 | - // save back to log file or delete log if empty | |
| 60 | - writeTempFileList(content); | |
| 61 | - } | |
| 62 | - | |
| 63 | - public static void addToList(String[] filePaths) { | |
| 64 | - // load temp file list from log file | |
| 65 | - String list = readTempFileList(); | |
| 66 | - | |
| 67 | - // add the file to the list | |
| 68 | - for (String path: filePaths) | |
| 69 | - list += path + "\n"; | |
| 70 | - | |
| 71 | - // save back to log file or delete log if empty | |
| 72 | - writeTempFileList(list); | |
| 73 | - } | |
| 74 | - | |
| 75 | - // 末尾改行付きのリストを返します。 | |
| 76 | - private static String readTempFileList() { | |
| 77 | - String ret = ""; | |
| 78 | - if (logFile.isFile()) { | |
| 79 | - try { | |
| 80 | - ret = FileUtil.readTextFile(logFile); | |
| 81 | - if (!ret.isEmpty() && !ret.endsWith("\n")) | |
| 82 | - ret += "\n"; | |
| 83 | - } catch (IOException ex) { | |
| 84 | - Log.log(ex); | |
| 85 | - } | |
| 86 | - } | |
| 87 | - return ret; | |
| 88 | - } | |
| 89 | - | |
| 90 | - private static void writeTempFileList(final String content) { | |
| 91 | - if (content.isEmpty()) { | |
| 92 | - if (logFile.isFile()) | |
| 93 | - logFile.delete(); | |
| 94 | - } else { | |
| 95 | - try { | |
| 96 | - FileUtil.writeTextFile(logFile, content); | |
| 97 | - } catch (IOException ex) { | |
| 98 | - Log.log(ex); | |
| 99 | - } | |
| 100 | - } | |
| 101 | - } | |
| 102 | -} |
| @@ -1,221 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu.filepreview; | |
| 18 | - | |
| 19 | -import java.io.File; | |
| 20 | -import java.io.IOException; | |
| 21 | -import java.util.HashMap; | |
| 22 | -import javax.swing.SwingUtilities; | |
| 23 | -import org.omegat.core.Core; | |
| 24 | -import org.omegat.core.CoreEvents; | |
| 25 | -import org.omegat.core.events.IApplicationEventListener; | |
| 26 | -import org.omegat.core.events.IProjectEventListener; | |
| 27 | -import org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE; | |
| 28 | -import static org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE.CLOSE; | |
| 29 | -import static org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE.COMPILE; | |
| 30 | - | |
| 31 | -/** | |
| 32 | - * must call init() before using this class. | |
| 33 | - * | |
| 34 | - * @author Yu-Tang | |
| 35 | - */ | |
| 36 | - | |
| 37 | -public class FilePreview { | |
| 38 | - | |
| 39 | - // key = target file's canonical path | |
| 40 | - private static final HashMap<String, IPreview> previews = new HashMap<String, IPreview>(); | |
| 41 | - | |
| 42 | - private static IProjectEventListener projectEventListener = null; | |
| 43 | - private static IApplicationEventListener applicationEventListener = null; | |
| 44 | - | |
| 45 | - static { | |
| 46 | - // cleanup left temp files if they exists | |
| 47 | - TempFileCleaner.cleanup(); | |
| 48 | - | |
| 49 | - // call each Preview#init() | |
| 50 | - WordPreview.init(); | |
| 51 | - | |
| 52 | - //@@TODO WSF reload 時にselectionがテキストボックスの場合、restore に失敗するバグ | |
| 53 | - } | |
| 54 | - | |
| 55 | - public static boolean delete(final File originalFile) throws IOException { | |
| 56 | - String key = originalFile.getCanonicalPath(); | |
| 57 | - IPreview deleted = previews.remove(key); | |
| 58 | - if (previews.isEmpty()) | |
| 59 | - unhookProjectChangeEvent(); | |
| 60 | - return (deleted != null); | |
| 61 | - } | |
| 62 | - | |
| 63 | - public static void init() { | |
| 64 | - // force executing static initializer | |
| 65 | - } | |
| 66 | - | |
| 67 | - public static boolean open(File file) throws IOException { | |
| 68 | - // not available for directory | |
| 69 | - if (! file.isFile()) | |
| 70 | - return false; | |
| 71 | - | |
| 72 | - // does file exists inside of the target folder? | |
| 73 | - if (! isUnderTargetFolder(file)) | |
| 74 | - return false; | |
| 75 | - | |
| 76 | - // file type or environment is not supported | |
| 77 | - if (! available(file)) | |
| 78 | - return false; | |
| 79 | - | |
| 80 | - // Preview instance is already there? | |
| 81 | - String key = file.getCanonicalPath(); | |
| 82 | - if (previews.containsKey(key)) { | |
| 83 | - previews.get(key).activate(); | |
| 84 | - return true; | |
| 85 | - } | |
| 86 | - | |
| 87 | - // open it | |
| 88 | - IPreview p = new WordPreview(file); | |
| 89 | - p.open(); | |
| 90 | - hookProjectChangeEvent(); | |
| 91 | - hookApplicationChangeEvent(); | |
| 92 | - previews.put(key, p); | |
| 93 | - | |
| 94 | - // add temp files to cleaner list | |
| 95 | - TempFileCleaner.addToList(p.getTempFiles()); | |
| 96 | - | |
| 97 | - return true; | |
| 98 | - } | |
| 99 | - | |
| 100 | - public static int size(Class<?> classObj) { | |
| 101 | - if (classObj == null) { | |
| 102 | - return previews.size(); | |
| 103 | - } else { | |
| 104 | - int i = 0; | |
| 105 | - for (Object o: previews.values()) { | |
| 106 | - if (classObj.isInstance(o)) | |
| 107 | - i++; | |
| 108 | - } | |
| 109 | - return i; | |
| 110 | - } | |
| 111 | - } | |
| 112 | - | |
| 113 | - private static boolean available(File file) { | |
| 114 | - return WordPreview.isAvailable(file); | |
| 115 | - } | |
| 116 | - | |
| 117 | - /** hook project change event */ | |
| 118 | - private static void hookProjectChangeEvent() { | |
| 119 | - if (projectEventListener != null) | |
| 120 | - return; | |
| 121 | - | |
| 122 | - projectEventListener= new IProjectEventListener() { | |
| 123 | - | |
| 124 | - @Override | |
| 125 | - public void onProjectChanged(PROJECT_CHANGE_TYPE eventType) { | |
| 126 | - switch (eventType) { | |
| 127 | - case CLOSE: | |
| 128 | - onProjectClose(); | |
| 129 | - break; | |
| 130 | - case COMPILE: | |
| 131 | - onProjectCompile(); | |
| 132 | - break; | |
| 133 | - } | |
| 134 | - } | |
| 135 | - | |
| 136 | - }; | |
| 137 | - | |
| 138 | - CoreEvents.registerProjectChangeListener(projectEventListener); | |
| 139 | - } | |
| 140 | - | |
| 141 | - /** unhook project change event */ | |
| 142 | - private static void unhookProjectChangeEvent() { | |
| 143 | - if (projectEventListener == null) | |
| 144 | - return; | |
| 145 | - | |
| 146 | - CoreEvents.unregisterProjectChangeListener(projectEventListener); | |
| 147 | - projectEventListener= null; | |
| 148 | - } | |
| 149 | - | |
| 150 | - /** hook application change event */ | |
| 151 | - private static void hookApplicationChangeEvent() { | |
| 152 | - if (applicationEventListener != null) | |
| 153 | - return; | |
| 154 | - | |
| 155 | - applicationEventListener= new IApplicationEventListener() { | |
| 156 | - | |
| 157 | - @Override | |
| 158 | - public void onApplicationStartup() { | |
| 159 | - /* do nothing */ | |
| 160 | - } | |
| 161 | - | |
| 162 | - @Override | |
| 163 | - public void onApplicationShutdown() { | |
| 164 | - closeAllPreviews(); | |
| 165 | - } | |
| 166 | - | |
| 167 | - }; | |
| 168 | - | |
| 169 | - CoreEvents.registerApplicationEventListener(applicationEventListener); | |
| 170 | - } | |
| 171 | - | |
| 172 | - /** unhook project change event */ | |
| 173 | - private static void unhookApplicationChangeEvent() { | |
| 174 | - if (applicationEventListener == null) | |
| 175 | - return; | |
| 176 | - | |
| 177 | - CoreEvents.unregisterApplicationEventListener(applicationEventListener); | |
| 178 | - applicationEventListener= null; | |
| 179 | - } | |
| 180 | - | |
| 181 | - private static void onProjectClose() { | |
| 182 | - closeAllPreviews(); | |
| 183 | - | |
| 184 | - // イベントリスナーの登録解除をここで発行するとスレッドエラーになるので | |
| 185 | - // 後で実行する。 | |
| 186 | - SwingUtilities.invokeLater(new Runnable() { | |
| 187 | - @Override | |
| 188 | - public void run() { | |
| 189 | - unhookProjectChangeEvent(); | |
| 190 | - unhookApplicationChangeEvent(); | |
| 191 | - } | |
| 192 | - }); | |
| 193 | - } | |
| 194 | - | |
| 195 | - private static void onProjectCompile() { | |
| 196 | - reloadAllPreviews(); | |
| 197 | - } | |
| 198 | - | |
| 199 | - private static boolean isUnderTargetFolder(final File file) throws IOException { | |
| 200 | - // does file exists inside of the target folder? | |
| 201 | - String targetRoot = Core.getProject().getProjectProperties().getTargetRoot(); | |
| 202 | - return file.getCanonicalPath().startsWith(targetRoot); | |
| 203 | - } | |
| 204 | - | |
| 205 | - private static void closeAllPreviews() { | |
| 206 | - if (! previews.isEmpty()) { | |
| 207 | - for (IPreview preview: previews.values()) { | |
| 208 | - preview.close(); | |
| 209 | - } | |
| 210 | - } | |
| 211 | - } | |
| 212 | - | |
| 213 | - private static void reloadAllPreviews() { | |
| 214 | - if (! previews.isEmpty()) { | |
| 215 | - for (IPreview preview: previews.values()) { | |
| 216 | - preview.reload(); | |
| 217 | - } | |
| 218 | - } | |
| 219 | - } | |
| 220 | - | |
| 221 | -} |
| @@ -1,41 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu.filepreview; | |
| 18 | - | |
| 19 | -import java.io.File; | |
| 20 | - | |
| 21 | -/** | |
| 22 | - * | |
| 23 | - * @author Yu-Tang | |
| 24 | - */ | |
| 25 | -public interface IPreview { | |
| 26 | - | |
| 27 | - /** activate preview window */ | |
| 28 | - public void activate(); | |
| 29 | - | |
| 30 | - /** get temporary files for preview */ | |
| 31 | - public String[] getTempFiles(); | |
| 32 | - | |
| 33 | - /** open preview window */ | |
| 34 | - public void open(); | |
| 35 | - | |
| 36 | - /** close preview window */ | |
| 37 | - public void close(); | |
| 38 | - | |
| 39 | - /** reload document */ | |
| 40 | - public void reload(); | |
| 41 | - } |
| @@ -1,36 +0,0 @@ | ||
| 1 | -/************************************************************************** | |
| 2 | - FolderMenu - easy access to project folders from menu. | |
| 3 | - | |
| 4 | - Copyright (C) 2013 Yu Tang | |
| 5 | - Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | - Support center: http://sourceforge.jp/users/yu-tang/ | |
| 7 | - | |
| 8 | - This file is part of plugin for OmegaT. | |
| 9 | - http://www.omegat.org/ | |
| 10 | - | |
| 11 | - License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | - | |
| 13 | - You should have received a copy of the GNU General Public License | |
| 14 | - along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | - **************************************************************************/ | |
| 16 | - | |
| 17 | -package org.omegat.plugin.foldermenu; | |
| 18 | - | |
| 19 | -import javax.swing.JOptionPane; | |
| 20 | - | |
| 21 | -/** | |
| 22 | - * | |
| 23 | - * @author Yu-Tang | |
| 24 | - */ | |
| 25 | -public class VersionInfo { | |
| 26 | - | |
| 27 | - private static final String APP_NAME = "FolderMenu"; | |
| 28 | - private static final String APP_VERSION = "0.3"; | |
| 29 | - private static final String APP_BUILD = "20131024"; | |
| 30 | - private static final String APP_AUTHOR = "Yu-Tang"; | |
| 31 | - | |
| 32 | - public static void main(String[] args) { | |
| 33 | - JOptionPane.showMessageDialog(null, | |
| 34 | - APP_NAME + " ver." + APP_VERSION + "." + APP_BUILD + "\nby " + APP_AUTHOR); | |
| 35 | - } | |
| 36 | -} |
| @@ -0,0 +1,82 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu; | |
| 18 | + | |
| 19 | +import java.io.File; | |
| 20 | +import java.io.IOException; | |
| 21 | +import javax.swing.JMenu; | |
| 22 | +import javax.swing.JMenuBar; | |
| 23 | +import org.omegat.core.Core; | |
| 24 | +import org.omegat.util.Log; | |
| 25 | +import org.omegat.util.StaticUtils; | |
| 26 | +import org.openide.awt.Mnemonics; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * | |
| 30 | + * @author Yu-Tang | |
| 31 | + */ | |
| 32 | +public class MenuManager { | |
| 33 | + | |
| 34 | + private JMenu root; | |
| 35 | + private JMenu currentProject; | |
| 36 | + private JMenu userConfig; | |
| 37 | + | |
| 38 | + public MenuManager() { | |
| 39 | + root = createLocalizedMenu(L10n.getFoldersMenuLabel()); // Folders menu | |
| 40 | + root.addMenuKeyListener(MenuHelper.getMenuKeyListener()); // for opening folder with enter key | |
| 41 | + root.addMenuListener(MenuHelper.getRootMenuListener()); | |
| 42 | + | |
| 43 | + // ProjectRoot | |
| 44 | + try { | |
| 45 | + root.add(currentProject = new ShellLinkMenu(L10n.getProjectRootMenuLabel()).getMenu()); | |
| 46 | + } catch (IOException ex) { | |
| 47 | + Log.log(ex); | |
| 48 | + return; | |
| 49 | + } | |
| 50 | + | |
| 51 | + // User Config | |
| 52 | + try { | |
| 53 | + File confDir = new File(StaticUtils.getConfigDir()); | |
| 54 | + root.add(userConfig = new ShellLinkMenu(confDir, L10n.getUserConfigMenuLabel()).getMenu()); | |
| 55 | + } catch (IOException ex) { | |
| 56 | + Log.log(ex); | |
| 57 | + } | |
| 58 | + | |
| 59 | + // insert Files menu before the last menu (Help menu.) | |
| 60 | + JMenuBar mainMenuBar = (JMenuBar) Core.getMainWindow().getMainMenu().getOptionsMenu().getParent(); | |
| 61 | + mainMenuBar.add(root, mainMenuBar.getMenuCount() - 1); | |
| 62 | + } | |
| 63 | + | |
| 64 | + public void createProjectItems() { | |
| 65 | + File rootDir = new File(Core.getProject().getProjectProperties().getProjectRoot()); | |
| 66 | + try { | |
| 67 | + new ShellLinkMenu(currentProject).link(rootDir); | |
| 68 | + } catch (IOException ex) { | |
| 69 | + Log.log(ex); | |
| 70 | + } | |
| 71 | + } | |
| 72 | + | |
| 73 | + public void removeAllProjectItems() { | |
| 74 | + new ShellLinkMenu(currentProject).unlink(); | |
| 75 | + } | |
| 76 | + | |
| 77 | + private JMenu createLocalizedMenu(String labelString) { | |
| 78 | + JMenu m = new JMenu(); | |
| 79 | + Mnemonics.setLocalizedText(m, labelString); | |
| 80 | + return m; | |
| 81 | + } | |
| 82 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,62 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu; | |
| 18 | + | |
| 19 | +import org.omegat.core.CoreEvents; | |
| 20 | +import org.omegat.core.events.IApplicationEventListener; | |
| 21 | +import org.omegat.core.events.IProjectEventListener; | |
| 22 | +import org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE.*; | |
| 23 | +import jp.sourceforge.users.yutang.omegat.plugin.foldermenu.filepreview.FilePreview; | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * easy access to project folders from menu | |
| 27 | + * | |
| 28 | + * @author Yu Tang | |
| 29 | + */ | |
| 30 | +public class FolderMenu implements IApplicationEventListener, IProjectEventListener { | |
| 31 | + | |
| 32 | + private MenuManager menuManager; | |
| 33 | + | |
| 34 | + @SuppressWarnings("LeakingThisInConstructor") | |
| 35 | + public FolderMenu() { | |
| 36 | + CoreEvents.registerApplicationEventListener(this); | |
| 37 | + CoreEvents.registerProjectChangeListener(this); | |
| 38 | + } | |
| 39 | + | |
| 40 | + @Override | |
| 41 | + public void onApplicationStartup() { | |
| 42 | + menuManager = new MenuManager(); | |
| 43 | + FilePreview.init(); | |
| 44 | + } | |
| 45 | + | |
| 46 | + @Override | |
| 47 | + public void onApplicationShutdown() { /* do nothing */ } | |
| 48 | + | |
| 49 | + @Override | |
| 50 | + public void onProjectChanged(PROJECT_CHANGE_TYPE eventType) { | |
| 51 | + switch (eventType) { | |
| 52 | + case CREATE: | |
| 53 | + case LOAD: | |
| 54 | + menuManager.createProjectItems(); | |
| 55 | + break; | |
| 56 | + case CLOSE: | |
| 57 | + menuManager.removeAllProjectItems(); | |
| 58 | + break; | |
| 59 | + } | |
| 60 | + } | |
| 61 | + | |
| 62 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,36 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu; | |
| 18 | + | |
| 19 | +import javax.swing.JOptionPane; | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * | |
| 23 | + * @author Yu-Tang | |
| 24 | + */ | |
| 25 | +public class VersionInfo { | |
| 26 | + | |
| 27 | + private static final String APP_NAME = "FolderMenu"; | |
| 28 | + private static final String APP_VERSION = "0.3"; | |
| 29 | + private static final String APP_BUILD = "20131024"; | |
| 30 | + private static final String APP_AUTHOR = "Yu-Tang"; | |
| 31 | + | |
| 32 | + public static void main(String[] args) { | |
| 33 | + JOptionPane.showMessageDialog(null, | |
| 34 | + APP_NAME + " ver." + APP_VERSION + "." + APP_BUILD + "\nby " + APP_AUTHOR); | |
| 35 | + } | |
| 36 | +} |
| @@ -0,0 +1,102 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu.filepreview; | |
| 18 | + | |
| 19 | +import java.io.File; | |
| 20 | +import java.io.IOException; | |
| 21 | +import org.omegat.util.FileUtil; | |
| 22 | +import org.omegat.util.Log; | |
| 23 | +import org.omegat.util.StaticUtils; | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * Cleanup temp files | |
| 27 | + * | |
| 28 | + * @author Yu-Tang | |
| 29 | + */ | |
| 30 | +public class TempFileCleaner { | |
| 31 | + | |
| 32 | + private static final String LOG_FILE_NAME = "FilePreviewTempFiles.log"; | |
| 33 | + private static final File logFile; | |
| 34 | + | |
| 35 | + private TempFileCleaner() { /* not allow instanciation. static only. */ } | |
| 36 | + | |
| 37 | + static { | |
| 38 | + logFile = new File(StaticUtils.getConfigDir(), LOG_FILE_NAME); | |
| 39 | + } | |
| 40 | + | |
| 41 | + public static void cleanup() { | |
| 42 | + // load temp file list from log file | |
| 43 | + String[] list = readTempFileList().split("\\n"); | |
| 44 | + String content = ""; | |
| 45 | + | |
| 46 | + // try to delete them | |
| 47 | + for (String path: list) { | |
| 48 | + if (! path.isEmpty()) { | |
| 49 | + File f = new File(path); | |
| 50 | + if (f.isFile()) { | |
| 51 | + if (! f.delete()) { | |
| 52 | + f.deleteOnExit(); | |
| 53 | + content += path + "\n"; | |
| 54 | + } | |
| 55 | + } | |
| 56 | + } | |
| 57 | + } | |
| 58 | + | |
| 59 | + // save back to log file or delete log if empty | |
| 60 | + writeTempFileList(content); | |
| 61 | + } | |
| 62 | + | |
| 63 | + public static void addToList(String[] filePaths) { | |
| 64 | + // load temp file list from log file | |
| 65 | + String list = readTempFileList(); | |
| 66 | + | |
| 67 | + // add the file to the list | |
| 68 | + for (String path: filePaths) | |
| 69 | + list += path + "\n"; | |
| 70 | + | |
| 71 | + // save back to log file or delete log if empty | |
| 72 | + writeTempFileList(list); | |
| 73 | + } | |
| 74 | + | |
| 75 | + // 末尾改行付きのリストを返します。 | |
| 76 | + private static String readTempFileList() { | |
| 77 | + String ret = ""; | |
| 78 | + if (logFile.isFile()) { | |
| 79 | + try { | |
| 80 | + ret = FileUtil.readTextFile(logFile); | |
| 81 | + if (!ret.isEmpty() && !ret.endsWith("\n")) | |
| 82 | + ret += "\n"; | |
| 83 | + } catch (IOException ex) { | |
| 84 | + Log.log(ex); | |
| 85 | + } | |
| 86 | + } | |
| 87 | + return ret; | |
| 88 | + } | |
| 89 | + | |
| 90 | + private static void writeTempFileList(final String content) { | |
| 91 | + if (content.isEmpty()) { | |
| 92 | + if (logFile.isFile()) | |
| 93 | + logFile.delete(); | |
| 94 | + } else { | |
| 95 | + try { | |
| 96 | + FileUtil.writeTextFile(logFile, content); | |
| 97 | + } catch (IOException ex) { | |
| 98 | + Log.log(ex); | |
| 99 | + } | |
| 100 | + } | |
| 101 | + } | |
| 102 | +} |
| @@ -0,0 +1,221 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu.filepreview; | |
| 18 | + | |
| 19 | +import java.io.File; | |
| 20 | +import java.io.IOException; | |
| 21 | +import java.util.HashMap; | |
| 22 | +import javax.swing.SwingUtilities; | |
| 23 | +import org.omegat.core.Core; | |
| 24 | +import org.omegat.core.CoreEvents; | |
| 25 | +import org.omegat.core.events.IApplicationEventListener; | |
| 26 | +import org.omegat.core.events.IProjectEventListener; | |
| 27 | +import org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE; | |
| 28 | +import static org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE.CLOSE; | |
| 29 | +import static org.omegat.core.events.IProjectEventListener.PROJECT_CHANGE_TYPE.COMPILE; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * must call init() before using this class. | |
| 33 | + * | |
| 34 | + * @author Yu-Tang | |
| 35 | + */ | |
| 36 | + | |
| 37 | +public class FilePreview { | |
| 38 | + | |
| 39 | + // key = target file's canonical path | |
| 40 | + private static final HashMap<String, IPreview> previews = new HashMap<String, IPreview>(); | |
| 41 | + | |
| 42 | + private static IProjectEventListener projectEventListener = null; | |
| 43 | + private static IApplicationEventListener applicationEventListener = null; | |
| 44 | + | |
| 45 | + static { | |
| 46 | + // cleanup left temp files if they exists | |
| 47 | + TempFileCleaner.cleanup(); | |
| 48 | + | |
| 49 | + // call each Preview#init() | |
| 50 | + WordPreview.init(); | |
| 51 | + | |
| 52 | + //@@TODO WSF reload 時にselectionがテキストボックスの場合、restore に失敗するバグ | |
| 53 | + } | |
| 54 | + | |
| 55 | + public static boolean delete(final File originalFile) throws IOException { | |
| 56 | + String key = originalFile.getCanonicalPath(); | |
| 57 | + IPreview deleted = previews.remove(key); | |
| 58 | + if (previews.isEmpty()) | |
| 59 | + unhookProjectChangeEvent(); | |
| 60 | + return (deleted != null); | |
| 61 | + } | |
| 62 | + | |
| 63 | + public static void init() { | |
| 64 | + // force executing static initializer | |
| 65 | + } | |
| 66 | + | |
| 67 | + public static boolean open(File file) throws IOException { | |
| 68 | + // not available for directory | |
| 69 | + if (! file.isFile()) | |
| 70 | + return false; | |
| 71 | + | |
| 72 | + // does file exists inside of the target folder? | |
| 73 | + if (! isUnderTargetFolder(file)) | |
| 74 | + return false; | |
| 75 | + | |
| 76 | + // file type or environment is not supported | |
| 77 | + if (! available(file)) | |
| 78 | + return false; | |
| 79 | + | |
| 80 | + // Preview instance is already there? | |
| 81 | + String key = file.getCanonicalPath(); | |
| 82 | + if (previews.containsKey(key)) { | |
| 83 | + previews.get(key).activate(); | |
| 84 | + return true; | |
| 85 | + } | |
| 86 | + | |
| 87 | + // open it | |
| 88 | + IPreview p = new WordPreview(file); | |
| 89 | + p.open(); | |
| 90 | + hookProjectChangeEvent(); | |
| 91 | + hookApplicationChangeEvent(); | |
| 92 | + previews.put(key, p); | |
| 93 | + | |
| 94 | + // add temp files to cleaner list | |
| 95 | + TempFileCleaner.addToList(p.getTempFiles()); | |
| 96 | + | |
| 97 | + return true; | |
| 98 | + } | |
| 99 | + | |
| 100 | + public static int size(Class<?> classObj) { | |
| 101 | + if (classObj == null) { | |
| 102 | + return previews.size(); | |
| 103 | + } else { | |
| 104 | + int i = 0; | |
| 105 | + for (Object o: previews.values()) { | |
| 106 | + if (classObj.isInstance(o)) | |
| 107 | + i++; | |
| 108 | + } | |
| 109 | + return i; | |
| 110 | + } | |
| 111 | + } | |
| 112 | + | |
| 113 | + private static boolean available(File file) { | |
| 114 | + return WordPreview.isAvailable(file); | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** hook project change event */ | |
| 118 | + private static void hookProjectChangeEvent() { | |
| 119 | + if (projectEventListener != null) | |
| 120 | + return; | |
| 121 | + | |
| 122 | + projectEventListener= new IProjectEventListener() { | |
| 123 | + | |
| 124 | + @Override | |
| 125 | + public void onProjectChanged(PROJECT_CHANGE_TYPE eventType) { | |
| 126 | + switch (eventType) { | |
| 127 | + case CLOSE: | |
| 128 | + onProjectClose(); | |
| 129 | + break; | |
| 130 | + case COMPILE: | |
| 131 | + onProjectCompile(); | |
| 132 | + break; | |
| 133 | + } | |
| 134 | + } | |
| 135 | + | |
| 136 | + }; | |
| 137 | + | |
| 138 | + CoreEvents.registerProjectChangeListener(projectEventListener); | |
| 139 | + } | |
| 140 | + | |
| 141 | + /** unhook project change event */ | |
| 142 | + private static void unhookProjectChangeEvent() { | |
| 143 | + if (projectEventListener == null) | |
| 144 | + return; | |
| 145 | + | |
| 146 | + CoreEvents.unregisterProjectChangeListener(projectEventListener); | |
| 147 | + projectEventListener= null; | |
| 148 | + } | |
| 149 | + | |
| 150 | + /** hook application change event */ | |
| 151 | + private static void hookApplicationChangeEvent() { | |
| 152 | + if (applicationEventListener != null) | |
| 153 | + return; | |
| 154 | + | |
| 155 | + applicationEventListener= new IApplicationEventListener() { | |
| 156 | + | |
| 157 | + @Override | |
| 158 | + public void onApplicationStartup() { | |
| 159 | + /* do nothing */ | |
| 160 | + } | |
| 161 | + | |
| 162 | + @Override | |
| 163 | + public void onApplicationShutdown() { | |
| 164 | + closeAllPreviews(); | |
| 165 | + } | |
| 166 | + | |
| 167 | + }; | |
| 168 | + | |
| 169 | + CoreEvents.registerApplicationEventListener(applicationEventListener); | |
| 170 | + } | |
| 171 | + | |
| 172 | + /** unhook project change event */ | |
| 173 | + private static void unhookApplicationChangeEvent() { | |
| 174 | + if (applicationEventListener == null) | |
| 175 | + return; | |
| 176 | + | |
| 177 | + CoreEvents.unregisterApplicationEventListener(applicationEventListener); | |
| 178 | + applicationEventListener= null; | |
| 179 | + } | |
| 180 | + | |
| 181 | + private static void onProjectClose() { | |
| 182 | + closeAllPreviews(); | |
| 183 | + | |
| 184 | + // イベントリスナーの登録解除をここで発行するとスレッドエラーになるので | |
| 185 | + // 後で実行する。 | |
| 186 | + SwingUtilities.invokeLater(new Runnable() { | |
| 187 | + @Override | |
| 188 | + public void run() { | |
| 189 | + unhookProjectChangeEvent(); | |
| 190 | + unhookApplicationChangeEvent(); | |
| 191 | + } | |
| 192 | + }); | |
| 193 | + } | |
| 194 | + | |
| 195 | + private static void onProjectCompile() { | |
| 196 | + reloadAllPreviews(); | |
| 197 | + } | |
| 198 | + | |
| 199 | + private static boolean isUnderTargetFolder(final File file) throws IOException { | |
| 200 | + // does file exists inside of the target folder? | |
| 201 | + String targetRoot = Core.getProject().getProjectProperties().getTargetRoot(); | |
| 202 | + return file.getCanonicalPath().startsWith(targetRoot); | |
| 203 | + } | |
| 204 | + | |
| 205 | + private static void closeAllPreviews() { | |
| 206 | + if (! previews.isEmpty()) { | |
| 207 | + for (IPreview preview: previews.values()) { | |
| 208 | + preview.close(); | |
| 209 | + } | |
| 210 | + } | |
| 211 | + } | |
| 212 | + | |
| 213 | + private static void reloadAllPreviews() { | |
| 214 | + if (! previews.isEmpty()) { | |
| 215 | + for (IPreview preview: previews.values()) { | |
| 216 | + preview.reload(); | |
| 217 | + } | |
| 218 | + } | |
| 219 | + } | |
| 220 | + | |
| 221 | +} |
| @@ -0,0 +1,41 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu.filepreview; | |
| 18 | + | |
| 19 | +import java.io.File; | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * | |
| 23 | + * @author Yu-Tang | |
| 24 | + */ | |
| 25 | +public interface IPreview { | |
| 26 | + | |
| 27 | + /** activate preview window */ | |
| 28 | + public void activate(); | |
| 29 | + | |
| 30 | + /** get temporary files for preview */ | |
| 31 | + public String[] getTempFiles(); | |
| 32 | + | |
| 33 | + /** open preview window */ | |
| 34 | + public void open(); | |
| 35 | + | |
| 36 | + /** close preview window */ | |
| 37 | + public void close(); | |
| 38 | + | |
| 39 | + /** reload document */ | |
| 40 | + public void reload(); | |
| 41 | + } |
| @@ -0,0 +1,390 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu.filepreview; | |
| 18 | + | |
| 19 | +import java.io.File; | |
| 20 | +import java.io.IOException; | |
| 21 | +import java.io.InputStream; | |
| 22 | +import java.util.ArrayList; | |
| 23 | +import java.util.Arrays; | |
| 24 | +import java.util.List; | |
| 25 | +import jp.sourceforge.users.yutang.omegat.plugin.foldermenu.L10n; | |
| 26 | +import org.omegat.util.LFileCopy; | |
| 27 | +import org.omegat.util.Log; | |
| 28 | +import static org.omegat.util.Platform.OsType.WIN32; | |
| 29 | +import static org.omegat.util.Platform.OsType.WIN64; | |
| 30 | +import static org.omegat.util.Platform.getOsType; | |
| 31 | +import org.omegat.util.StaticUtils; | |
| 32 | + | |
| 33 | +/** | |
| 34 | + * Word 文書をプレビュー用に開きます。 | |
| 35 | + * | |
| 36 | + * | |
| 37 | + * @author Yu-Tang | |
| 38 | + */ | |
| 39 | +public class WordPreview implements IPreview { | |
| 40 | + | |
| 41 | + private static final String WSF_NAME = "WordPreview.wsf"; | |
| 42 | + private static boolean _isMSWordAvailable; | |
| 43 | + private static File _wsf; | |
| 44 | + | |
| 45 | + private final File originalFile; | |
| 46 | + private long originalFileLastModified; // will update at each every time compiling target docs | |
| 47 | + private final String windowTitle; | |
| 48 | + private final File temporaryFile; // Primary temp file | |
| 49 | + private final File temporaryFile2; // Secondary temp file | |
| 50 | + | |
| 51 | + public WordPreview(final File originalFile) throws IOException { | |
| 52 | + this.originalFile = originalFile; | |
| 53 | + this.originalFileLastModified = originalFile.lastModified(); | |
| 54 | + this.temporaryFile = getTempFile(originalFile); | |
| 55 | + this.windowTitle = StaticUtils.format( | |
| 56 | + L10n.getWordWindowCaption(), | |
| 57 | + originalFile.getName()); | |
| 58 | + this.temporaryFile2 = getTempFile2(this.temporaryFile); | |
| 59 | + } | |
| 60 | + | |
| 61 | + static { | |
| 62 | + // _isMSWordAvailable | |
| 63 | + switch (getOsType()) { | |
| 64 | + case WIN64: | |
| 65 | + case WIN32: | |
| 66 | + new Thread() { | |
| 67 | + @Override | |
| 68 | + public void run() { | |
| 69 | + _isMSWordAvailable = getMSWordAvailable(); | |
| 70 | + Log.log("_isMSWordAvailable = " + _isMSWordAvailable); | |
| 71 | + } | |
| 72 | + }.start(); | |
| 73 | + break; | |
| 74 | + default: // Mac, Linux and others | |
| 75 | + _isMSWordAvailable = false; | |
| 76 | + break; | |
| 77 | + } | |
| 78 | + | |
| 79 | + // _wsf | |
| 80 | + File tempDir = new File(System.getProperty("java.io.tmpdir")); | |
| 81 | + _wsf = new File(tempDir, WSF_NAME); | |
| 82 | + } | |
| 83 | + | |
| 84 | + public static boolean isAvailable(File file) { | |
| 85 | + return isAvailable() && | |
| 86 | + file.isFile() && | |
| 87 | + file.getName().toLowerCase().endsWith(".docx"); | |
| 88 | + } | |
| 89 | + | |
| 90 | + public static boolean isAvailable() { | |
| 91 | + return _isMSWordAvailable; | |
| 92 | + } | |
| 93 | + | |
| 94 | + public static void init() { | |
| 95 | + // force executing static initializer | |
| 96 | + } | |
| 97 | + | |
| 98 | + private static boolean getMSWordAvailable() { | |
| 99 | + final int RET_OK = 0; | |
| 100 | + try { | |
| 101 | + Command command = new Command(); | |
| 102 | + String s; | |
| 103 | + if (RET_OK == command.execDOS("assoc", ".docx")) { | |
| 104 | + s = command.getStdout(); | |
| 105 | + // s's data example) | |
| 106 | + // ----------------------------------------------------- | |
| 107 | + //.docx=Word.Document.12 | |
| 108 | + //<-(\r\n) | |
| 109 | + // ----------------------------------------------------- | |
| 110 | + // 末尾に空行が入るので注意。 | |
| 111 | + if (s.toLowerCase().startsWith(".docx=word.document.")) { | |
| 112 | + String classString = s.substring(".docx=".length()).replaceAll("\\r\\n", ""); | |
| 113 | + if (RET_OK == command.exec("reg", "query", "HKCR\\" + classString + "\\shell\\open\\command", "/ve")) { | |
| 114 | + s = command.getStdout(); | |
| 115 | + // s's data example) | |
| 116 | + // ----------------------------------------------------- | |
| 117 | + //<-(\r\n) | |
| 118 | + //HKEY_CLASSES_ROOT\Word.document.12\shell\open\command | |
| 119 | + //(既定) REG_SZ "C:\PROGRA~2\MICROS~4\OFFICE11\WINWORD.EXE" /n /dde | |
| 120 | + //<-(\r\n) | |
| 121 | + // ----------------------------------------------------- | |
| 122 | + // 前後に空行が入るので注意。 | |
| 123 | + return s.toUpperCase().indexOf("\\WINWORD.EXE") > -1; | |
| 124 | + } | |
| 125 | + } | |
| 126 | + } | |
| 127 | + } catch (Exception ex) { | |
| 128 | + Log.log(ex); | |
| 129 | + } | |
| 130 | + return false; | |
| 131 | + } | |
| 132 | + | |
| 133 | + private static File getWSF() throws IOException { | |
| 134 | + if (! _wsf.exists()) { | |
| 135 | + InputStream in = WordPreview.class.getResourceAsStream(WSF_NAME); | |
| 136 | + try { | |
| 137 | + LFileCopy.copy(in, _wsf); | |
| 138 | + } finally { | |
| 139 | + in.close(); | |
| 140 | + } | |
| 141 | + _wsf.deleteOnExit(); | |
| 142 | + } | |
| 143 | + return _wsf; | |
| 144 | + } | |
| 145 | + | |
| 146 | + @Override | |
| 147 | + public String[] getTempFiles() { | |
| 148 | + // ここでは、残留する可能性のある一時ファイルをすべて申告します。 | |
| 149 | + String[] paths = new String[3]; | |
| 150 | + try { | |
| 151 | + paths[0] = this.temporaryFile.getCanonicalPath(); | |
| 152 | + paths[1] = this.temporaryFile2.getCanonicalPath(); | |
| 153 | + | |
| 154 | + // MS Word が作成する(プレビュー用ファイルの)一時ファイルも、強制 | |
| 155 | + // 終了時などには残留する可能性があるため、ここで申告しておきます。 | |
| 156 | + final String PREFIX = "~$"; | |
| 157 | + String parent = this.temporaryFile.getParent(); | |
| 158 | + String name = this.temporaryFile.getName(); | |
| 159 | + paths[2] = (new File(parent, PREFIX + name.substring(2))).getCanonicalPath(); | |
| 160 | + } catch (IOException ex) { | |
| 161 | + Log.log(ex); | |
| 162 | + } | |
| 163 | + return paths; | |
| 164 | + } | |
| 165 | + | |
| 166 | + @Override | |
| 167 | + public void activate() { | |
| 168 | + try { | |
| 169 | + final Command command = new Command(); | |
| 170 | + final String job = "activate"; | |
| 171 | + final int ret = command.execWSF(job, this.windowTitle); | |
| 172 | + } catch (IOException ex) { | |
| 173 | + Log.log(ex); | |
| 174 | + } catch (InterruptedException ex) { | |
| 175 | + Log.log(ex); | |
| 176 | + } | |
| 177 | + } | |
| 178 | + | |
| 179 | + @Override | |
| 180 | + public void open() { | |
| 181 | + | |
| 182 | + // 以下の処理は少し時間がかかるため、別スレッドに処理を委譲します。 | |
| 183 | + new Thread() { | |
| 184 | + @Override | |
| 185 | + public void run() { | |
| 186 | + try { | |
| 187 | + // 起動前にファイルをコピーする。 | |
| 188 | + // OmegaT は訳文ファイルの作成時に、既存の訳文ファイルを上書きする。 | |
| 189 | + // そのため、オリジナルのファイルをそのまま開くとファイルがロックされ、 | |
| 190 | + // 次回のコンパイル時に上書きできずに失敗する。それを避けるために、 | |
| 191 | + // プレビュー専用の一時ファイルをコピーして、そちらを開く。 | |
| 192 | + // コピー先は、temp フォルダーではなく、オリジナルと同じフォルダー内に | |
| 193 | + // コピーする。文書に相対パスで画像リンクなどが張られている場合のリンク | |
| 194 | + // 切れを防ぐため。 | |
| 195 | + // そのままコピーすると FolderMenu プラグインのメニュー上で一時ファイル | |
| 196 | + // が見えてしまうため、hidden 属性を付けておく。 | |
| 197 | + LFileCopy.copy(originalFile, temporaryFile); | |
| 198 | + | |
| 199 | + // make temp file hidden on Windows | |
| 200 | + addHiddenFileAttribute(temporaryFile); | |
| 201 | + | |
| 202 | + // Desktop.getDesktop().open(temp); | |
| 203 | + // 上記のようにして一時ファイルを開くと、場合によっては Word | |
| 204 | + // の MRU に一時ファイルを開いた履歴が大量に残ってしまう。 | |
| 205 | + // これを回避するため、WSH を経由して COM オートメーションで | |
| 206 | + // 処理する。 | |
| 207 | + | |
| 208 | + // open the document | |
| 209 | + Command command = new Command(); | |
| 210 | + String document = temporaryFile.getCanonicalPath(); | |
| 211 | + String document2 = temporaryFile2.getCanonicalPath(); | |
| 212 | + String job = "open"; | |
| 213 | + int ret = command.execWSF(job, document, document2, windowTitle); | |
| 214 | + | |
| 215 | + if (! command.stderr.isEmpty()) { | |
| 216 | + Log.log("Word error(" + ret + "): " + command.stderr); | |
| 217 | + } | |
| 218 | + onWordApplicationQuit(ret); | |
| 219 | + } catch (IOException ex) { | |
| 220 | + Log.log(ex); | |
| 221 | + } catch (InterruptedException ex) { | |
| 222 | + Log.log(ex); | |
| 223 | + } | |
| 224 | + } | |
| 225 | + }.start(); | |
| 226 | + } | |
| 227 | + | |
| 228 | + private File getTempFile(final File originalFile) throws IOException { | |
| 229 | + String prefix = "_WordPreview"; | |
| 230 | + String name = originalFile.getName(); | |
| 231 | + String suffix = name.substring(name.lastIndexOf(".")); | |
| 232 | + File parentFolder = originalFile.getParentFile(); | |
| 233 | + File tempFile = File.createTempFile(prefix, suffix, parentFolder); | |
| 234 | + tempFile.deleteOnExit(); | |
| 235 | + return tempFile; | |
| 236 | + } | |
| 237 | + | |
| 238 | + // foo.ext => foo(2).ext | |
| 239 | + private File getTempFile2(final File primaryTempFile) throws IOException { | |
| 240 | + String name = primaryTempFile.getName(); | |
| 241 | + int lastDotPos = name.lastIndexOf("."); | |
| 242 | + String baseName = name.substring(0, lastDotPos); | |
| 243 | + String extension = name.substring(lastDotPos); | |
| 244 | + String fileName = baseName + "(2)" + extension; | |
| 245 | + File parentFolder = primaryTempFile.getParentFile(); | |
| 246 | + File tempFile2 = new File(parentFolder, fileName); | |
| 247 | + tempFile2.deleteOnExit(); | |
| 248 | + return tempFile2; | |
| 249 | + } | |
| 250 | + | |
| 251 | + private void addHiddenFileAttribute(File file) { | |
| 252 | + try { | |
| 253 | + new ProcessBuilder("attrib","+H", file.getCanonicalPath()).start(); | |
| 254 | + } catch (IOException ex) { | |
| 255 | + Log.log(ex); | |
| 256 | + } | |
| 257 | + } | |
| 258 | + | |
| 259 | + private void onWordApplicationQuit(final int returnCode) { | |
| 260 | + try { | |
| 261 | + // remove this from Previews collection | |
| 262 | + FilePreview.delete(originalFile); | |
| 263 | + | |
| 264 | + // try to delete temporary file | |
| 265 | + temporaryFile.delete(); | |
| 266 | + | |
| 267 | + // try to delete WSF file | |
| 268 | + if (FilePreview.size(WordPreview.class) == 0) | |
| 269 | + _wsf.delete(); | |
| 270 | + | |
| 271 | + } catch (IOException ex) { | |
| 272 | + Log.log(ex); | |
| 273 | + } | |
| 274 | + } | |
| 275 | + | |
| 276 | + @Override | |
| 277 | + public void close() { | |
| 278 | + try { | |
| 279 | + // close the document | |
| 280 | + final Command command = new Command(); | |
| 281 | + final String job = "close"; | |
| 282 | + final String document = temporaryFile.getCanonicalPath(); | |
| 283 | + command.execWSF(job, document); | |
| 284 | + } catch (IOException ex) { | |
| 285 | + Log.log(ex); | |
| 286 | + } catch (InterruptedException ex) { | |
| 287 | + Log.log(ex); | |
| 288 | + } | |
| 289 | + } | |
| 290 | + | |
| 291 | + @Override | |
| 292 | + public void reload() { | |
| 293 | + if (! isOriginalFileUpdated()) { | |
| 294 | + return; | |
| 295 | + } | |
| 296 | + | |
| 297 | + try { | |
| 298 | + File temp = getTempFile(originalFile); | |
| 299 | + | |
| 300 | + // copy the file to avoid locking the file unnecessarily | |
| 301 | + LFileCopy.copy(originalFile, temp); | |
| 302 | + | |
| 303 | + // rename to secondary temp file (and pass it to WSF) | |
| 304 | + temp.renameTo(temporaryFile2); | |
| 305 | + | |
| 306 | + // make temp file hidden on Windows | |
| 307 | + addHiddenFileAttribute(temporaryFile2); | |
| 308 | + | |
| 309 | + // update lastModified value | |
| 310 | + this.originalFileLastModified = originalFile.lastModified(); | |
| 311 | + } catch (IOException ex) { | |
| 312 | + Log.log(ex); | |
| 313 | + } | |
| 314 | + } | |
| 315 | + | |
| 316 | + private boolean isOriginalFileUpdated() { | |
| 317 | + return this.originalFileLastModified != this.originalFile.lastModified(); | |
| 318 | + } | |
| 319 | + | |
| 320 | + // バッファあふれ非対応のため、少量のテキスト(だいたい 500文字ていど)が | |
| 321 | + // 予想される場合のみ利用してください。 | |
| 322 | + // また同期実行です。プロセスの終了を待機してから制御を返します。 | |
| 323 | + protected static class Command { | |
| 324 | + | |
| 325 | + private int exitCode = 0; | |
| 326 | + private String stdout = ""; | |
| 327 | + private String stderr = ""; | |
| 328 | + | |
| 329 | + public int getExitCode() { | |
| 330 | + return exitCode; | |
| 331 | + } | |
| 332 | + | |
| 333 | + public String getStdout() { | |
| 334 | + return stdout; | |
| 335 | + } | |
| 336 | + | |
| 337 | + public String getStderr() { | |
| 338 | + return stderr; | |
| 339 | + } | |
| 340 | + | |
| 341 | + public int exec(String... command) | |
| 342 | + throws IOException, InterruptedException { | |
| 343 | + return startProcessAndWait(Arrays.asList(command)); | |
| 344 | + } | |
| 345 | + | |
| 346 | + public int execDOS(String... command) | |
| 347 | + throws IOException, InterruptedException { | |
| 348 | + List<String> commands = new ArrayList<String>(command.length + 2); | |
| 349 | + commands.add("cmd.exe"); | |
| 350 | + commands.add("/c"); | |
| 351 | + commands.addAll(Arrays.asList(command)); | |
| 352 | + | |
| 353 | + return startProcessAndWait(commands); | |
| 354 | + } | |
| 355 | + | |
| 356 | + public int execWSF(String job, String... command) | |
| 357 | + throws IOException, InterruptedException { | |
| 358 | + String script = getWSF().getCanonicalPath(); | |
| 359 | + List<String> commands = new ArrayList<String>(command.length + 4); | |
| 360 | + commands.add("cscript.exe"); | |
| 361 | + commands.add("//nologo"); | |
| 362 | + commands.add("//Job:" + job); | |
| 363 | + commands.add(script); | |
| 364 | + commands.addAll(Arrays.asList(command)); | |
| 365 | + | |
| 366 | + return startProcessAndWait(commands); | |
| 367 | + } | |
| 368 | + | |
| 369 | + private int startProcessAndWait(List<String> command) | |
| 370 | + throws IOException, InterruptedException { | |
| 371 | + ProcessBuilder pb = new ProcessBuilder(command); | |
| 372 | + Process process = pb.start(); | |
| 373 | + exitCode = process.waitFor(); // 0: succeed | |
| 374 | + stdout = getString(process.getInputStream()); | |
| 375 | + stderr = getString(process.getErrorStream()); | |
| 376 | + return exitCode; | |
| 377 | + } | |
| 378 | + | |
| 379 | + private String getString(InputStream is) throws IOException { | |
| 380 | + byte[] b = new byte[1024]; | |
| 381 | + int size = is.read(b); | |
| 382 | + if (size > 0) { | |
| 383 | + return new String(b, 0, size); | |
| 384 | + } else { | |
| 385 | + return ""; | |
| 386 | + } | |
| 387 | + } | |
| 388 | + | |
| 389 | + } | |
| 390 | +} |
| @@ -0,0 +1,226 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu; | |
| 18 | + | |
| 19 | +import java.awt.Component; | |
| 20 | +import java.awt.event.ActionEvent; | |
| 21 | +import java.awt.event.ActionListener; | |
| 22 | +import java.awt.event.KeyEvent; | |
| 23 | +import java.awt.event.MouseEvent; | |
| 24 | +import java.awt.event.MouseListener; | |
| 25 | +import java.io.File; | |
| 26 | +import java.io.FileFilter; | |
| 27 | +import java.util.Comparator; | |
| 28 | +import javax.swing.Icon; | |
| 29 | +import javax.swing.JMenu; | |
| 30 | +import javax.swing.JMenuItem; | |
| 31 | +import javax.swing.MenuElement; | |
| 32 | +import javax.swing.MenuSelectionManager; | |
| 33 | +import javax.swing.event.MenuEvent; | |
| 34 | +import javax.swing.event.MenuKeyEvent; | |
| 35 | +import javax.swing.event.MenuKeyListener; | |
| 36 | +import javax.swing.event.MenuListener; | |
| 37 | +import javax.swing.filechooser.FileSystemView; | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * | |
| 41 | + * @author Yu-Tang | |
| 42 | + */ | |
| 43 | +public class MenuHelper { | |
| 44 | + | |
| 45 | + static { | |
| 46 | + fs = FileSystemView.getFileSystemView(); | |
| 47 | + ff = new FileFilter() { | |
| 48 | + | |
| 49 | + @Override | |
| 50 | + public boolean accept(File file) { | |
| 51 | + // except dot started named files (i.e. ".svn") and hidden files | |
| 52 | + return !file.getName().startsWith(".") && !file.isHidden(); | |
| 53 | + } | |
| 54 | + | |
| 55 | + }; | |
| 56 | + | |
| 57 | + al = new ActionListener() { | |
| 58 | + | |
| 59 | + @Override | |
| 60 | + public void actionPerformed(ActionEvent e) { $(e).open(); } | |
| 61 | + | |
| 62 | + }; | |
| 63 | + | |
| 64 | + mkl = new MenuKeyListener() { | |
| 65 | + | |
| 66 | + @Override | |
| 67 | + public void menuKeyTyped(MenuKeyEvent e) { /* do nothing */ } | |
| 68 | + | |
| 69 | + @Override | |
| 70 | + public void menuKeyPressed(MenuKeyEvent e) { | |
| 71 | + if (e.getKeyCode() == KeyEvent.VK_ENTER) { | |
| 72 | + MenuSelectionManager manager = e.getMenuSelectionManager(); | |
| 73 | + MenuElement[] selectedPath = manager.getSelectedPath(); | |
| 74 | + MenuElement selection = selectedPath[selectedPath.length-1]; | |
| 75 | + if (selection instanceof JMenu) { | |
| 76 | + JMenu menu = (JMenu) selection; | |
| 77 | + if (menu.isEnabled()) { | |
| 78 | + manager.clearSelectedPath(); | |
| 79 | + $(menu).open(); | |
| 80 | + } | |
| 81 | + } | |
| 82 | + } | |
| 83 | + } | |
| 84 | + | |
| 85 | + @Override | |
| 86 | + public void menuKeyReleased(MenuKeyEvent e) { /* do nothing */ } | |
| 87 | + | |
| 88 | + }; | |
| 89 | + | |
| 90 | + mol = new MouseListener() { | |
| 91 | + | |
| 92 | + @Override | |
| 93 | + public void mouseClicked(MouseEvent e) { $(e).open(); } | |
| 94 | + | |
| 95 | + @Override | |
| 96 | + public void mousePressed(MouseEvent e) { /* do nothing */ } | |
| 97 | + | |
| 98 | + @Override | |
| 99 | + public void mouseReleased(MouseEvent e) { /* do nothing */ } | |
| 100 | + | |
| 101 | + @Override | |
| 102 | + public void mouseEntered(MouseEvent e) { /* do nothing */ } | |
| 103 | + | |
| 104 | + @Override | |
| 105 | + public void mouseExited(MouseEvent e) { /* do nothing */ } | |
| 106 | + | |
| 107 | + }; | |
| 108 | + | |
| 109 | + mel = new MenuListener() { | |
| 110 | + | |
| 111 | + @Override | |
| 112 | + public void menuSelected(MenuEvent e) { | |
| 113 | + // Lazy create submenus | |
| 114 | + $(e).createChildren(); | |
| 115 | + } | |
| 116 | + | |
| 117 | + @Override | |
| 118 | + public void menuDeselected(MenuEvent e) { /* do nothing */ } | |
| 119 | + | |
| 120 | + @Override | |
| 121 | + public void menuCanceled(MenuEvent e) { /* do nothing */ } | |
| 122 | + | |
| 123 | + }; | |
| 124 | + | |
| 125 | + /* for Folders root menu only */ | |
| 126 | + melRoot = new MenuListener() { | |
| 127 | + | |
| 128 | + @Override | |
| 129 | + public void menuSelected(MenuEvent e) { /* do nothing */ } | |
| 130 | + | |
| 131 | + @Override | |
| 132 | + public void menuDeselected(MenuEvent e) { | |
| 133 | + // remove children's all menuitems | |
| 134 | + JMenu menu = (JMenu) e.getSource(); | |
| 135 | + for (Component c: menu.getMenuComponents()) { | |
| 136 | + if (c instanceof JMenu) { | |
| 137 | + JMenu m = (JMenu) c; | |
| 138 | + if (m.isEnabled()) | |
| 139 | + m.removeAll(); | |
| 140 | + } | |
| 141 | + } | |
| 142 | + } | |
| 143 | + | |
| 144 | + @Override | |
| 145 | + public void menuCanceled(MenuEvent e) { /* do nothing */ } | |
| 146 | + | |
| 147 | + }; | |
| 148 | + | |
| 149 | + comp = new Comparator<File>() { | |
| 150 | + | |
| 151 | + @Override | |
| 152 | + public int compare(File f1, File f2) { | |
| 153 | + if (f1.isFile() == f2.isFile()) { | |
| 154 | + return f1.getName().compareToIgnoreCase(f2.getName()); | |
| 155 | + } else { | |
| 156 | + return f1.isFile() ? 1 : -1; | |
| 157 | + } | |
| 158 | + } | |
| 159 | + | |
| 160 | + }; | |
| 161 | + } | |
| 162 | + | |
| 163 | + private MenuHelper() {} // no instanciation, static only. | |
| 164 | + | |
| 165 | + public static Icon getIcon(File file) { | |
| 166 | + return fs.getSystemIcon(file); | |
| 167 | + } | |
| 168 | + | |
| 169 | + public static File[] getFilteredListFiles(File folder) { | |
| 170 | + return folder.listFiles(ff); | |
| 171 | + } | |
| 172 | + | |
| 173 | + public static ActionListener getActionListener() { | |
| 174 | + return al; | |
| 175 | + } | |
| 176 | + | |
| 177 | + public static MenuKeyListener getMenuKeyListener() { | |
| 178 | + return mkl; | |
| 179 | + } | |
| 180 | + | |
| 181 | + public static MouseListener getMouseListener() { | |
| 182 | + return mol; | |
| 183 | + } | |
| 184 | + | |
| 185 | + public static MenuListener getMenuListener() { | |
| 186 | + return mel; | |
| 187 | + } | |
| 188 | + | |
| 189 | + public static MenuListener getRootMenuListener() { | |
| 190 | + return melRoot; | |
| 191 | + } | |
| 192 | + | |
| 193 | + public static Comparator<File> getComparator() { | |
| 194 | + return comp; | |
| 195 | + } | |
| 196 | + | |
| 197 | + private static ShellLinkMenuItem $(JMenuItem mi) { | |
| 198 | + return new ShellLinkMenuItem(mi); | |
| 199 | + } | |
| 200 | + | |
| 201 | + private static ShellLinkMenu $(JMenu m) { | |
| 202 | + return new ShellLinkMenu(m); | |
| 203 | + } | |
| 204 | + | |
| 205 | + private static ShellLinkMenuItem $(ActionEvent e) { | |
| 206 | + return new ShellLinkMenuItem((JMenuItem) e.getSource()); | |
| 207 | + } | |
| 208 | + | |
| 209 | + private static ShellLinkMenu $(MouseEvent e) { | |
| 210 | + return new ShellLinkMenu((JMenu) e.getSource()); | |
| 211 | + } | |
| 212 | + | |
| 213 | + private static ShellLinkMenu $(MenuEvent e) { | |
| 214 | + return new ShellLinkMenu((JMenu) e.getSource()); | |
| 215 | + } | |
| 216 | + | |
| 217 | + private static final FileSystemView fs; | |
| 218 | + private static final FileFilter ff; | |
| 219 | + private static final ActionListener al; | |
| 220 | + private static final MenuKeyListener mkl; | |
| 221 | + private static final MouseListener mol; | |
| 222 | + private static final MenuListener mel; | |
| 223 | + private static final MenuListener melRoot; | |
| 224 | + private static final Comparator<File> comp; | |
| 225 | + | |
| 226 | +} |
| @@ -0,0 +1,94 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu; | |
| 18 | + | |
| 19 | +import java.awt.Desktop; | |
| 20 | +import java.io.File; | |
| 21 | +import java.io.IOException; | |
| 22 | +import javax.swing.JMenuItem; | |
| 23 | +import org.omegat.core.Core; | |
| 24 | +import static jp.sourceforge.users.yutang.omegat.plugin.foldermenu.MenuHelper.getActionListener; | |
| 25 | +import static jp.sourceforge.users.yutang.omegat.plugin.foldermenu.MenuHelper.getIcon; | |
| 26 | +import jp.sourceforge.users.yutang.omegat.plugin.foldermenu.filepreview.FilePreview; | |
| 27 | +import org.omegat.util.Log; | |
| 28 | +import static org.omegat.util.Platform.OsType.MAC32; | |
| 29 | +import static org.omegat.util.Platform.OsType.MAC64; | |
| 30 | +import static org.omegat.util.Platform.OsType.WIN32; | |
| 31 | +import static org.omegat.util.Platform.OsType.WIN64; | |
| 32 | +import static org.omegat.util.Platform.getOsType; | |
| 33 | +import org.omegat.util.StaticUtils; | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * | |
| 37 | + * @author Yu-Tang | |
| 38 | + */ | |
| 39 | +public class ShellLinkMenuItem { | |
| 40 | + | |
| 41 | + protected JMenuItem menuItem; | |
| 42 | + | |
| 43 | + public ShellLinkMenuItem() { | |
| 44 | + menuItem = new JMenuItem(); | |
| 45 | + } | |
| 46 | + | |
| 47 | + public ShellLinkMenuItem(JMenuItem mi) { | |
| 48 | + menuItem = mi; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public ShellLinkMenuItem(File file) throws IOException { | |
| 52 | + JMenuItem m = new JMenuItem(file.getName(), getIcon(file)); | |
| 53 | + m.setActionCommand(file.getCanonicalPath()); | |
| 54 | + m.addActionListener(getActionListener()); | |
| 55 | + menuItem = m; | |
| 56 | + } | |
| 57 | + | |
| 58 | + public boolean isEnabled() { | |
| 59 | + return menuItem.isEnabled(); | |
| 60 | + } | |
| 61 | + | |
| 62 | + public JMenuItem getMenuItem() { | |
| 63 | + return menuItem; | |
| 64 | + } | |
| 65 | + | |
| 66 | + public void open() { | |
| 67 | + if (! menuItem.isEnabled()) | |
| 68 | + return; | |
| 69 | + | |
| 70 | + String path = menuItem.getActionCommand(); | |
| 71 | + try { | |
| 72 | + switch (getOsType()) { | |
| 73 | + case WIN64: | |
| 74 | + case WIN32: | |
| 75 | + File file = new File(path); | |
| 76 | + if (! FilePreview.open(file)) { | |
| 77 | + Desktop.getDesktop().open(file); | |
| 78 | + } | |
| 79 | + break; | |
| 80 | + case MAC64: | |
| 81 | + case MAC32: | |
| 82 | + new ProcessBuilder("open", path).start(); | |
| 83 | + break; | |
| 84 | + default: // Linux and others | |
| 85 | + new ProcessBuilder("xdg-open", path).start(); | |
| 86 | + break; | |
| 87 | + } | |
| 88 | + } catch (IOException ex) { | |
| 89 | + Log.log(ex); | |
| 90 | + Core.getMainWindow().showMessageDialog(StaticUtils.format( | |
| 91 | + L10n.getErrMsgFileHasNoAssoc(), path)); | |
| 92 | + } | |
| 93 | + } | |
| 94 | +} |
| @@ -0,0 +1,59 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu; | |
| 18 | + | |
| 19 | +import java.util.ResourceBundle; | |
| 20 | + | |
| 21 | +/** | |
| 22 | + * | |
| 23 | + * @author Yu-Tang | |
| 24 | + */ | |
| 25 | +public class L10n { | |
| 26 | + | |
| 27 | + private static final ResourceBundle bundle; | |
| 28 | + | |
| 29 | + static { | |
| 30 | + bundle = ResourceBundle.getBundle("org/omegat/plugin/foldermenu/Bundle"); | |
| 31 | + } | |
| 32 | + | |
| 33 | + // for menu | |
| 34 | + | |
| 35 | + public static String getFoldersMenuLabel() { | |
| 36 | + return bundle.getString("FOLDERS_MENU_LABEL"); | |
| 37 | + } | |
| 38 | + | |
| 39 | + public static String getProjectRootMenuLabel() { | |
| 40 | + return bundle.getString("PROJECT_ROOT_MENU_LABEL"); | |
| 41 | + } | |
| 42 | + | |
| 43 | + public static String getUserConfigMenuLabel() { | |
| 44 | + return bundle.getString("USER_CONFIG_MENU_LABEL"); | |
| 45 | + } | |
| 46 | + | |
| 47 | + // for Word | |
| 48 | + | |
| 49 | + public static String getWordWindowCaption() { | |
| 50 | + return bundle.getString("WORD_WINDOW_CAPTION"); | |
| 51 | + } | |
| 52 | + | |
| 53 | + // for error | |
| 54 | + | |
| 55 | + public static String getErrMsgFileHasNoAssoc() { | |
| 56 | + return bundle.getString("ERROR_FILE_HAS_NO_ASSOC"); | |
| 57 | + } | |
| 58 | + | |
| 59 | +} |
| @@ -0,0 +1,114 @@ | ||
| 1 | +/************************************************************************** | |
| 2 | + FolderMenu - easy access to project folders from menu. | |
| 3 | + | |
| 4 | + Copyright (C) 2013 Yu Tang | |
| 5 | + Home page: http://sourceforge.jp/users/yu-tang/ | |
| 6 | + Support center: http://sourceforge.jp/users/yu-tang/pf/ | |
| 7 | + | |
| 8 | + This file is part of plugin for OmegaT. | |
| 9 | + http://www.omegat.org/ | |
| 10 | + | |
| 11 | + License: GNU GPL version 3 or (at your option) any later version. | |
| 12 | + | |
| 13 | + You should have received a copy of the GNU General Public License | |
| 14 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 15 | + **************************************************************************/ | |
| 16 | + | |
| 17 | +package jp.sourceforge.users.yutang.omegat.plugin.foldermenu; | |
| 18 | + | |
| 19 | +import java.io.File; | |
| 20 | +import java.io.IOException; | |
| 21 | +import java.util.Arrays; | |
| 22 | +import javax.swing.JMenu; | |
| 23 | +import static jp.sourceforge.users.yutang.omegat.plugin.foldermenu.MenuHelper.getComparator; | |
| 24 | +import static jp.sourceforge.users.yutang.omegat.plugin.foldermenu.MenuHelper.getFilteredListFiles; | |
| 25 | +import static jp.sourceforge.users.yutang.omegat.plugin.foldermenu.MenuHelper.getIcon; | |
| 26 | +import static jp.sourceforge.users.yutang.omegat.plugin.foldermenu.MenuHelper.getMenuListener; | |
| 27 | +import static jp.sourceforge.users.yutang.omegat.plugin.foldermenu.MenuHelper.getMouseListener; | |
| 28 | +import org.omegat.util.Log; | |
| 29 | +import org.openide.awt.Mnemonics; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * | |
| 33 | + * @author Yu-Tang | |
| 34 | + */ | |
| 35 | +public class ShellLinkMenu extends ShellLinkMenuItem { | |
| 36 | + | |
| 37 | + public ShellLinkMenu(JMenu m) { | |
| 38 | + super(m); | |
| 39 | + } | |
| 40 | + | |
| 41 | + public ShellLinkMenu(File folder) throws IOException { | |
| 42 | + this(folder, null); | |
| 43 | + } | |
| 44 | + | |
| 45 | + public ShellLinkMenu(String label) throws IOException { | |
| 46 | + this(null, label); | |
| 47 | + } | |
| 48 | + | |
| 49 | + public ShellLinkMenu(File folder, String label) throws IOException { | |
| 50 | + JMenu m; | |
| 51 | + if (label == null) { | |
| 52 | + m = new JMenu(folder.getName()); | |
| 53 | + } else { | |
| 54 | + m = new JMenu(); | |
| 55 | + Mnemonics.setLocalizedText(m, label); | |
| 56 | + } | |
| 57 | + | |
| 58 | + m.addMenuListener(getMenuListener()); | |
| 59 | + m.addMouseListener(getMouseListener()); | |
| 60 | + | |
| 61 | + if (folder != null) { | |
| 62 | + m.setIcon(getIcon(folder)); | |
| 63 | + m.setActionCommand(folder.getCanonicalPath()); | |
| 64 | + } else { | |
| 65 | + m.setEnabled(false); | |
| 66 | + } | |
| 67 | + | |
| 68 | + menuItem = m; | |
| 69 | + } | |
| 70 | + | |
| 71 | + public void createChildren() { | |
| 72 | + JMenu menu = (JMenu) menuItem; | |
| 73 | + if (menu.isEnabled() && menu.getItemCount() == 0) { | |
| 74 | + File folder = new File(menu.getActionCommand()); | |
| 75 | + File[] filteredListFiles = getFilteredListFiles(folder); | |
| 76 | + Arrays.sort(filteredListFiles, getComparator()); | |
| 77 | + | |
| 78 | + for (File file : filteredListFiles) { | |
| 79 | + try { | |
| 80 | + if (file.isDirectory() && hasChildren(file)) { | |
| 81 | + menu.add(new ShellLinkMenu(file).getMenuItem()); | |
| 82 | + } else { | |
| 83 | + menu.add(new ShellLinkMenuItem(file).getMenuItem()); | |
| 84 | + } | |
| 85 | + } catch (IOException ex) { | |
| 86 | + Log.log(ex); | |
| 87 | + } | |
| 88 | + } | |
| 89 | + } | |
| 90 | + } | |
| 91 | + | |
| 92 | + public JMenu getMenu() { | |
| 93 | + return (JMenu) menuItem; | |
| 94 | + } | |
| 95 | + | |
| 96 | + public void link(File folder) throws IOException { | |
| 97 | + JMenu menu = (JMenu) menuItem; | |
| 98 | + menu.setActionCommand(folder.getCanonicalPath()); | |
| 99 | + menu.setIcon(getIcon(folder)); | |
| 100 | + menu.setEnabled(true); | |
| 101 | + } | |
| 102 | + | |
| 103 | + public void unlink() { | |
| 104 | + JMenu menu = (JMenu) menuItem; | |
| 105 | + menu.setEnabled(false); | |
| 106 | + menu.removeAll(); | |
| 107 | + menu.setActionCommand(""); | |
| 108 | + menu.setIcon(null); | |
| 109 | + } | |
| 110 | + | |
| 111 | + private boolean hasChildren(File folder) { | |
| 112 | + return getFilteredListFiles(folder).length > 0; | |
| 113 | + } | |
| 114 | +} |