/************************************************************************** OmegaT - Computer Assisted Translation (CAT) tool with fuzzy matching, translation memory, keyword search, glossaries, and translation leveraging into updated projects. Copyright (C) 2000-2006 Keith Godfrey, Maxym Mykhalchuk, Henry Pijffers, Benjamin Siband, and Kim Bruning 2007 Zoltan Bartko 2008 Andrzej Sawula, Alex Buloichik 2014 Piotr Kulik 2015 Aaron Madlon-Kay Home page: http://www.omegat.org/ Support center: http://groups.yahoo.com/group/OmegaT/ This file is part of OmegaT. OmegaT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OmegaT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. **************************************************************************/ package org.omegat.gui.main; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.border.Border; import org.omegat.core.Core; import org.omegat.core.CoreEvents; import org.omegat.core.events.IApplicationEventListener; import org.omegat.core.events.IProjectEventListener; import org.omegat.gui.editor.EditorController; import org.omegat.gui.filelist.ProjectFilesListController; import org.omegat.util.Log; import org.omegat.util.OStrings; import org.omegat.util.Preferences; import org.omegat.util.StaticUtils; import org.omegat.util.gui.DockingUI; import org.omegat.util.gui.StaticUIUtils; import org.openide.awt.Mnemonics; import com.vlsolutions.swing.docking.DockingDesktop; import com.vlsolutions.swing.docking.event.DockableStateWillChangeEvent; import com.vlsolutions.swing.docking.event.DockableStateWillChangeListener; /** * Class for initialize, load/save, etc. for main window UI components. * * @author Keith Godfrey * @author Benjamin Siband * @author Maxym Mykhalchuk * @author Kim Bruning * @author Henry Pijffers (henry.pijffers@saxnot.com) * @author Zoltan Bartko - bartkozoltan@bartkozoltan.com * @author Andrzej Sawula * @author Alex Buloichik (alex73mail@gmail.com) * @author Piotr Kulik * @author Aaron Madlon-Kay */ public class MainWindowUI { public static final String UI_LAYOUT_FILE = "uiLayout" + OStrings.getBrandingToken() + ".xml"; public enum STATUS_BAR_MODE { DEFAULT, PERCENTAGE, }; /** * Create main UI panels. */ public static void createMainComponents(final MainWindow mainWindow, final Font font) { mainWindow.m_projWin = new ProjectFilesListController(mainWindow); } /** * Create docking desktop panel. */ public static DockingDesktop initDocking(final MainWindow mainWindow) { DockingUI.initialize(); mainWindow.desktop = new DockingDesktop(); mainWindow.desktop.addDockableStateWillChangeListener(new DockableStateWillChangeListener() { public void dockableStateWillChange(DockableStateWillChangeEvent event) { if (event.getFutureState().isClosed()) event.cancel(); } }); return mainWindow.desktop; } /** * Installs a {@link IProjectEventListener} that handles loading, storing, * and restoring the main window layout when a project-specific layout is present. */ public static void handlePerProjectLayouts(final MainWindow mainWindow) { PerProjectLayoutHandler handler = new PerProjectLayoutHandler(mainWindow); CoreEvents.registerProjectChangeListener(handler); CoreEvents.registerApplicationEventListener(handler); } private static class PerProjectLayoutHandler implements IProjectEventListener, IApplicationEventListener { private final MainWindow mainWindow; private boolean didApplyPerProjectLayout = false; public PerProjectLayoutHandler(MainWindow mainWindow) { this.mainWindow = mainWindow; } @Override public void onApplicationStartup() { } @Override public void onApplicationShutdown() { // Project is not closed before shutdown, so we need to handle this separately // from the onProjectChanged events. if (Core.getProject().isProjectLoaded() && didApplyPerProjectLayout) { loadScreenLayoutFromPreferences(mainWindow); didApplyPerProjectLayout = false; } } @Override public void onProjectChanged(PROJECT_CHANGE_TYPE eventType) { if (eventType == PROJECT_CHANGE_TYPE.CLOSE && didApplyPerProjectLayout) { loadScreenLayoutFromPreferences(mainWindow); didApplyPerProjectLayout = false; return; } if (!Core.getProject().isProjectLoaded()) { return; } File perProjLayout = getPerProjectLayout(); if (!perProjLayout.isFile()) { return; } switch (eventType) { case LOAD: saveScreenLayout(mainWindow); loadScreenLayout(mainWindow, perProjLayout); didApplyPerProjectLayout = true; break; case SAVE: saveScreenLayout(mainWindow, perProjLayout); break; default: } } private File getPerProjectLayout() { return new File(Core.getProject().getProjectProperties().getProjectInternal(), MainWindowUI.UI_LAYOUT_FILE); } } /** * Create swing UI components for status panel. */ public static JPanel createStatusBar(final MainWindow mainWindow) { mainWindow.statusLabel = new JLabel(); mainWindow.progressLabel = new JLabel(); mainWindow.lengthLabel = new JLabel(); mainWindow.statusLabel.setFont(mainWindow.statusLabel.getFont().deriveFont(11f)); Border border = UIManager.getBorder("OmegaTStatusArea.border"); final STATUS_BAR_MODE progressMode = Preferences.getPreferenceEnumDefault( Preferences.SB_PROGRESS_MODE, STATUS_BAR_MODE.DEFAULT); String statusText = OStrings.getString("MW_PROGRESS_DEFAULT"); String tooltipText = "MW_PROGRESS_TOOLTIP"; if (progressMode == STATUS_BAR_MODE.PERCENTAGE) { statusText = OStrings.getProgressBarDefaultPrecentageText(); tooltipText = "MW_PROGRESS_TOOLTIP_PERCENTAGE"; } Mnemonics.setLocalizedText(mainWindow.progressLabel, statusText); mainWindow.progressLabel.setToolTipText(OStrings.getString(tooltipText)); mainWindow.progressLabel.setBorder(border); mainWindow.progressLabel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { STATUS_BAR_MODE[] modes = STATUS_BAR_MODE.values(); STATUS_BAR_MODE progressMode = Preferences.getPreferenceEnumDefault( Preferences.SB_PROGRESS_MODE, STATUS_BAR_MODE.DEFAULT); progressMode = modes[(progressMode.ordinal() + 1) % modes.length]; Preferences.setPreference(Preferences.SB_PROGRESS_MODE, progressMode); String statusText = OStrings.getString("MW_PROGRESS_DEFAULT"); String tooltipText = "MW_PROGRESS_TOOLTIP"; if (progressMode == STATUS_BAR_MODE.PERCENTAGE) { statusText = OStrings.getProgressBarDefaultPrecentageText(); tooltipText = "MW_PROGRESS_TOOLTIP_PERCENTAGE"; } if (Core.getProject().isProjectLoaded()) { ((EditorController)Core.getEditor()).showStat(); } else { Core.getMainWindow().showProgressMessage(statusText); } ((MainWindow)Core.getMainWindow()).setProgressToolTipText(OStrings.getString(tooltipText)); } }); Mnemonics.setLocalizedText(mainWindow.lengthLabel, OStrings.getString("MW_SEGMENT_LENGTH_DEFAULT")); mainWindow.lengthLabel.setToolTipText(OStrings.getString("MW_SEGMENT_LENGTH_TOOLTIP")); mainWindow.lengthLabel.setBorder(border); mainWindow.lengthLabel.setFocusable(false); JPanel statusPanel2 = new JPanel(new FlowLayout(FlowLayout.RIGHT)); statusPanel2.add(mainWindow.progressLabel); statusPanel2.add(mainWindow.lengthLabel); JPanel statusPanel = new JPanel(new BorderLayout()); statusPanel.add(mainWindow.statusLabel, BorderLayout.CENTER); statusPanel.add(statusPanel2, BorderLayout.EAST); statusPanel.setBorder(UIManager.getBorder("OmegaTMainWindowBottomMargin.border")); Color bgColor = UIManager.getColor("AutoHideButtonPanel.background"); if (bgColor != null) { statusPanel.setBackground(bgColor); statusPanel2.setBackground(bgColor); } return statusPanel; } /** * Initialize the size of OmegaT window, then load the layout prefs. */ public static void initializeScreenLayout(MainWindow mainWindow) { mainWindow.setBounds(getDefaultBounds()); StaticUIUtils.persistGeometry(mainWindow, Preferences.MAINWINDOW_GEOMETRY_PREFIX); loadScreenLayoutFromPreferences(mainWindow); // Ensure any "closed" Dockables are visible. These can be newly added // panes not included in an older layout file, or e.g. panes installed by // plugins. DockingUI.ensureDockablesVisible(mainWindow.desktop); } /** * Assume screen size is 800x600 if width less than 900, and 1024x768 if * larger. Assume task bar at bottom of screen. If screen size saved, * recover that and use instead (18may04). */ static Rectangle getDefaultBounds() { // size info missing - put window in default position GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); Rectangle scrSize = env.getMaximumWindowBounds(); if (scrSize.width < 900) { // assume 800x600 return new Rectangle(0, 0, 580, 536); } else { // assume 1024x768 or larger return new Rectangle(0, 0, 690, 700); } } /** * Load the main window layout from the global preferences file. Will reset to defaults * if global preferences are not present or if an error occurs. */ private static void loadScreenLayoutFromPreferences(MainWindow mainWindow) { File uiLayoutFile = new File(StaticUtils.getConfigDir(), MainWindowUI.UI_LAYOUT_FILE); if (uiLayoutFile.exists()) { loadScreenLayout(mainWindow, uiLayoutFile); } else { resetDesktopLayout(mainWindow); } } /** * Load the main window layout from the specified file. Will reset to * defaults if an error occurs. */ private static void loadScreenLayout(MainWindow mainWindow, File uiLayoutFile) { try (InputStream in = new FileInputStream(uiLayoutFile)) { mainWindow.desktop.readXML(in); } catch (Exception ex) { Log.log(ex); resetDesktopLayout(mainWindow); } } /** * Stores main window docking layout to disk. */ public static void saveScreenLayout(MainWindow mainWindow) { File uiLayoutFile = new File(StaticUtils.getConfigDir(), MainWindowUI.UI_LAYOUT_FILE); saveScreenLayout(mainWindow, uiLayoutFile); } /** * Stores main window layout to the specified output file. */ private static void saveScreenLayout(MainWindow mainWindow, File uiLayoutFile) { try (OutputStream out = new FileOutputStream(uiLayoutFile)) { mainWindow.desktop.writeXML(out); } catch (Exception ex) { Log.log(ex); } } /** * Restores main window layout to the default values (distinct from global preferences). */ public static void resetDesktopLayout(MainWindow mainWindow) { try (InputStream in = MainWindowUI.class.getResourceAsStream("DockingDefaults.xml")) { mainWindow.desktop.readXML(in); } catch (Exception e) { Log.log(e); } } }