/* * Copyright 2016 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.gui.utils; import org.jdesktop.swingx.JXErrorPane; import org.jdesktop.swingx.error.ErrorInfo; import pixelitor.Build; import pixelitor.gui.GlobalKeyboardWatch; import pixelitor.gui.PixelitorWindow; import pixelitor.history.History; import pixelitor.utils.test.Events; import pixelitor.utils.test.RandomGUITest; import javax.sound.midi.MidiChannel; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Synthesizer; import javax.swing.*; import java.awt.Component; import java.awt.Frame; import java.awt.Toolkit; import java.awt.Window; import java.lang.reflect.InvocationTargetException; import java.util.logging.Level; /** * Static utility methods related to dialogs */ public class Dialogs { private static boolean mainWindowInitialized = false; private Dialogs() { // should not be instantiated } public static void setMainWindowInitialized(boolean mainWindowInitialized) { Dialogs.mainWindowInitialized = mainWindowInitialized; } public static Frame getParentForDialogs() { if (mainWindowInitialized) { return PixelitorWindow.getInstance(); } return null; } public static void showInfoDialog(String title, String msg) { showInfoDialog(getParentForDialogs(), title, msg); } public static void showInfoDialog(Component parent, String title, String msg) { GlobalKeyboardWatch.setDialogActive(true); JOptionPane.showMessageDialog(parent, msg, title, JOptionPane.INFORMATION_MESSAGE); GlobalKeyboardWatch.setDialogActive(false); } public static boolean showYesNoQuestionDialog(String title, String msg) { return showYesNoQuestionDialog(getParentForDialogs(), title, msg); } public static boolean showYesNoQuestionDialog(Component parent, String title, String msg) { return showYesNoDialog(parent, title, msg, JOptionPane.QUESTION_MESSAGE); } public static boolean showYesNoWarningDialog(String title, String msg) { return showYesNoWarningDialog(getParentForDialogs(), title, msg); } public static boolean showYesNoWarningDialog(Component parent, String title, String msg) { return showYesNoDialog(parent, title, msg, JOptionPane.WARNING_MESSAGE); } public static boolean showYesNoDialog(Component parent, String title, String msg, int messageType) { GlobalKeyboardWatch.setDialogActive(true); int reply = JOptionPane.showConfirmDialog(parent, msg, title, JOptionPane.YES_NO_OPTION, messageType); GlobalKeyboardWatch.setDialogActive(false); return (reply == JOptionPane.YES_OPTION); } public static boolean showOKCancelWarningDialog(String msg, String title, Object[] options, int initialOptionIndex) { return showOKCancelDialog(msg, title, options, initialOptionIndex, JOptionPane.WARNING_MESSAGE); } public static boolean showOKCancelDialog(String msg, String title, Object[] options, int initialOptionIndex, int messageType) { GlobalKeyboardWatch.setDialogActive(true); int userAnswer = JOptionPane.showOptionDialog(getParentForDialogs(), msg, title, JOptionPane.OK_CANCEL_OPTION, messageType, null, options, options[initialOptionIndex]); GlobalKeyboardWatch.setDialogActive(false); return userAnswer == JOptionPane.OK_OPTION; } public static void showErrorDialog(String title, String msg) { showErrorDialog(getParentForDialogs(), title, msg); } public static void showErrorDialog(Component parent, String title, String msg) { GlobalKeyboardWatch.setDialogActive(true); JOptionPane.showMessageDialog(parent, msg, title, JOptionPane.ERROR_MESSAGE); GlobalKeyboardWatch.setDialogActive(false); } public static void showWarningDialog(String title, String msg) { showWarningDialog(getParentForDialogs(), title, msg); } public static void showNotAColorOnClipboardDialog(Window parent) { showWarningDialog(parent, "Not a Color", "The clipboard contents could not be interpreted as a color"); } public static void showWarningDialog(Component parent, String title, String msg) { GlobalKeyboardWatch.setDialogActive(true); JOptionPane.showMessageDialog(parent, msg, title, JOptionPane.WARNING_MESSAGE); GlobalKeyboardWatch.setDialogActive(false); } public static void showNotImageLayerDialog() { if (!RandomGUITest.isRunning()) { showErrorDialog("Not an image layer", "The active layer is not an image layer."); } } public static void showNotImageLayerOrMaskDialog() { if (!RandomGUITest.isRunning()) { showErrorDialog("Not an image layer or mask", "The active layer is not an image layer or mask."); } } public static void showExceptionDialog(Throwable e) { Thread currentThread = Thread.currentThread(); showExceptionDialog(e, currentThread); } public static void showExceptionDialog(Throwable e, Thread thread) { String threadName = thread.getName(); System.err.printf("Exception in the thread '%s'%n", threadName); e.printStackTrace(); if(e instanceof InvocationTargetException) { e = e.getCause(); } if (RandomGUITest.isRunning()) { Events.dumpAll(); History.showHistory(); Toolkit.getDefaultToolkit().beep(); playWarningSound(); RandomGUITest.stop(); } else if(Build.CURRENT.isDevelopment()) { Events.dumpActive(); } Frame parent = getParentForDialogs(); String basicErrorMessage = "An exception occurred: " + e.getMessage(); ErrorInfo ii = new ErrorInfo("Program error", basicErrorMessage, null, null, e, Level.SEVERE, null); JXErrorPane.showDialog(parent, ii); } private static void playWarningSound() { // if (2 > 1) { // return; // } try { // int velocity = 127; // max volume int velocity = 90; // max volume int sound = 65; Synthesizer synthesizer = MidiSystem.getSynthesizer(); synthesizer.open(); MidiChannel channel = synthesizer.getChannels()[9]; // drums channel. for (int i = 0; i < 10; i++) { Thread.sleep(100); channel.noteOn(sound + i, velocity); Thread.sleep(100); channel.noteOff(sound + i); } } catch (MidiUnavailableException | InterruptedException e1) { e1.printStackTrace(); } } public static void showOutOfMemoryDialog(OutOfMemoryError e) { if (Build.CURRENT.isDevelopment()) { e.printStackTrace(); } String message = "<html><b>Out of memory error.</b> You can try <ul>" + "<li>decreasing the undo levels" + "<li>decreasing the number of layers" + "<li>working with smaller images"; String title = "Out of memory error."; Dialogs.showErrorDialog(title, message); } }