Author: echatellier Date: 2009-11-13 19:05:35 +0100 (Fri, 13 Nov 2009) New Revision: 2691 Added: trunk/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog.properties trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog_fr.properties trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/alert.png trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/go-jump.png trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/go-next.png trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/process-stop.png Removed: trunk/src/main/resources/org/chorem/jtimer/ui/resources/jtimer-logo-bleu-little.jpg Modified: trunk/src/main/java/org/chorem/jtimer/JTimer.java trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java trunk/src/main/resources/org/chorem/jtimer/resources/JTimer.properties trunk/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties Log: Modify idle frame (now multi tasks support, beautiful icons :-)...) Modified: trunk/src/main/java/org/chorem/jtimer/JTimer.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/JTimer.java 2009-11-13 18:04:45 UTC (rev 2690) +++ trunk/src/main/java/org/chorem/jtimer/JTimer.java 2009-11-13 18:05:35 UTC (rev 2691) @@ -59,6 +59,7 @@ import org.chorem.jtimer.ui.alert.AlertEditor; import org.chorem.jtimer.ui.report.ReportView; import org.chorem.jtimer.ui.systray.SystrayManager; +import org.chorem.jtimer.ui.tasks.IdleDialog; import org.chorem.jtimer.ui.tasks.RefreshTreeTask; import org.chorem.jtimer.ui.tasks.RunTaskJob; import org.chorem.jtimer.ui.treetable.ProjectsAndTasksTable; @@ -168,6 +169,8 @@ // Systray mgr systrayManager = new SystrayManager(this); core.getData().addDataEventListener(systrayManager); + + IdleDialog.init(this); } /** @@ -1103,59 +1106,6 @@ } /** - * Ask user what to do in idle case. - * - * @return chosen option - */ - public int askIdleOption() { - - int option; - - String[] dialogOption = new String[] { - resourceMap.getString("idleDetect.askOptionResume"), - resourceMap.getString("idleDetect.askOptionContinue"), - resourceMap.getString("idleDetect.askOptionRevert") }; - - // get instance for current locale - DateFormat formatter = DateFormat.getTimeInstance(DateFormat.SHORT); - - // calculate idle date - Date idleDate = new Date(); - idleDate.setTime(System.currentTimeMillis() - - JTimerFactory.getIdleTime()); - - // build complete message - // and replace vars - String title = resourceMap.getString("idleDetect.askTitle"); - String message = resourceMap.getString("idleDetect.askMessage", - Long.valueOf(JTimerFactory.getIdleTime() / (60 * 1000)), formatter - .format(idleDate)); - - int answer = JOptionPane.showOptionDialog(getMainFrame(), message, - title, JOptionPane.DEFAULT_OPTION, - JOptionPane.QUESTION_MESSAGE, null, dialogOption, - dialogOption[0]); - - if (log.isDebugEnabled()) { - log.debug("Answer for idle response = " + answer); - } - - switch (answer) { - case 0: - option = RunTaskJob.RESUME; - break; - case 1: - option = RunTaskJob.CONTINUE; - break; - default: - option = RunTaskJob.REVERT; - break; - } - - return option; - } - - /** * Get action for named component. * * Util method. Added: trunk/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java (rev 0) +++ trunk/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java 2009-11-13 18:05:35 UTC (rev 2691) @@ -0,0 +1,244 @@ +/* *##% + * Copyright (C) 2009 Code Lutin, Chatellier Eric + * + * 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. + *##%*/ + +package org.chorem.jtimer.ui.tasks; + +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JSeparator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.jtimer.JTimerFactory; +import org.jdesktop.application.Action; +import org.jdesktop.application.ApplicationContext; +import org.jdesktop.application.ResourceManager; +import org.jdesktop.application.ResourceMap; +import org.jdesktop.application.SingleFrameApplication; + +/** + * Idle dialog showed to user when idle has been detected. + * + * Composed of an unique blocking show method. + * + * Also composed of three resume option : + * <ul> + * <li>Stop task + * <li>Continue (with idle time summed) + * <li>Resume (without idle time summed) + * </ul> + * + * @author chatellier + * @version $Revision$ + * + * Last update : $Date$ + * By : $Author$ + */ +public class IdleDialog extends JDialog { + + /** serialVersionUID. */ + private static final long serialVersionUID = 7669429291708466753L; + + /** log */ + private static Log log = LogFactory.getLog(IdleDialog.class); + + protected SingleFrameApplication application; + + protected ResourceMap resourceMap; + + protected static IdleDialog mutex; + + protected static int lastResumeOption; + + protected JLabel idleDurationLabel; + + /** Option after idle detect */ + public static final int REVERT = 0; + /** Option after idle detect */ + public static final int CONTINUE = 1; + /** Option after idle detect */ + public static final int RESUME = 2; + + /** + * IdleDialog constructor. + * + * Protected to force use of show static method. + * + * @param parent parent application + */ + protected IdleDialog(SingleFrameApplication application) { + super(application.getMainFrame()); + + // init resources map + this.application = application; + ApplicationContext ctxt = application.getContext(); + ResourceManager mgr = ctxt.getResourceManager(); + resourceMap = mgr.getResourceMap(IdleDialog.class); + + //setName("idleFrame"); + setTitle(resourceMap.getString("idleTitle")); + setResizable(false); + + // TODO : must be modal , but break mecanism + //setModal(true); + + getRootPane().setLayout(new BorderLayout(1,1)); + getRootPane().add(getMainComponent(), BorderLayout.CENTER); + } + + /** + * Build main component UI. + * + * @return component ui. + */ + private JComponent getMainComponent() { + JPanel mainComponent = new JPanel(new GridBagLayout()); + + // label + JLabel idleIcon = new JLabel(resourceMap.getIcon("idleIcon")); + mainComponent.add(idleIcon, new GridBagConstraints(0, 0, 1, 5, 0, 1, + GridBagConstraints.NORTH, GridBagConstraints.NONE, + new Insets(10, 10, 10, 10), 0, 0)); + + // label + JLabel idleLabel = new JLabel(resourceMap.getString("idleMessage", + Long.valueOf(JTimerFactory.getIdleTime() / (60 * 1000)))); + mainComponent.add(idleLabel, new GridBagConstraints(1, 0, 3, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 0, 0, 3), 0, 0)); + + idleDurationLabel = new JLabel(" "); + mainComponent.add(idleDurationLabel, new GridBagConstraints(1, 1, 3, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 0, 5, 5), 0, 0)); + + // separator + mainComponent.add(new JSeparator(), new GridBagConstraints(1, 2, 3, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 5), 0, 0)); + + // label + JLabel idleRestart = new JLabel(resourceMap.getString("idleRestart")); + mainComponent.add(idleRestart, new GridBagConstraints(1, 3, 3, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 0, 0, 3), 0, 0)); + + JButton revertButton = new JButton(); + revertButton.setHorizontalAlignment(JLabel.LEFT); + revertButton.setAction(application.getContext().getActionMap(this).get("chooseRevertOption")); + mainComponent.add(revertButton, new GridBagConstraints(1, 4, 1, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 0, 5, 5), 0, 0)); + + JButton continueButton = new JButton(); + continueButton.setHorizontalAlignment(JLabel.LEFT); + continueButton.setAction(application.getContext().getActionMap(this).get("chooseContinueOption")); + mainComponent.add(continueButton, new GridBagConstraints(2, 4, 1, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 0, 5, 5), 0, 0)); + + JButton resumeButton = new JButton(); + resumeButton.setHorizontalAlignment(JLabel.LEFT); + resumeButton.setAction(application.getContext().getActionMap(this).get("chooseResumeOption")); + mainComponent.add(resumeButton, new GridBagConstraints(3, 4, 1, 1, 1, 0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(5, 0, 5, 5), 0, 0)); + + return mainComponent; + } + + public void run () { + idleDurationLabel.setText(resourceMap.getString("idleDuration", + Long.valueOf(JTimerFactory.getIdleTime() / (60 * 1000)))); + } + /** + * Init dialog mutex instance. + * + * @param parent parent reference + */ + public static void init(SingleFrameApplication parent) { + mutex = new IdleDialog(parent); + } + + @Action + public void chooseRevertOption() { + lastResumeOption = REVERT; + idleEnded(); + } + + @Action + public void chooseContinueOption() { + lastResumeOption = CONTINUE; + idleEnded(); + } + + @Action + public void chooseResumeOption() { + lastResumeOption = RESUME; + idleEnded(); + } + + protected void idleEnded() { + synchronized(this) { + notifyAll(); + } + setVisible(false); + } + + protected synchronized void waitForIdleEnd() { + try { + wait(); + log.debug("Thread unwaiting"); + } catch (InterruptedException e) { + if (log.isErrorEnabled()) { + log.error("Thread inturrupted", e); + } + } + } + + /** + * Called function on idle detect. + * + * This function is thread safe and show only one dialog even if + * function is called multiples times. + * + * @param lastActivityTimestamp + * @return idle option + */ + public static int showIdleDialog(long lastActivityTimestamp) { + //synchronized(mutex) { + if (!mutex.isVisible()) { + mutex.application.show(mutex); + mutex.run(); + } + //} + + mutex.waitForIdleEnd(); + + return lastResumeOption; + } +} Property changes on: trunk/src/main/java/org/chorem/jtimer/ui/tasks/IdleDialog.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL" Modified: trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java =================================================================== --- trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java 2009-11-13 18:04:45 UTC (rev 2690) +++ trunk/src/main/java/org/chorem/jtimer/ui/tasks/RunTaskJob.java 2009-11-13 18:05:35 UTC (rev 2691) @@ -91,13 +91,6 @@ /** Want to stop flag */ protected Boolean bWantToStop; - /** Option after idle detect */ - public static final int REVERT = 0; - /** Option after idle detect */ - public static final int CONTINUE = 1; - /** Option after idle detect */ - public static final int RESUME = 2; - /** * Constructor. * @@ -298,7 +291,8 @@ // send idle detect event parentApplication.preIdleDetect(); // ask user what to do - int option = ((JTimer) getApplication()).askIdleOption(); + //int option = ((JTimer) getApplication()).askIdleOption(); + int option = IdleDialog.showIdleDialog(lastPublishTimestamp); // send idle detect event parentApplication.postIdleDetect(); @@ -308,12 +302,12 @@ switch (option) { - case REVERT: + case IdleDialog.REVERT: // just stop the task ((JTimer) getApplication()).stopTask(managedTask); break; - case CONTINUE: + case IdleDialog.CONTINUE: // refresh time // remove idle time previously added offsetTimeInMs += configIdleTime; Modified: trunk/src/main/resources/org/chorem/jtimer/resources/JTimer.properties =================================================================== --- trunk/src/main/resources/org/chorem/jtimer/resources/JTimer.properties 2009-11-13 18:04:45 UTC (rev 2690) +++ trunk/src/main/resources/org/chorem/jtimer/resources/JTimer.properties 2009-11-13 18:05:35 UTC (rev 2691) @@ -144,13 +144,6 @@ vetoable.saver.invalid.task.characters=Task name contains invalid characters ! vetoable.ws.chorem.cant.modify.synchronized.project=Can't do this action on a synchronized project ! -# idle i18n -idleDetect.askTitle = Idle detect -idleDetect.askMessage = You have been idle for %d minutes (%s)\n\nYou may now:\n - revert to back before the idle\n - continue timing, ignoring the idle\n - resume timing from when the idle started -idleDetect.askOptionContinue = Continue -idleDetect.askOptionRevert = Revert -idleDetect.askOptionResume = Resume - #�Start fail i18n startFail.title=Error startFail.message=${Application.title} fail to init.\nCheck that ${Application.title} is not already launched. Modified: trunk/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties =================================================================== --- trunk/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties 2009-11-13 18:04:45 UTC (rev 2690) +++ trunk/src/main/resources/org/chorem/jtimer/resources/JTimer_fr.properties 2009-11-13 18:05:35 UTC (rev 2691) @@ -124,13 +124,6 @@ vetoable.saver.invalid.characters=Le nom contient des caract\u00E8res invalide ! vetoable.ws.chorem.cant.modify.synchronized.project=Impossible d'effectuer cette action sur un projet synchronis\u00E9 ! -# jtimer main class -idleDetect.askTitle = Inactivit\u00E9 d\u00E9tect\u00E9e -idleDetect.askMessage = Vous avez \u00E9t\u00E9 inactif pendant %d minutes (%s)\n\nVous pouvez maintenant :\n - revenir avant l'inactivit\u00E9\n - continuer en ignorant l'inactivit\u00E9\n - reprendre depuis la d\u00E9tection de l'inactivit\u00E9 -idleDetect.askOptionContinue = Continuer -idleDetect.askOptionRevert = Revenir -idleDetect.askOptionResume = Reprendre - #�Start fail i18n startFail.title=Erreur startFail.message=${Application.title} n'a pas r\u00E9ussi \u00E0 s'initiliser.\nV\u00E9rifiez que ${Application.title} n'est pas d\u00E9j\u00E0 lanc\u00E9. \ No newline at end of file Deleted: trunk/src/main/resources/org/chorem/jtimer/ui/resources/jtimer-logo-bleu-little.jpg =================================================================== (Binary files differ) Added: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog.properties =================================================================== --- trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog.properties (rev 0) +++ trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog.properties 2009-11-13 18:05:35 UTC (rev 2691) @@ -0,0 +1,18 @@ +# idle i18n +idleTitle = Idle detect +idleIcon = alert.png +idleMessage = You have been idle for %d minutes. +idleRestart = Choose restart option : +idleDuration = Idle duration : %s + +chooseRevertOption.Action.text=Stop +chooseRevertOption.Action.shortDescription=Stop task without counting elapsed time +chooseRevertOption.Action.icon=process-stop.png + +chooseContinueOption.Action.text=Continue +chooseContinueOption.Action.shortDescription=Continue task counting elapsed time +chooseContinueOption.Action.icon=go-next.png + +chooseResumeOption.Action.text=Resume +chooseResumeOption.Action.shortDescription=Resume task without counting elapsed time +chooseResumeOption.Action.icon=go-jump.png Added: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog_fr.properties =================================================================== --- trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog_fr.properties (rev 0) +++ trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/IdleDialog_fr.properties 2009-11-13 18:05:35 UTC (rev 2691) @@ -0,0 +1,17 @@ +# idle i18n +idleTitle = Inactivit\u00E9 d\u00E9tect\u00E9e +idleMessage = Vous avez \u00E9t\u00E9 inactif pendant %d minutes. +idleRestart = Choisissez une option : +idleDuration = Dur\u00E9e d'inactivit\u00E9 : %s + +chooseRevertOption.Action.text=Stopper +chooseRevertOption.Action.shortDescription=Annuler le temps \u00E9coul\u00E9 et stopper la t\u00E2che +chooseRevertOption.Action.icon=process-stop.png + +chooseContinueOption.Action.text=Continuer +chooseContinueOption.Action.shortDescription=Continuer la t\u00E2che en comptant le temps \u00E9coul\u00E9 +chooseContinueOption.Action.icon=go-next.png + +chooseResumeOption.Action.text=Reprendre +chooseResumeOption.Action.shortDescription=Reprendre la t\u00E2che en ne comptant pas le temps \u00E9coul\u00E9 +chooseResumeOption.Action.icon=go-jump.png Added: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/alert.png =================================================================== (Binary files differ) Property changes on: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/alert.png ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + application/octet-stream Added: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/go-jump.png =================================================================== (Binary files differ) Property changes on: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/go-jump.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/go-next.png =================================================================== (Binary files differ) Property changes on: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/go-next.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/process-stop.png =================================================================== (Binary files differ) Property changes on: trunk/src/main/resources/org/chorem/jtimer/ui/tasks/resources/process-stop.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream