edu.udo.scaffoldhunter.gui.GUIController.java Source code

Java tutorial

Introduction

Here is the source code for edu.udo.scaffoldhunter.gui.GUIController.java

Source

/*
 * Scaffold Hunter
 * Copyright (C) 2006-2008 PG504
 * Copyright (C) 2010-2011 PG552
 * See README.txt in the root directory of the Scaffold Hunter source tree
 * for details.
 *
 * Scaffold Hunter 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 3 of the License, or
 * (at your option) any later version.
 *
 * Scaffold Hunter 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, see <http://www.gnu.org/licenses/>.
 */

package edu.udo.scaffoldhunter.gui;

import static edu.udo.scaffoldhunter.util.I18n._;

import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.FormLayout;

import edu.udo.scaffoldhunter.data.ConnectionData;
import edu.udo.scaffoldhunter.data.ConnectionDataManager;
import edu.udo.scaffoldhunter.gui.dialogs.AboutDialog;
import edu.udo.scaffoldhunter.gui.dialogs.InitialViewDialog;
import edu.udo.scaffoldhunter.gui.dialogs.ProfileDialog;
import edu.udo.scaffoldhunter.gui.dialogs.SessionDialog;
import edu.udo.scaffoldhunter.gui.dialogs.StartDialog;
import edu.udo.scaffoldhunter.gui.dialogs.StartDialog.Result;
import edu.udo.scaffoldhunter.gui.dialogs.TooltipConfigurationDialog;
import edu.udo.scaffoldhunter.gui.filtering.FilterDialog;
import edu.udo.scaffoldhunter.gui.util.DBExceptionHandler;
import edu.udo.scaffoldhunter.gui.util.DBFunction;
import edu.udo.scaffoldhunter.gui.util.ProgressWorker;
import edu.udo.scaffoldhunter.gui.util.ProgressWorkerUtil;
import edu.udo.scaffoldhunter.gui.util.VoidNullaryDBFunction;
import edu.udo.scaffoldhunter.model.XMLSerialization;
import edu.udo.scaffoldhunter.model.db.DatabaseException;
import edu.udo.scaffoldhunter.model.db.Dataset;
import edu.udo.scaffoldhunter.model.db.DbManager;
import edu.udo.scaffoldhunter.model.db.DbManagerHibernate;
import edu.udo.scaffoldhunter.model.db.Filterset;
import edu.udo.scaffoldhunter.model.db.Profile;
import edu.udo.scaffoldhunter.model.db.Session;
import edu.udo.scaffoldhunter.model.db.Subset;
import edu.udo.scaffoldhunter.model.db.Tree;
import edu.udo.scaffoldhunter.util.I18n;
import edu.udo.scaffoldhunter.util.ProgressAdapter;
import edu.udo.scaffoldhunter.util.StringList;
import edu.udo.scaffoldhunter.view.View;

/**
 * Main controller class, managing main windows and basic user actions.
 * 
 * @author Dominic Sacr
 * @author Thomas Schmitz
 */
public class GUIController {

    private final XMLSerialization xmlSerialization = new XMLSerialization();

    private DbManager db;
    private ConfigManager configManager;
    private GUISession session;

    // profile, sessionTitles and datasets used to call db functions in
    // LoginWorker and use the data later
    private Profile profile;
    private List<String> sessionTitles;
    private List<Dataset> datasets;

    /**
     * Creates the initial main window
     * 
     * @param dataManager
     *            the data manager which is used to access configuration data on
     *            disk
     */
    public void start(final ConnectionDataManager dataManager) {
        class Start implements Runnable {
            @Override
            public void run() {
                final StartDialog startDialog = new StartDialog(GUIController.this, dataManager);
                startDialog.setModal(true);
                // setVisible doc says this works, although it blocks the EDT
                startDialog.setVisible(true);
                Result result = startDialog.getResult();
                if (result.equals(Result.OK) && startDialog.getData() != null) {
                    ConnectionData data = startDialog.getData();
                    final boolean useLastSession = startDialog.getUseLastSession();
                    String dbPassword = data.getDbPassword();
                    // ask for password if no password has been set
                    if (dbPassword == null) {
                        // blocks, nevertheless ok on EDT
                        dbPassword = showPasswordDialog(data);
                    }
                    if (dbPassword != null) {

                        LoginWorker login;

                        if (startDialog.isPasswordChanged())
                            login = new LoginWorker(data.getDbType().getDriverClass(),
                                    data.getDbType().getHibernateDialect(), data.getDbUrl(), data.getDbName(),
                                    data.getDbUsername(), dbPassword, startDialog.getUsername(),
                                    startDialog.getNewPassword(), null);
                        else
                            login = new LoginWorker(data.getDbType().getDriverClass(),
                                    data.getDbType().getHibernateDialect(), data.getDbUrl(), data.getDbName(),
                                    data.getDbUsername(), dbPassword, startDialog.getUsername(), "",
                                    startDialog.getSavedPassword());
                        login.addProgressListener(new ProgressAdapter<Boolean>() {
                            @Override
                            public void finished(Boolean success, boolean cancelled) {
                                if (success != null && success && !cancelled) {
                                    if (startDialog.isPasswordChanged() && startDialog.getSavePassword())
                                        startDialog.saveNewPassword(profile.getPassword());
                                    if (!startDialog.getSavePassword())
                                        startDialog.saveNewPassword(null);
                                    createStartingState(profile, useLastSession);
                                } else {
                                    startDialog.saveNewPassword(null);
                                    SwingUtilities.invokeLater(new Start());
                                }
                            }
                        });
                        ProgressWorkerUtil.executeWithProgressDialog(startDialog, _("Message.Info"),
                                _("Message.Connect"), ModalityType.MODELESS, login);
                    } else {
                        SwingUtilities.invokeLater(new Start());
                    }
                } else if (result.equals(Result.QUIT)) {
                    System.exit(0);
                }
            }
        }

        SwingUtilities.invokeLater(new Start());
    }

    private class LoginWorker extends ProgressWorker<Boolean, Void> {
        private String connectionDriver;
        private String hibernateDialect;
        private String connectionUrl;
        private String connectionSchema;
        private String connectionUsername;
        private String connectionPassword;
        private String username;
        private String newPassword;
        private byte[] savedPassword;

        private boolean getUserAndCheckPassword = true;

        /**
         * @param getUserAndCheckPassword
         *            the checkUserAndPassword to set
         */
        public void setGetUserAndCheckPassword(boolean getUserAndCheckPassword) {
            this.getUserAndCheckPassword = getUserAndCheckPassword;
        }

        /**
         * @param connectionDriver
         * @param hibernateDialect
         * @param connectionUrl
         * @param connectionSchema
         * @param connectionUsername
         * @param connectionPassword
         * @param username
         * @param newPassword
         * @param savedPassword
         */
        public LoginWorker(String connectionDriver, String hibernateDialect, String connectionUrl,
                String connectionSchema, String connectionUsername, String connectionPassword, String username,
                String newPassword, byte[] savedPassword) {
            super();
            this.connectionDriver = connectionDriver;
            this.hibernateDialect = hibernateDialect;
            this.connectionUrl = connectionUrl;
            this.connectionSchema = connectionSchema;
            this.connectionUsername = connectionUsername;
            this.connectionPassword = connectionPassword;
            this.username = username;
            this.newPassword = newPassword;
            this.savedPassword = savedPassword;
        }

        @Override
        protected Boolean doInBackground() throws Exception {
            boolean failed = false;
            try {
                setProgressIndeterminate(true);
                if (db == null || !db.isConnected() || !db.getConnectionDriverClass().equals(connectionDriver)
                        || !db.getHibernateDialect().equals(hibernateDialect)
                        || !db.getConnectionUrl().equals(connectionUrl)
                        || !db.getConnectionUsername().equals(connectionUsername)
                        || !db.getConnectionPassword().equals(connectionPassword)) {
                    db = new DbManagerHibernate(connectionDriver, hibernateDialect, connectionUrl, connectionSchema,
                            connectionUsername, connectionPassword, false, false);
                    if (db.schemaExists()) {
                        if (db.validateSchema())
                            db.initializeSessionFactory();
                        else {
                            int result = JOptionPane.showConfirmDialog(null, _("Message.DbInvalid"),
                                    _("Title.Question"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
                            if (result == JOptionPane.YES_OPTION) {
                                db.createAndExportSchema();
                                db.initializeSessionFactory();
                            } else
                                failed = true;
                        }
                    } else {
                        int result = JOptionPane.showConfirmDialog(null, _("Message.DbNotExisting"),
                                _("Title.Question"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
                        if (result == JOptionPane.YES_OPTION) {
                            db.createAndExportSchema();
                            db.initializeSessionFactory();
                        } else
                            failed = true;
                    }
                }
                if (!failed && getUserAndCheckPassword) {
                    List<String> profiles = db.getAllProfileNames();
                    if (!profiles.contains(username)) {
                        JOptionPane.showMessageDialog(null, I18n.get("Message.UserNotFound"),
                                I18n.get("Title.Error"), JOptionPane.ERROR_MESSAGE);
                        failed = true;
                    } else {
                        profile = db.getProfile(username);

                        boolean check;
                        if (savedPassword != null)
                            check = profile.checkPassword(savedPassword);
                        else
                            check = profile.checkPassword(newPassword);
                        if (!check) {
                            JOptionPane.showMessageDialog(null, I18n.get("Message.PasswordWrong"),
                                    I18n.get("Title.Error"), JOptionPane.ERROR_MESSAGE);
                            failed = true;
                        }
                        sessionTitles = db.getAllSessionTitles(profile);
                        datasets = db.getAllDatasets();
                    }
                }
            } catch (DatabaseException dbex) {
                failed = true;
                JOptionPane.showMessageDialog(null, I18n.get("Message.ConnectionProblems"), I18n.get("Title.Error"),
                        JOptionPane.ERROR_MESSAGE);
            }
            return !failed;
        }
    }

    private class NewSessionWorker extends ProgressWorker<Session, Void> {

        private Profile profile;
        private String sessionTitle;
        private Tree tree;
        private Filterset filterset;

        public NewSessionWorker(Profile profile, String sessionTitle, Tree tree, Filterset filterset) {
            this.profile = profile;
            this.sessionTitle = sessionTitle;
            this.tree = tree;
            this.filterset = filterset;
        }

        @Override
        protected Session doInBackground() throws Exception {
            setProgressIndeterminate(true);

            Session newSession = new Session(profile, sessionTitle, new Date(), tree, null, null);

            Subset root = db.getRootSubset(newSession, filterset);
            newSession.setProfile(profile);
            db.saveAsNew(newSession);
            db.saveAsNew(root);
            newSession.setSubset(root);
            db.saveOrUpdate(newSession);

            return newSession;
        }

    }

    private class LoadSessionWorker extends ProgressWorker<GUISession, Void> {
        private Profile profile;
        private String sessionTitle;
        private java.awt.Window parent;

        public LoadSessionWorker(Profile profile, String sessionTitle, java.awt.Window parent) {
            this.profile = profile;
            this.sessionTitle = sessionTitle;
            this.parent = parent;
        }

        @Override
        protected GUISession doInBackground() throws Exception {
            setProgressIndeterminate(true);

            if (sessionTitle == null) {
                db.loadCurrentSession(profile);
            } else {
                Session newCurrentSession = db.getSession(profile, sessionTitle);
                profile.setCurrentSession(newCurrentSession);
                db.saveOrUpdate(profile);
            }

            final Session dbSession = profile.getCurrentSession();

            if (dbSession != null) {
                dbSession.setLastUsed(new Date());
                db.saveOrUpdate(dbSession);

                String xmlConfig = profile.getConfigData();
                final String xmlSession = dbSession.getSessionData();

                configManager = null;
                session = null;

                if (!Strings.isNullOrEmpty(xmlConfig)) {
                    // try restoring existing config
                    try {
                        configManager = xmlSerialization.configFromXML(GUIController.this, xmlConfig);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        SwingUtilities.invokeAndWait(new Runnable() {
                            @Override
                            public void run() {
                                JOptionPane.showMessageDialog(null, _("ConfigRestoreError.Message"),
                                        _("ConfigRestoreError.Title"), JOptionPane.ERROR_MESSAGE);
                            }
                        });
                    }
                }

                if (configManager == null) {
                    // no existing config, or config failed to load
                    configManager = new ConfigManager(GUIController.this);
                }

                if (!Strings.isNullOrEmpty(xmlSession)) {
                    // try restoring existing session
                    SwingUtilities.invokeAndWait(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                session = xmlSerialization.sessionFromXML(GUIController.this, dbSession,
                                        xmlSession);

                                for (edu.udo.scaffoldhunter.gui.Window w : session.getViewManager().getWindows()) {
                                    w.setVisible(true);
                                }
                            } catch (Exception ex) {
                                ex.printStackTrace();
                                JOptionPane.showMessageDialog(null, _("SessionRestoreError.Message"),
                                        _("SessionRestoreError.Title"), JOptionPane.ERROR_MESSAGE);
                            }
                        }
                    });
                }

                if (session == null) {
                    // no existing session, or session failed to load
                    SwingUtilities.invokeAndWait(new Runnable() {
                        @Override
                        public void run() {
                            session = new GUISession(GUIController.this, dbSession);

                            Subset rootSubset = session.getRootSubset();

                            // create dialog, which asks for initally opened views
                            InitialViewDialog viewDlg = new InitialViewDialog(parent);
                            viewDlg.setModal(true);
                            viewDlg.setVisible(true);
                            viewDlg.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

                            List<View> views = Lists.newArrayList();
                            for (Class<? extends View> viewclass : viewDlg.getSelectedViews()) {
                                views.add(session.getViewManager().createView(viewclass, rootSubset));
                            }
                            createWindow(views);
                        }
                    });
                }
            }

            return session;
        }

    }

    /**
     * Creates the starting state of Scaffoldhunter
     */
    private void createStartingState(Profile profile, boolean useLastSession) {
        // Profile profile = db.getProfile(profileName);
        Session currentSession = null;

        if (useLastSession) {
            LoadSessionWorker loadSession = new LoadSessionWorker(profile, null, null);
            ProgressWorkerUtil.executeWithProgressDialog(null, _("Message.Info"), _("Message.LoadSession"),
                    ModalityType.DOCUMENT_MODAL, loadSession);

            currentSession = profile.getCurrentSession();
        }

        if (currentSession == null) {
            if (!showSessionDialog(profile, null))
                System.exit(0);
            currentSession = profile.getCurrentSession();
        }
    }

    /**
     * Opens the dialog to create a new user profile and creates that user in
     * the database.
     * 
     * @param startDialog
     *            The StartDialog
     * @param dataManager
     * 
     * @return Did the user create a new profile?
     */
    public boolean createNewProfile(StartDialog startDialog, ConnectionDataManager dataManager) {
        final ProfileDialog profileDlg = new ProfileDialog(dataManager);
        profileDlg.setModal(true);
        profileDlg.setVisible(true);

        if (profileDlg.getResult()) {
            ConnectionData data = startDialog.getData();

            String dbPassword = data.getDbPassword();
            // ask for password if no password has been set
            if (dbPassword == null) {
                // blocks, nevertheless ok on EDT
                dbPassword = showPasswordDialog(data);
            }
            if (dbPassword != null) {

                startDialog.setUsername(profileDlg.getUsername());
                startDialog.setNewPassword("");

                LoginWorker login = new LoginWorker(data.getDbType().getDriverClass(),
                        data.getDbType().getHibernateDialect(), data.getDbUrl(), data.getDbName(),
                        data.getDbUsername(), dbPassword, "", "", null);
                login.setGetUserAndCheckPassword(false);
                login.addProgressListener(new ProgressAdapter<Boolean>() {
                    @Override
                    public void finished(Boolean result, boolean cancelled) {
                        final Boolean finalResult = result;
                        final boolean finalCancalled = cancelled;

                        DBExceptionHandler.callDBManager(db, new VoidNullaryDBFunction() {
                            @Override
                            public void voidCall() throws DatabaseException {
                                if (finalResult != null && finalResult && !finalCancalled) {
                                    if (!StringList.containsIgnoreCase(db.getAllProfileNames(),
                                            profileDlg.getUsername())) {
                                        Profile profile = new Profile();
                                        profile.setUsername(profileDlg.getUsername());
                                        profile.setPasswordEncrypted(profileDlg.getPassword());
                                        db.saveAsNew(profile);
                                    } else
                                        JOptionPane.showMessageDialog(profileDlg,
                                                _("EditProfile.AlreadyExisting", profileDlg.getUsername()),
                                                _("Title.Warning"), JOptionPane.WARNING_MESSAGE);
                                }
                            }
                        });
                    }
                });
                ProgressWorkerUtil.executeWithProgressDialog(startDialog, _("Message.Info"), _("Message.Connect"),
                        ModalityType.APPLICATION_MODAL, login);
                return true;
            }
        }
        return false;
    }

    /**
     * Shows the session dialog and loads the selected session.
     * 
     * @param profile
     *            The profile for which the session will be loaded
     * @param owner
     *            The owner of this dialog. If null, a quit button is shown
     *            instead of a cancel button.
     * @return The result of the session dialog
     */
    public boolean showSessionDialog(Profile profile, java.awt.Window owner) {
        SessionDialog sessionDlg = new SessionDialog(db, datasets, profile, sessionTitles, this, owner);
        sessionDlg.setModal(true);
        sessionDlg.setVisible(true);

        if (sessionDlg.getResult()) {
            if (session != null) {
                int result = JOptionPane.showConfirmDialog(owner, _("Sessions.ConfirmSaveMessage"),
                        _("Sessions.ConfirmSaveTitle"), JOptionPane.YES_NO_CANCEL_OPTION,
                        JOptionPane.WARNING_MESSAGE);
                if (result == JOptionPane.CANCEL_OPTION)
                    return false;
                if (result == JOptionPane.YES_OPTION) {
                    saveSession(owner);
                }

                for (Window w : session.getViewManager().getWindows()) {
                    w.destroy();
                }
            }

            LoadSessionWorker loadSession = new LoadSessionWorker(profile, sessionDlg.getSessionTitle(), owner);
            ProgressWorkerUtil.executeWithProgressDialog(null, _("Message.Info"), _("Message.LoadSession"),
                    ModalityType.DOCUMENT_MODAL, loadSession);
            return true;
        } else
            return false;
    }

    /**
     * Saves the current session.
     * 
     * @param parent
     *            the parent Component for modal dialogs
     */
    public void saveSession(Component parent) {
        String xmlConfig = xmlSerialization.configToXML(configManager);
        String xmlSession = xmlSerialization.sessionToXML(session);
        final Session dbSession = session.getDbSession();

        profile.setConfigData(xmlConfig);
        dbSession.setSessionData(xmlSession);

        boolean canBeSaved = DBExceptionHandler.callDBManager(db, new DBFunction<Boolean>() {

            @Override
            public Boolean call() throws DatabaseException {
                return db.canSaveSession(dbSession);
            }
        });
        if (!canBeSaved) {
            JOptionPane.showMessageDialog(parent, _("Sessions.PacketToLargeMessage"),
                    _("Sessions.PacketToLargeTitle"), JOptionPane.ERROR_MESSAGE);
        } else {
            DBExceptionHandler.callDBManager(db, new VoidNullaryDBFunction() {
                @Override
                public void voidCall() throws DatabaseException {
                    db.saveOrUpdate(profile);
                    db.saveOrUpdate(dbSession);
                }
            });
        }
    }

    /**
     * Shows the FilterDialog and creates a new Session with given data and
     * chosen filterset.
     * 
     * @param profile
     *            The profile, the session should be created for
     * @param dataset
     *            The dataset, the session should be created with
     * @param tree
     *            The tree, the session should be created with
     * @param title
     *            The title, the session should be created with
     * @param parent
     *            The parent window for the WorkerDialog
     */
    public void createNewSession(Profile profile, Dataset dataset, Tree tree, String title,
            java.awt.Window parent) {
        FilterDialog filterDlg = new FilterDialog(null, db, profile, dataset, null);
        filterDlg.setModal(true);
        filterDlg.setVisible(true);

        if (filterDlg.getResult()) {
            NewSessionWorker newSession = new NewSessionWorker(profile, title, tree,
                    filterDlg.getSelectedFilterset());
            ProgressWorkerUtil.executeWithProgressDialog(parent, _("Message.Info"), _("Message.NewSession"),
                    ModalityType.APPLICATION_MODAL, newSession);
        }
    }

    /**
     * Shows a password dialog and blocks the current thread until the dialog is
     * closed.
     * 
     * @param data
     *            url, database name and username of this object are displayed
     *            in the dialog
     * 
     * @return the password if the user entered a password and clicked OK, null
     *         otherwise
     */
    private String showPasswordDialog(ConnectionData data) {
        // Build the password panel
        final JPasswordField pwField = new JPasswordField();
        DefaultFormBuilder builder = new DefaultFormBuilder(new FormLayout("left:default, default, 200dlu"));
        builder.append("URL: ", new JLabel(data.getDbUrl()));
        builder.append("Database: ", new JLabel(data.getDbName()));
        builder.append("Username: ", new JLabel(data.getDbUsername()));
        builder.append(pwField, 3);

        // Show a password dialog with a nasty hack to set the focus to the
        // password field.
        // There is no beautiful way of focusing the field:
        // http://bugs.sun.com./bugdatabase/view_bug.do?bug_id=5018574
        // The solution used here is: repeat setFocus using a timer until user
        // pressed key in password field
        // TODO maybe write a class PasswordDialog which sets up the dialog
        // manually, so that we get rid of this hack
        JOptionPane pwPane = new JOptionPane(builder.getPanel(), JOptionPane.PLAIN_MESSAGE,
                JOptionPane.OK_CANCEL_OPTION);
        JDialog pwDialog = pwPane.createDialog("Enter password:");
        final Timer timer = new Timer(1, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                pwField.requestFocusInWindow();
            }
        });
        timer.setRepeats(true);
        timer.start();
        pwField.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyReleased(KeyEvent e) {
            }

            @Override
            public void keyPressed(KeyEvent e) {
                timer.stop();
            }
        });
        pwDialog.setVisible(true);

        // Handle return value
        Object returnValue = pwPane.getValue();
        if (returnValue instanceof Integer) {
            int result = (Integer) returnValue;
            if (result == JOptionPane.OK_OPTION) {
                return new String(pwField.getPassword());
            }
        }
        // User clicked cancel or closed the dialog
        return null;
    }

    /**
     * Creates a new main window with no views.
     * 
     * @return the new window
     */
    public MainWindow createWindow() {
        return createWindow(null);
    }

    /**
     * Creates a new main window.
     * 
     * @param views
     *            the views to be shown in this main window, or null for an
     *            empty window
     * 
     * @return the new window
     */
    public MainWindow createWindow(List<View> views) {
        MainWindow window = session.getViewManager().createMainWindow(session);
        session.getViewManager().addWindow(window);

        if (views != null) {
            for (View view : views) {
                session.getViewManager().addView(view, window);
            }
        }

        window.setVisible(true);

        return window;
    }

    /**
     * Closes a main window.
     * 
     * @param window
     *            the window to be closed
     */
    public void closeWindow(MainWindow window) {
        if (session.getViewManager().getWindows().size() == 1) {
            exit(window);
        } else {
            int result = JOptionPane.showConfirmDialog(window.getFrame(), _("CloseWindow.Message"),
                    _("CloseWindow.Title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

            if (result == JOptionPane.YES_OPTION) {
                session.getViewManager().removeWindow(window);
            }
        }
    }

    /**
     * Exits the program.
     * 
     * @param window
     *            the window from which the exit was initiated
     */
    public void exit(MainWindow window) {
        int result = JOptionPane.showConfirmDialog(window.getFrame(), _("Sessions.ConfirmSaveMessage"),
                _("Sessions.ConfirmSaveTitle"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);

        switch (result) {
        case JOptionPane.YES_OPTION:
            saveSession(window.getFrame());
            System.exit(0);
            break;
        case JOptionPane.NO_OPTION:
            System.exit(0);
            break;
        case JOptionPane.CANCEL_OPTION:
            break;
        }
    }

    /**
     * Shows the config dialog for all views of the given main window.
     * 
     * @param window
     */
    public void showOptionsDialog(MainWindow window) {
        configManager.showOptionsDialog(window.getFrame(), session.getViewManager().getViews(window),
                window.getActiveView());
    }

    /**
     * Shows the global config dialog for all views of all frames
     * 
     * @param window
     *            the parent window of the dialog
     */
    public void showGlobalOptionsDialog(MainWindow window) {
        List<View> views = new LinkedList<View>();
        for (View view : session.getViewManager().getAllViews()) {
            views.add(view);
        }
        configManager.showGlobalOptionsDialog(window.getFrame(), views, window.getActiveView());
    }

    /**
     * Shows the tooltip configuration dialog
     * 
     * @param window
     *            the parent window of the dialog
     */
    public void showTooltipDialog(MainWindow window) {
        TooltipConfigurationDialog dialog = new TooltipConfigurationDialog(window.getFrame(),
                session.getDbSession().getDataset(), configManager.getGlobalConfig());

        dialog.setVisible(true);
        configManager.updateGlobalConfig(session.getViewManager().getAllViews());
    }

    /**
     * Shows the about dialog.
     * 
     * @param window
     *            the dialog's parent window
     */
    public void showAboutDialog(MainWindow window) {
        AboutDialog dlg = new AboutDialog(window.getFrame());
        dlg.setVisible(true);
    }

    /**
     * @return the DB manager
     */
    public DbManager getDbManager() {
        return db;
    }

    /**
     * @return the config manager
     */
    public ConfigManager getConfigManager() {
        return configManager;
    }

    /**
     * @return the current session
     */
    public GUISession getCurrentSession() {
        return session;
    }

}