/* * Created on May 1, 2004 * Created by Olivier Chalouhi * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved. * * This program 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 2 * of the License, or (at your option) any later version. * This program 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package org.gudy.azureus2.ui.swt; import java.util.*; import com.aelitis.azureus.ui.UIFunctions; import com.aelitis.azureus.ui.UIFunctionsManager; import com.aelitis.azureus.ui.UIStatusTextClickListener; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.MessageBox; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.internat.MessageText; import org.gudy.azureus2.core3.logging.*; import org.gudy.azureus2.ui.swt.mainwindow.SWTThread; import org.gudy.azureus2.ui.swt.shells.MessageSlideShell; import org.gudy.azureus2.core3.util.*; /** * Utility methods to display popup window * * TODO: Finish up moving from LGLogger to Logger/LogAlert. ie alert_queue * could store LogAlert instead of an object array. */ public class Alerts { private static List alert_queue = new ArrayList(); private static AEMonitor alert_queue_mon = new AEMonitor("Alerts:Q"); private static List alert_history = new ArrayList(); private static AEMonitor alert_history_mon = new AEMonitor("Alerts:H"); private static boolean initialisation_complete = false; private static boolean has_unshown_messages = false; private static transient boolean stopping; private static List listeners = new ArrayList(); private Alerts() { } private static void showWarningMessageBox(Object[] relatedTo, String message) { showMessageBoxUsingResourceString(relatedTo, SWT.ICON_WARNING, "AlertMessageBox.warning", message); } private static void showMessageBoxUsingResourceString(Object[] relatedTo, int type, String key, String message) { showMessageBox(relatedTo, type, MessageText.getString(key), message, null); } // All ShowMessageBox* functions should end up here.. private static void showMessageBox(Object[] relatedTo, final int type, String title, String message, String details) { final Display display = SWTThread.getInstance().getDisplay(); if (stopping || display.isDisposed()) { try { alert_queue_mon.enter(); List close_alerts = COConfigurationManager.getListParameter( "Alerts.raised.at.close", new ArrayList()); Map alert_map = new HashMap(); alert_map.put("type", new Long(type)); alert_map.put("title", title); alert_map.put("message", message); if (details != null) { alert_map.put("details", details); } close_alerts.add(alert_map); COConfigurationManager.setParameter("Alerts.raised.at.close", close_alerts); return; } finally { alert_queue_mon.exit(); } } if (display.isDisposed()) { return; } final String message2; if (message != null && COConfigurationManager.getBooleanParameter("Show Timestamp For Alerts")) { message2 = "[" + DisplayFormatters.formatDateShort(SystemTime.getCurrentTime()) + "] " + message; } else { message2 = (message == null) ? "" : message; } boolean suppress_popups = COConfigurationManager.getBooleanParameter("Suppress Alerts"); boolean use_message_box = COConfigurationManager.getBooleanParameter("Use Message Box For Popups"); // We'll add the message to the list and then force it to be displayed if necessary. MessageSlideShell.recordMessage(type, title, message2 == null ? "" : message2, details, relatedTo); for (Iterator iter = listeners.iterator(); iter.hasNext();) { AlertListener l = (AlertListener) iter.next(); if (!l.allowPopup(relatedTo, type)) { suppress_popups = true; return; } } if (suppress_popups) { try { alert_queue_mon.enter(); if (!has_unshown_messages) { final UIFunctions ui_functions = UIFunctionsManager.getUIFunctions(); if (ui_functions != null) { ui_functions.setStatusText(UIFunctions.STATUSICON_WARNING, MessageText.getString("AlertMessageBox.unread"), new UIStatusTextClickListener() { public void UIStatusTextClicked() { MessageSlideShell.displayLastMessage(display, true); ui_functions.setStatusText(""); has_unshown_messages = false; } }); has_unshown_messages = true; } } return; } finally { alert_queue_mon.exit(); } } else if (!use_message_box) { MessageSlideShell.displayLastMessage(display, true); } else { /** * I don't like displaying dialog boxes with titles like "Information" and "Error". * So if we are going to be displaying those message titles, then just revert back * to something like "Azureus" (sounds good to me!). */ String amb_key_suffix; switch (type) { case SWT.ICON_ERROR: amb_key_suffix = "error"; break; case SWT.ICON_INFORMATION: amb_key_suffix = "information"; break; case SWT.ICON_WARNING: amb_key_suffix = "warning"; break; default: amb_key_suffix = null; break; } final String title2; if (amb_key_suffix != null && title.equals(MessageText.getString("AlertMessageBox." + amb_key_suffix))) { title2 = Constants.AZUREUS_NAME; } else { title2 = title; } display.asyncExec(new AERunnable() { public void runSupport() { // XXX: Not sure whether findAnyShell is the best thing to use here... Shell s = Utils.findAnyShell(); if (s == null) { return; } MessageBox mb = new MessageBox(s, type | SWT.OK); mb.setText(title2); mb.setMessage(MessageSlideShell.stripOutHyperlinks(message2)); mb.open(); } }); } // end else } // end method public static void showErrorMessageBoxUsingResourceString(Object[] relatedTo, String title_key, Throwable error) { showErrorMessageBox(relatedTo, MessageText.getString(title_key), error); } private static void showErrorMessageBox(Object[] relatedTo, String message, Throwable error) { String error_message = Debug.getStackTrace(error); showMessageBox(relatedTo, SWT.ICON_ERROR, MessageText.getString("AlertMessageBox.error"), message + "\n" + Debug.getExceptionMessage(error), error_message); } private static void showErrorMessageBox(Object[] relatedTo, String message) { showMessageBoxUsingResourceString(relatedTo, SWT.ICON_ERROR, "AlertMessageBox.error", message); } private static void showCommentMessageBox(Object[] relatedTo, String message) { showMessageBoxUsingResourceString(relatedTo, SWT.ICON_INFORMATION, "AlertMessageBox.information", message); } /** * @param alert * * @since 3.0.0.9 */ protected static void showAlert(LogAlert alert) { String key = (alert.err == null) ? alert.text : alert.text + ":" + alert.err.toString(); try { alert_history_mon.enter(); if (!alert.repeatable) { if (alert_history.contains(key)) { return; } alert_history.add(key); if (alert_history.size() > 512) { alert_history.remove(0); } } } finally { alert_history_mon.exit(); } if (alert.err == null) { if (alert.entryType == LogAlert.AT_INFORMATION) { showCommentMessageBox(alert.relatedTo, alert.text); } else if (alert.entryType == LogAlert.AT_WARNING) { showWarningMessageBox(alert.relatedTo, alert.text); } else { showErrorMessageBox(alert.relatedTo, alert.text); } } else { showErrorMessageBox(alert.relatedTo, alert.text, alert.err); } } public static void initComplete() { new AEThread("Init Complete") { public void runSupport() { try { alert_queue_mon.enter(); initialisation_complete = true; for (int i = 0; i < alert_queue.size(); i++) { LogAlert alert = (LogAlert) alert_queue.get(i); showAlert(alert); } List close_alerts = COConfigurationManager.getListParameter( "Alerts.raised.at.close", new ArrayList()); if (close_alerts.size() > 0) { COConfigurationManager.setParameter("Alerts.raised.at.close", new ArrayList()); String intro = MessageText.getString("alert.raised.at.close") + "\n"; for (int i = 0; i < close_alerts.size(); i++) { try { Map alert_map = (Map) close_alerts.get(i); byte[] details = (byte[]) alert_map.get("details"); showMessageBox(null, ((Long) alert_map.get("type")).intValue(), new String((byte[]) alert_map.get("title")), intro + new String((byte[]) alert_map.get("message")), details == null ? null : new String(details)); } catch (Throwable e) { Debug.printStackTrace(e); } } } alert_queue.clear(); } finally { alert_queue_mon.exit(); } } }.start(); } public static void stopInitiated() { stopping = true; } public static void init() { Logger.addListener(new ILogAlertListener() { /* (non-Javadoc) * @see org.gudy.azureus2.core3.logging.ILogAlertListener#alertRaised(org.gudy.azureus2.core3.logging.LogAlert) */ public void alertRaised(LogAlert alert) { if (!initialisation_complete) { try { alert_queue_mon.enter(); alert_queue.add(alert); } finally { alert_queue_mon.exit(); } return; } showAlert(alert); } }); } public static void addListener(AlertListener l) { listeners .add(l); } public static interface AlertListener { public boolean allowPopup(Object[] relatedObjects, int configID); } }