/* * Copyright 2017 Laszlo Balazs-Csiki * * This file is part of Pixelitor. Pixelitor is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License, version 3 as published by the Free * Software Foundation. * * Pixelitor 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 Pixelitor. If not, see <http://www.gnu.org/licenses/>. */ package pixelitor.utils; import pixelitor.NewImage; import pixelitor.Pixelitor; import pixelitor.TipsOfTheDay; import pixelitor.colors.FgBgColors; import pixelitor.filters.gui.IntChoiceParam.Value; import pixelitor.gui.Desktop; import pixelitor.gui.PixelitorWindow; import pixelitor.gui.utils.GridBagHelper; import pixelitor.gui.utils.IntTextField; import pixelitor.gui.utils.OKCancelDialog; import pixelitor.history.History; import pixelitor.io.Directories; import pixelitor.layers.LayerButtonLayout; import pixelitor.menus.file.RecentFileInfo; import pixelitor.menus.file.RecentFilesMenu; import javax.swing.*; import javax.swing.filechooser.FileSystemView; import java.awt.Color; import java.awt.Dimension; import java.awt.GraphicsEnvironment; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; import java.io.File; import java.util.prefs.Preferences; /** * Static methods for saving and loading application preferences */ public final class AppPreferences { private static final String FRAME_X_KEY = "window_x"; private static final String FRAME_Y_KEY = "window_y"; private static final String FRAME_WIDTH_KEY = "window_width"; private static final String FRAME_HEIGHT_KEY = "window_height"; private static final String NEW_IMAGE_WIDTH = "new_image_width"; private static final String NEW_IMAGE_HEIGHT = "new_image_height"; private static Dimension newImageSize = null; private static final String RECENT_FILE_PREFS_KEY = "recent_file_"; private static final Preferences mainUserNode = Preferences.userNodeForPackage(Pixelitor.class); private static final Preferences recentFilesUserNode = Preferences.userNodeForPackage(RecentFilesMenu.class); private static final String FG_COLOR_KEY = "fg_color"; private static final String BG_COLOR_KEY = "bg_color"; private static final String LAST_OPEN_DIR_KEY = "last_open_dir"; private static final String LAST_SAVE_DIR_KEY = "last_save_dir"; private static final String HISTOGRAMS_SHOWN_KEY = "histograms_shown"; private static final String LAYERS_SHOWN_KEY = "layers_shown"; private static final String TOOLS_SHOWN_KEY = "tools_shown"; private static final String STATUS_BAR_SHOWN_KEY = "status_bar_shown"; private static final String UNDO_LEVELS_KEY = "undo_levels"; private static final String THUMB_SIZE_KEY = "thumb_size"; private AppPreferences() { } private static void saveFramePosition(Window window) { int x = window.getX(); int y = window.getY(); int width = window.getWidth(); int height = window.getHeight(); mainUserNode.putInt(FRAME_X_KEY, x); mainUserNode.putInt(FRAME_Y_KEY, y); mainUserNode.putInt(FRAME_WIDTH_KEY, width); mainUserNode.putInt(FRAME_HEIGHT_KEY, height); } public static Dimension getNewImageSize() { if (newImageSize == null) { loadNewImageSize(); } return newImageSize; } private static void loadNewImageSize() { int defaultWidth = 600; int defaultHeight = 400; Dimension desktopSize = Desktop.INSTANCE.getDesktopSize(); if (desktopSize != null) { defaultWidth = Math.max(600, desktopSize.width - 30); defaultHeight = Math.max(400, desktopSize.height - 50); } int width = mainUserNode.getInt(NEW_IMAGE_WIDTH, defaultWidth); int height = mainUserNode.getInt(NEW_IMAGE_HEIGHT, defaultHeight); newImageSize = new Dimension(width, height); } private static void saveNewImageSize() { Dimension lastNew = NewImage.getLastNew(); if (lastNew != null) { mainUserNode.putInt(NEW_IMAGE_WIDTH, lastNew.width); mainUserNode.putInt(NEW_IMAGE_HEIGHT, lastNew.height); } } public static void loadFramePosition(Window window) { int x = mainUserNode.getInt(FRAME_X_KEY, 0); int y = mainUserNode.getInt(FRAME_Y_KEY, 0); int width = mainUserNode.getInt(FRAME_WIDTH_KEY, 0); int height = mainUserNode.getInt(FRAME_HEIGHT_KEY, 0); Rectangle screenBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); if ((width <= 0) || (height <= 0)) { width = screenBounds.width; height = screenBounds.height; } if (width > screenBounds.width) { width = screenBounds.width; } if (height > screenBounds.height) { height = screenBounds.height; } if ((x < 0) || (y < 0)) { x = 0; y = 0; } window.setLocation(new Point(x, y)); window.setSize(width, height); } public static BoundedUniqueList<RecentFileInfo> loadRecentFiles() { BoundedUniqueList<RecentFileInfo> retVal = new BoundedUniqueList<>(RecentFilesMenu.MAX_RECENT_FILES); for (int i = 0; i < RecentFilesMenu.MAX_RECENT_FILES; i++) { String key = RECENT_FILE_PREFS_KEY + i; String fileName = recentFilesUserNode.get(key, null); if (fileName == null) { break; } File file = new File(fileName); if (file.exists()) { RecentFileInfo fileInfo = new RecentFileInfo(file); retVal.addIfNotThere(fileInfo); } } return retVal; } private static void saveRecentFiles(BoundedUniqueList<RecentFileInfo> fileInfos) { for (int i = 0; i < fileInfos.size(); i++) { String key = RECENT_FILE_PREFS_KEY + i; String value = fileInfos.get(i).getSavedName(); recentFilesUserNode.put(key, value); } } public static void removeRecentFiles() { for (int i = 0; i < RecentFilesMenu.MAX_RECENT_FILES; i++) { recentFilesUserNode.remove(RECENT_FILE_PREFS_KEY + i); } } public static File loadLastOpenDir() { return loadDir(LAST_OPEN_DIR_KEY); } public static File loadLastSaveDir() { return loadDir(LAST_SAVE_DIR_KEY); } private static File loadDir(String key) { String s = mainUserNode.get(key, null); if (s == null) { return getDocumentsDir(); } File dir = new File(s); if (!dir.exists()) { return getDocumentsDir(); } if (!dir.isDirectory()) { return getDocumentsDir(); } return dir; } private static File getDocumentsDir() { return FileSystemView.getFileSystemView().getDefaultDirectory(); } private static void saveLastOpenDir() { saveDir(Directories.getLastOpenDir(), LAST_OPEN_DIR_KEY); } private static void saveLastSaveDir() { saveDir(Directories.getLastSaveDir(), LAST_SAVE_DIR_KEY); } private static void saveDir(File f, String key) { if (f != null) { mainUserNode.put(key, f.getAbsolutePath()); } else { mainUserNode.put(key, null); } } public static int loadUndoLevels() { int retVal = mainUserNode.getInt(UNDO_LEVELS_KEY, -1); if (retVal == -1) { return Math.min(5, getDefaultUndoLevels()); } return retVal; } private static void saveUndoLevels() { mainUserNode.putInt(UNDO_LEVELS_KEY, History.getUndoLevels()); } public static int loadThumbSize() { return mainUserNode.getInt(THUMB_SIZE_KEY, LayerButtonLayout.SMALL_THUMB_SIZE); } private static void saveThumbSize() { mainUserNode.putInt(THUMB_SIZE_KEY, LayerButtonLayout.getThumbSize()); } private static void savePreferencesBeforeExit() { saveRecentFiles(RecentFilesMenu.getInstance().getRecentFileInfosForSaving()); saveFramePosition(PixelitorWindow.getInstance()); saveLastOpenDir(); saveLastSaveDir(); saveFgBgColors(); WorkSpace.saveVisibility(); saveUndoLevels(); saveThumbSize(); TipsOfTheDay.saveNextTipNr(); saveNewImageSize(); } public static Color loadFgColor() { int fgInt = mainUserNode.getInt(FG_COLOR_KEY, 0xFF000000); return new Color(fgInt); } public static Color loadBgColor() { int bgInt = mainUserNode.getInt(BG_COLOR_KEY, 0xFFFFFFFF); return new Color(bgInt); } private static void saveFgBgColors() { Color fgColor = FgBgColors.getFG(); if (fgColor != null) { mainUserNode.putInt(FG_COLOR_KEY, fgColor.getRGB()); } Color bgColor = FgBgColors.getBG(); if (bgColor != null) { mainUserNode.putInt(BG_COLOR_KEY, bgColor.getRGB()); } } public static String getLookAndFeelClass() { UIManager.LookAndFeelInfo[] lookAndFeels = UIManager.getInstalledLookAndFeels(); for (UIManager.LookAndFeelInfo lookAndFeel : lookAndFeels) { if (lookAndFeel.getName().equals("Nimbus")) { return lookAndFeel.getClassName(); } } return UIManager.getSystemLookAndFeelClassName(); } public static void savePrefsAndExit() { savePreferencesBeforeExit(); System.exit(0); } public static class WorkSpace { /** * Utility class with static methods */ private WorkSpace() { } private static final boolean DEFAULT_HISTOGRAMS_VISIBILITY = false; private static final boolean DEFAULT_TOOLS_VISIBILITY = true; private static final boolean DEFAULT_LAYERS_VISIBILITY = true; private static final boolean DEFAULT_STATUS_BAR_VISIBILITY = true; static boolean loaded = false; private static boolean histogramsVisibility; private static boolean toolsVisibility; private static boolean layersVisibility; private static boolean statusBarVisibility; private static void load() { if (loaded) { return; } histogramsVisibility = mainUserNode.getBoolean(HISTOGRAMS_SHOWN_KEY, DEFAULT_HISTOGRAMS_VISIBILITY); toolsVisibility = mainUserNode.getBoolean(TOOLS_SHOWN_KEY, DEFAULT_TOOLS_VISIBILITY); layersVisibility = mainUserNode.getBoolean(LAYERS_SHOWN_KEY, DEFAULT_LAYERS_VISIBILITY); statusBarVisibility = mainUserNode.getBoolean(STATUS_BAR_SHOWN_KEY, DEFAULT_STATUS_BAR_VISIBILITY); loaded = true; } public static void setDefault(PixelitorWindow pw) { pw.setHistogramsVisibility(DEFAULT_HISTOGRAMS_VISIBILITY, false); pw.setToolsVisibility(DEFAULT_TOOLS_VISIBILITY, false); pw.setLayersVisibility(DEFAULT_LAYERS_VISIBILITY, false); pw.setStatusBarVisibility(DEFAULT_STATUS_BAR_VISIBILITY, false); pw.getContentPane().revalidate(); histogramsVisibility = DEFAULT_HISTOGRAMS_VISIBILITY; toolsVisibility = DEFAULT_TOOLS_VISIBILITY; layersVisibility = DEFAULT_LAYERS_VISIBILITY; statusBarVisibility = DEFAULT_STATUS_BAR_VISIBILITY; } public static boolean getHistogramsVisibility() { load(); return histogramsVisibility; } public static boolean getLayersVisibility() { load(); return layersVisibility; } public static boolean getStatusBarVisibility() { load(); return statusBarVisibility; } public static boolean getToolsVisibility() { load(); return toolsVisibility; } private static void saveVisibility() { mainUserNode.putBoolean(HISTOGRAMS_SHOWN_KEY, histogramsVisibility); mainUserNode.putBoolean(LAYERS_SHOWN_KEY, layersVisibility); mainUserNode.putBoolean(TOOLS_SHOWN_KEY, toolsVisibility); mainUserNode.putBoolean(STATUS_BAR_SHOWN_KEY, statusBarVisibility); } public static void setLayersVisibility(boolean v) { layersVisibility = v; PixelitorWindow pixelitorWindow = PixelitorWindow.getInstance(); pixelitorWindow.setLayersVisibility(v, true); } public static void setHistogramsVisibility(boolean v) { histogramsVisibility = v; PixelitorWindow pixelitorWindow = PixelitorWindow.getInstance(); pixelitorWindow.setHistogramsVisibility(v, true); } public static void setToolsVisibility(boolean v) { toolsVisibility = v; PixelitorWindow pixelitorWindow = PixelitorWindow.getInstance(); pixelitorWindow.setToolsVisibility(v, true); } public static void setStatusBarVisibility(boolean v) { statusBarVisibility = v; PixelitorWindow pixelitorWindow = PixelitorWindow.getInstance(); pixelitorWindow.setStatusBarVisibility(v, true); } } public static class Panel extends JPanel { private final JTextField undoLevelsTF; private final JComboBox<Value> thumbSizeCB; Panel() { setLayout(new GridBagLayout()); GridBagHelper gbh = new GridBagHelper(this); undoLevelsTF = new IntTextField(3); undoLevelsTF.setText(String.valueOf(History.getUndoLevels())); gbh.addLabelWithControl("Undo/Redo Levels: ", undoLevelsTF); Value[] thumbSizes = { new Value("24x24 pixels", 24), new Value("48x48 pixels", 48), new Value("72x72 pixels", 72), new Value("96x96 pixels", 96), }; thumbSizeCB = new JComboBox<>(thumbSizes); int currentSize = LayerButtonLayout.getThumbSize(); thumbSizeCB.setSelectedIndex(currentSize / 24 - 1); gbh.addLabelWithControl("Layer/Mask Thumb Sizes: ", thumbSizeCB); thumbSizeCB.addActionListener(e -> updateThumbSize()); } private int getUndoLevels() { String s = undoLevelsTF.getText(); return Integer.parseInt(s); } private void updateThumbSize() { int newSize = ((Value) thumbSizeCB.getSelectedItem()).getValue(); LayerButtonLayout.setThumbSize(newSize); } public static void showInDialog() { Panel p = new Panel(); OKCancelDialog d = new OKCancelDialog(p, "Preferences") { @Override protected void dialogAccepted() { int undoLevels = p.getUndoLevels(); History.setUndoLevels(undoLevels); p.updateThumbSize(); close(); } }; d.setVisible(true); } } public static Preferences getMainUserNode() { return mainUserNode; } private static int getDefaultUndoLevels() { int sizeInMegaBytes = Utils.getMaxHeapInMegabytes(); int retVal = 1 + (sizeInMegaBytes / 50); // rounds up to the nearest multiple of 5 return ((retVal + 4) / 5) * 5; } }