/** Updates {@link #labelAppVersion} with current verson information */ private void updateLabelAppVersion() { if (Version.isUpdateAvailable() == null) { if (ConfigurationFactory.getConfigurationFactory().getConfiguration().checkForUpdates()) { labelAppVersion.setToolTipText("Could not get version information."); } } else { if (Version.isUpdateAvailable()) { labelAppVersion.setForeground(SharedStyle.COLOR_RED); labelAppVersion.setText(Version.VERSION_NUMBER + " (Update Available!)"); labelAppVersion.setToolTipText("Click to go to update " + "download page"); labelAppVersion.setCursor(SharedStyle.CURSOR_HAND); labelAppVersion.addMouseListener( new MouseAdapter() { @Override public void mouseUp(final MouseEvent event) { Program.launch(Version.DOWNLOAD_URL); shell.dispose(); } }); } else { labelAppVersion.setText(Version.VERSION_NUMBER); labelAppVersion.setToolTipText("Latest available version!"); labelAppVersion.setForeground(SharedStyle.COLOR_GREEN); } } }
/** * {@link MainMenu} - SWT implementation * * @author Tomas Varaneckas * @version $Id$ */ public class MainMenu { /** Singleton instance */ private static MainMenu instance = null; /** SWT Menu object */ private final Menu menu; /** Marks that menu is reloading */ private boolean isReloading; /** Is icon reload enqueued after changing display theme? */ private boolean isIconReloadEnqueued = false; /** Unix timestamp since when menu was hidden. Used for enhancing the reloading performance. */ private static long hiddenSince; /** Instance of configuration */ private Configuration cfg = ConfigurationFactory.getConfigurationFactory().getConfiguration(); /** Initializing singleton constructor */ private MainMenu() { menu = new Menu(TrayManager.getInstance().getShell(), SWT.POP_UP); menu.addListener( SWT.Hide, new Listener() { public void handleEvent(final Event event) { new Thread( new Runnable() { public void run() { if (!menu.isDisposed()) { menu.getDisplay() .asyncExec( new Runnable() { public void run() { try { Thread.sleep(10l); hiddenSince = System.currentTimeMillis(); } catch (InterruptedException e) { log.warn("Could not sleep", e); } if (!(state instanceof MenuClosedState)) { setState(MenuClosedState.getInstance()); } } }); } } }) .start(); } }); } /** * Singleton instance getter * * @return instance of SWTMainMenu */ public static MainMenu getInstance() { if (instance == null) { instance = new MainMenu(); } return instance; } public void clearMenu() { for (org.eclipse.swt.widgets.MenuItem item : menu.getItems()) { if (!item.isDisposed()) { item.dispose(); } } if (isIconReloadEnqueued) { IconFactory.getInstance().cleanup(); IconFactory.getInstance().loadResources(); isIconReloadEnqueued = false; } } public void forceHide() { hiddenSince = System.currentTimeMillis(); setState(MenuClosedState.getInstance()); if (!menu.isDisposed()) { menu.setVisible(false); } } public void showMenu(final int x, final int y) { hiddenSince = 0L; menu.setLocation(x, y); menu.setVisible(true); } public void addMenuItem(final com.varaneckas.hawkscope.menu.MenuItem item) { item.createMenuItem(menu); } public Menu getSwtMenuObject() { return menu; } public void addSeparator() { new org.eclipse.swt.widgets.MenuItem(menu, SWT.SEPARATOR); } public void setHiddenSince(final long timestamp) { hiddenSince = timestamp; } public void reloadMenu(final boolean canWait) { if (!canWait && log.isDebugEnabled()) { log.debug("Forcing menu reload now."); } if (!isReloading || !canWait) { isReloading = true; new Thread( new Runnable() { public void run() { try { if (canWait) { Thread.sleep( ConfigurationFactory.getConfigurationFactory() .getConfiguration() .getMenuReloadDelay()); } } catch (final InterruptedException e1) { log.warn("Could not sleep", e1); } doReload(canWait); } }) .start(); } } /** Does the actual reload of Main Menu */ private void doReload(final boolean canWait) { if (menu.getDisplay().isDisposed()) { log.warn("Menu disposed - won't reload"); return; } menu.getDisplay() .asyncExec( new Runnable() { public void run() { try { if (canWait) { if (hiddenSince == -1) { log.debug("Skipping planned reload as it was forced a while ago."); return; } if (hiddenSince == 0L) { log.debug("Menu now open, reload skipped"); isReloading = false; return; } else if (System.currentTimeMillis() - hiddenSince < cfg.getMenuReloadDelay()) { // menu is actively used, try reloading later if (log.isDebugEnabled()) { log.debug( "Reloading later, menu is not sleeping " + "long enough: (" + ((System.currentTimeMillis() - hiddenSince) / 1000.0) + " seconds)"); } isReloading = false; reloadMenu(true); return; } } else { // way of telling other reloader threads to stay the f*** away :) hiddenSince = -1; } clearMenu(); loadMenu(); Runtime.getRuntime().gc(); } catch (final Exception e) { log.debug("Failed reloading menu", e); } isReloading = false; hiddenSince = System.currentTimeMillis(); enqueueIdleReload(); } }); } /** Enqueues idle reload */ private void enqueueIdleReload() { if (isReloading) { log.warn("Can't enqueue idle reload on a reloading menu"); return; } new Thread( new Runnable() { public void run() { try { // sleep at least 3 minutes Thread.sleep(Math.max(cfg.getMenuReloadDelay(), 180000)); if (!isReloading) { log.debug("Idle reload."); doReload(true); } else { log.debug("Idle reload cancelled"); } } catch (final InterruptedException e) { log.warn("Idle reload interrupted", e); } } }) .start(); } /** Current menu state */ protected State state = MenuClosedState.getInstance(); /** Logger */ protected Log log = LogFactory.getLog(getClass()); /** Root partitions */ protected List<File> roots = OSUtils.getFileSystemRoots(); /** * Gets current {@link State} * * @return current state */ public State getState() { return state; } /** * Sets menu {@link State} * * @param state new state */ public void setState(final State state) { if (!this.state.equals(state)) { this.state = state; state.init(); } } /** Loads the menu */ public void loadMenu() { PluginManager.getInstance().beforeQuickAccess(this); loadQuickAccessMenu(); boolean addSeparator = false; for (final File root : roots) { if (cfg.getBlackList().contains(root)) { continue; } if (cfg.isFloppyDrivesDisplayed() || !PathUtils.isFloppy(root)) { if (log.isDebugEnabled()) { log.debug("Generating menu for: " + root.getAbsolutePath()); } final FolderMenu item = MenuFactory.newFolderMenu(root); item.setText(PathUtils.getFileName(root)); item.setIcon(IconFactory.getInstance().getIcon(root)); addMenuItem(item); addSeparator = true; } } if (addSeparator) { addSeparator(); } addStaticItems(); reloadRoots(); } /** Lazy reload of root partitions */ protected void reloadRoots() { log.debug("Performing root partition listing"); roots = OSUtils.getFileSystemRoots(); log.debug("Root partition listing complete"); } /** Loads quick access menu */ private void loadQuickAccessMenu() { final List<File> quick = cfg.getQuickAccessList(); if (quick != null && quick.size() > 0) { final List<String> quickRaw = cfg.getRawQuickAccessList(); final Map<String, String> qaNames = cfg.getQuickAccessNames(); for (int i = 0; i < quick.size(); i++) { File custom = quick.get(i); String customEntry = quickRaw.get(i); try { final FolderMenu fm = MenuFactory.newFolderMenu(custom); if (qaNames.containsKey(customEntry)) { fm.setText(qaNames.get(customEntry)); } PluginManager.getInstance().enhanceQuickAccessItem(fm, custom); addMenuItem(fm); } catch (final Exception e) { log.warn("Skipping unloadable Quick Access List item", e); } } addSeparator(); } } /** Adds static menu items */ private void addStaticItems() { if (cfg.checkForUpdates()) { if (Version.isUpdateAvailable() != null && Version.isUpdateAvailable()) { addExecutableMenuItem( "update", "Update Available! (" + Version.VERSION_NUMBER + " to " + Version.updateVersion + ")", new UpdateCommand(Version.DOWNLOAD_URL)); } for (final Entry<String, String> plugUp : PluginManager.getInstance().getAvailableUpdates().entrySet()) { addExecutableMenuItem( "update", "Plugin Update! (" + plugUp.getKey() + " " + plugUp.getValue() + ")", new UpdateCommand(Version.PLUGINS_URL)); } } addExecutableMenuItem("hide", "Hide", new HideCommand()); PluginManager.getInstance().beforeAboutMenuItem(this); addExecutableMenuItem("about", "About", new AboutCommand()); addExecutableMenuItem("settings", "Settings", new SettingsCommand()); addExecutableMenuItem("help", "Help", new HelpCommand()); addExecutableMenuItem("exit", "Exit", new ExitCommand()); } /** * Adds an executable menu item * * @param name Item name * @param text Text on menu item * @param command Command to execute */ public void addExecutableMenuItem(final String name, final String text, final Command command) { final ExecutableMenuItem item = MenuFactory.newExecutableMenuItem(); item.setCommand(command); item.setText(text); item.setIcon(IconFactory.getInstance().getIcon(name)); addMenuItem(item); } /** Enqueues icons reload */ public void enqueueIconsReload() { isIconReloadEnqueued = true; } }