package org.korsakow.ide.ui.controller.action;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Collection;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.KeyStroke;
import org.apache.log4j.Logger;
import org.dsrg.soenea.domain.MapperException;
import org.korsakow.domain.interf.IProject;
import org.korsakow.domain.mapper.input.ProjectInputMapper;
import org.korsakow.eawt.ApplicationEvent;
import org.korsakow.ide.Application;
import org.korsakow.ide.DataRegistry;
import org.korsakow.ide.lang.LanguageBundle;
import org.korsakow.ide.ui.ResourceEditor;
import org.korsakow.ide.ui.dialogs.UnsavedChangesDialog;
import org.korsakow.ide.ui.dialogs.UnsavedChangesDialog.Result;
import org.korsakow.ide.util.StrongReference;
import org.korsakow.ide.util.UIUtil;
public class ExitAction implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
Application.getInstance().shutdown();
}
public void handleQuit(ApplicationEvent event)
{
if (!Application.getInstance().shutdown())
event.cancel();
}
/**
* Checks if the current version is up to date or not.
* If not (ie unsaved changes) then the user is prompted about saving work.
*
* @return whether it is OK to unload the current project
* @throws MapperException
*/
public static boolean checkForChangesAndPrompt() throws MapperException
{
Application app = Application.getInstance();
Logger.getLogger(ExitAction.class).debug("ExitAction.checkForChangedAndPrompt; disk version="+app.getSaveVersion()+"; mem version="+DataRegistry.getHeadVersion());
if (haveOpenEditors() || haveUnsavedChanged()) {
IProject project = ProjectInputMapper.find();
UnsavedChangesDialog.Result result = showUnsavedChangesDialog(project!=null?project.getName():"");
switch (result) {
case DONTSAVE:
closeOpenEditors();
return true;
case CANCEL:
return false;
case SAVE:
closeOpenEditors();
new SaveProjectAction().performAction();
// give exit sound a chance to play...
try { Thread.sleep(1000); } catch (InterruptedException e) {}
return true;
}
}
return true;
}
private static UnsavedChangesDialog.Result showUnsavedChangesDialog(String projectName) {
final UnsavedChangesDialog pane = new UnsavedChangesDialog(LanguageBundle.getString("confirmexitdialog.message", projectName));
final JDialog dialog = new JDialog(Application.getInstance().getProjectExplorer());
dialog.setBackground(dialog.getBackground().darker());
dialog.getContentPane().setLayout(new BorderLayout());
dialog.getContentPane().add(pane);
dialog.setModal(true);
dialog.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
dialog.getRootPane().getActionMap().put("escape", new AbstractAction() {
@Override
public void actionPerformed( ActionEvent event ) {
dialog.setVisible( false );
}
});
dialog.getRootPane().setDefaultButton(pane.getCancelButton());
dialog.pack();
dialog.setSize(400, 150);
UIUtil.centerOnFrame(dialog, Application.getInstance().getProjectExplorer());
final StrongReference<UnsavedChangesDialog.Result> result = new StrongReference<UnsavedChangesDialog.Result>();
pane.addResultActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
result.set(pane.getResult());
}
});
dialog.setVisible(true);
if ( result.isNull() )
result.set( Result.CANCEL );
return result.get();
}
private static boolean haveUnsavedChanged()
{
Application app = Application.getInstance();
boolean haveChanges = app.getSaveVersion() != DataRegistry.getHeadVersion();
return haveChanges;
}
private static boolean haveOpenEditors()
{
Application app = Application.getInstance();
Collection<ResourceEditor> openEditors = app.getOpenEditors();
return !openEditors.isEmpty();
}
private static void closeOpenEditors()
{
Application app = Application.getInstance();
Collection<ResourceEditor> openEditors = app.getOpenEditors();
for (ResourceEditor editor : openEditors) {
UIUtil.closeWindow(editor);
}
}
}