/*
* Copyright PMEase (c) 2005 - 2010,
* Date: Jan 9, 2010 8:38:15 PM
*
* All rights reserved.
*
* Revision: $Id$
*/
package com.pmease.quickbuild.monitor.gui;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.pmease.quickbuild.monitor.BuildHistory;
import com.pmease.quickbuild.monitor.cache.ColorCache;
import com.pmease.quickbuild.monitor.cache.FontCache;
import com.pmease.quickbuild.monitor.cache.ImageCache;
import com.pmease.quickbuild.monitor.event.EventCentral;
import com.pmease.quickbuild.monitor.notifier.BuildFragment;
import com.pmease.quickbuild.monitor.notifier.BuildNotifier;
import com.pmease.quickbuild.monitor.notifier.NotificationHandler;
import com.pmease.quickbuild.monitor.notifier.Notifier;
import com.pmease.quickbuild.monitor.notifier.BuildFragment.Status;
import com.pmease.quickbuild.monitor.notifier.Notifier.NotificationType;
import com.pmease.quickbuild.monitor.utils.SWTUtils;
public class TrayMonitor {
private static final Logger logger = LoggerFactory.getLogger(TrayMonitor.class);
private final Display display;
private Shell shell;
private Tray tray;
private TrayItem trayItem;
private Menu trayMenu;
private MenuManager menuManager;
private EventCentral eventCentral;
public MonitorSetting settings;
public NotificationHandler notificationHandler;
public WindowManager windowManager;
public BuildHistory history;
public boolean hasModalWindow;
private static final String APP_NAME = "QuickBuild Monitor";
/*
public enum Status {
IDLE("idle.png"),
CONNECTION_LOST("connection-failed.png"),
BUILDS_PASSED("green-ball.png"),
BUILDS_FAILED("red-ball.png");
private String iconFile;
Status(String iconFile) {
this.iconFile = iconFile;
}
public String getIconFile() {
return iconFile;
}
}
public Status status = Status.IDLE;
*/
public final File settingDir;
public TrayMonitor(Display display) {
settingDir = getSettingDir();
this.display = display;
this.settings = new MonitorSetting();
this.settings.load(new File(settingDir, "settings.properties"));
this.notificationHandler = new NotificationHandler(this);
this.notificationHandler.start();
create();
this.windowManager = new WindowManager(this);
history = new BuildHistory(this);
}
public File getSettingFile() {
return new File(getSettingDir(), "settings.properties");
}
public File getSettingDir() {
String home = System.getProperty("user.home");
String dirName = ".qbmonitor";
File file = new File(home, dirName);
if (!file.exists()) {
try {
FileUtils.forceMkdir(file);
} catch (IOException e) {
throw new RuntimeException("Unable to create QuickBuild monitor settings directory.");
}
}
return file;
}
private void create() {
shell = createShell();
shell.setVisible(false);
eventCentral = new EventCentral(this);
tray = display.getSystemTray();
trayItem = new TrayItem(tray, SWT.NONE);
trayItem.setToolTipText(APP_NAME);
Image image = ImageCache.getImage("notification-good.png");
trayItem.setImage(image);
menuManager = new MenuManager();
menuManager.add(eventCentral.triggerViewAction);
menuManager.add(eventCentral.pauseResumeAction);
menuManager.add(new Separator());
menuManager.add(eventCentral.viewHistoryAction);
menuManager.add(eventCentral.clearHistoryAction);
menuManager.add(new Separator());
menuManager.add(eventCentral.editPreferenceAction);
menuManager.add(new Separator());
menuManager.add(eventCentral.aboutAction);
menuManager.add(new Separator());
menuManager.add(eventCentral.exitAction);
trayMenu = menuManager.createContextMenu(shell);
trayItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
trayMenu.setVisible(true);
}
});
}
public void clearHistory() {
history.clear();
}
public void updateMenus() {
Display display = shell.getDisplay();
if (display == null || display.isDisposed()) {
return;
}
display.asyncExec(new Runnable() {
public void run() {
MenuItem[] items = trayMenu.getItems();
for (MenuItem each : items) {
String text = each.getText();
if (!text.equalsIgnoreCase("Exit")) {
each.setEnabled(!hasModalWindow);
}
}
}
});
}
public void updateStatus() {
if (shell == null || shell.isDisposed()) {
return;
}
Display display = shell.getDisplay();
if (display == null || display.isDisposed()) {
return;
}
display.asyncExec(new Runnable() {
public void run() {
StringBuffer sb = new StringBuffer(APP_NAME);
sb.append(" (").append(history.size()).append(" messages)");
if (notificationHandler.isConnectionLost()) {
sb.append(" - Disconnected");
} else if (notificationHandler.isPaused()) {
// image = ImageCache.getImage("yellow-ball.png");
sb.append(" - Paused");
// image = ImageCache.getImage(TrayMonitor.this.status.getIconFile());
}
trayItem.setToolTipText(sb.toString());
Status status = history.getStatus();
Image image;
if (notificationHandler.isConnectionLost()) {
image = ImageCache.getImage("notification-disconnected.png");
} else if (notificationHandler.isPaused()) {
image = ImageCache.getImage("notification-paused.png");
} else if (status == Status.SUCCESSFUL) {
image = ImageCache.getImage("notification-good.png");
} else {
image = ImageCache.getImage("notification-error.png");
}
/*
boolean paused = notificationHandler.isPaused();
String str = paused ? "paused-" : "connected-";
switch (status) {
case FAILED:
str = str + "error.png";
break;
case CANCELLED:
str = str + "warn.png";
break;
default:
str = str + "good.png";
break;
}
image = ImageCache.getImage(str);
}
*/
trayItem.setImage(image);
}
});
}
/*
public void setStatus(Status status) {
if (this.status == status) {
return;
} else {
this.status = status;
updateStatus();
}
}
public Status getStatus() {
return this.status;
}
*/
public void showBuildNotification(final BuildFragment build) {
Display display = getDisplay();
display.asyncExec(new Runnable() {
public void run() {
BuildNotifier notifier = new BuildNotifier(TrayMonitor.this, build);
notifier.open();
}
});
}
public void showMessage(final String title, final String msg, final NotificationType type) {
Display display = getDisplay();
display.asyncExec(new Runnable() {
public void run() {
String message = msg;
if (message == null) {
message = "Unknown error!";
}
Notifier notifier = new Notifier(TrayMonitor.this, title, message, type);
notifier.open();
}
});
}
public void showError(final String title, final String msg) {
Display display = getDisplay();
display.asyncExec(new Runnable() {
public void run() {
String message = msg;
if (message == null) {
message = "Unknown error!";
}
Notifier notifier = new Notifier(TrayMonitor.this, title, message, NotificationType.ERROR);
notifier.open();
}
});
}
private Shell createShell() {
Shell shell = new Shell(display, SWT.NO_TRIM);
shell.setText(APP_NAME);
shell.setToolTipText(APP_NAME);
Image image = ImageCache.getImage("logo128.png");
shell.setImage(image);
shell.setSize(new Point(0, 0));
return shell;
}
public int open() {
if (SWTUtils.isDisposed(shell)) {
shell = null;
create();
}
shell.setVisible(false);
// shell.open();
runEventLoop(shell);
return Window.OK;
}
public Shell getShell() {
return shell;
}
public Display getDisplay() {
if (display == null || display.isDisposed()) {
return Display.getCurrent();
}
return display;
}
private void runEventLoop(Shell loopShell) {
Display display;
Shell shell = getShell();
if (shell == null) {
display = Display.getCurrent();
} else {
display = loopShell.getDisplay();
}
while (loopShell != null && !loopShell.isDisposed()) {
try {
if (!display.readAndDispatch()) {
display.sleep();
}
} catch (Exception e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
}
public boolean close() {
ImageCache.dispose();
ColorCache.dispose();
FontCache.dispose();
menuManager.dispose();
menuManager = null;
trayItem.dispose();
trayItem = null;
notificationHandler.shutdown();
if (shell == null || shell.isDisposed()) {
return true;
}
shell.dispose();
shell = null;
settings.save(new File(settingDir, "settings.properties"));
return true;
}
public EventCentral getEventCentral() {
return eventCentral;
}
public void setHasModalWindow(boolean b) {
this.hasModalWindow = b;
updateMenus();
}
}