org.omegat.gui.main.ProjectUICommands.java Source code

Java tutorial

Introduction

Here is the source code for org.omegat.gui.main.ProjectUICommands.java

Source

/**************************************************************************
 OmegaT - Computer Assisted Translation (CAT) tool 
      with fuzzy matching, translation memory, keyword search, 
      glossaries, and translation leveraging into updated projects.
    
 Copyright (C) 2008-2016 Alex Buloichik
           2011 Martin Fleurke
           2012 Thomas Cordonnier
           2013 Yu Tang
           2014 Aaron Madlon-Kay, Piotr Kulik
           2015 Aaron Madlon-Kay, Yu Tang
           Home page: http://www.omegat.org/
           Support center: http://groups.yahoo.com/group/OmegaT/
    
 This file is part of OmegaT.
    
 OmegaT 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.
    
 OmegaT 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 org.omegat.gui.main;

import java.awt.Cursor;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

import org.apache.commons.io.FileUtils;
import org.omegat.convert.ConvertProject;
import org.omegat.core.Core;
import org.omegat.core.CoreEvents;
import org.omegat.core.KnownException;
import org.omegat.core.data.ProjectFactory;
import org.omegat.core.data.ProjectProperties;
import org.omegat.core.events.IProjectEventListener;
import org.omegat.core.segmentation.SRX;
import org.omegat.core.segmentation.Segmenter;
import org.omegat.core.team2.RemoteRepositoryProvider;
import org.omegat.filters2.master.FilterMaster;
import org.omegat.gui.dialogs.ChooseMedProject;
import org.omegat.gui.dialogs.FileCollisionDialog;
import org.omegat.gui.dialogs.NewProjectFileChooser;
import org.omegat.gui.dialogs.NewTeamProject;
import org.omegat.gui.dialogs.ProjectPropertiesDialog;
import org.omegat.util.FileUtil;
import org.omegat.util.FileUtil.ICollisionCallback;
import org.omegat.util.Log;
import org.omegat.util.OConsts;
import org.omegat.util.OStrings;
import org.omegat.util.Preferences;
import org.omegat.util.ProjectFileStorage;
import org.omegat.util.RecentProjects;
import org.omegat.util.StaticUtils;
import org.omegat.util.StringUtil;
import org.omegat.util.WikiGet;
import org.omegat.util.gui.OmegaTFileChooser;
import org.omegat.util.gui.OpenProjectFileChooser;
import org.omegat.util.gui.UIThreadsUtil;

import gen.core.project.RepositoryDefinition;
import gen.core.project.RepositoryMapping;

/**
 * Handler for project UI commands, like open, save, compile, etc.
 * 
 * @author Alex Buloichik (alex73mail@gmail.com)
 * @author Martin Fleurke
 * @author Thomas Cordonnier
 * @author Aaron Madlon-Kay
 */
public class ProjectUICommands {
    public static void projectCreate() {
        UIThreadsUtil.mustBeSwingThread();

        if (Core.getProject().isProjectLoaded()) {
            return;
        }

        // ask for new project dir
        NewProjectFileChooser ndc = new NewProjectFileChooser();
        int ndcResult = ndc.showSaveDialog(Core.getMainWindow().getApplicationFrame());
        if (ndcResult != OmegaTFileChooser.APPROVE_OPTION) {
            // user press 'Cancel' in project creation dialog
            return;
        }
        final File dir = ndc.getSelectedFile();

        new SwingWorker<Object, Void>() {
            protected Object doInBackground() throws Exception {

                dir.mkdirs();

                // ask about new project properties
                ProjectProperties props = new ProjectProperties(dir);
                props.setSourceLanguage(Preferences.getPreferenceDefault(Preferences.SOURCE_LOCALE, "EN-US"));
                props.setTargetLanguage(Preferences.getPreferenceDefault(Preferences.TARGET_LOCALE, "EN-GB"));
                ProjectPropertiesDialog newProjDialog = new ProjectPropertiesDialog(
                        Core.getMainWindow().getApplicationFrame(), props, dir.getAbsolutePath(),
                        ProjectPropertiesDialog.Mode.NEW_PROJECT);
                newProjDialog.setVisible(true);
                newProjDialog.dispose();

                IMainWindow mainWindow = Core.getMainWindow();
                Cursor hourglassCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
                Cursor oldCursor = mainWindow.getCursor();
                mainWindow.setCursor(hourglassCursor);

                final ProjectProperties newProps = newProjDialog.getResult();
                if (newProps == null) {
                    // user clicks on 'Cancel'
                    dir.delete();
                    mainWindow.setCursor(oldCursor);
                    return null;
                }

                final String projectRoot = newProps.getProjectRoot();

                if (!StringUtil.isEmpty(projectRoot)) {
                    // create project
                    try {
                        ProjectFactory.createProject(newProps);
                    } catch (Exception ex) {
                        Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                        Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    }
                }

                RecentProjects.add(dir.getAbsolutePath());

                mainWindow.setCursor(oldCursor);
                return null;
            }
        }.execute();
    }

    public static void projectOpenMED() {
        UIThreadsUtil.mustBeSwingThread();

        if (Core.getProject().isProjectLoaded()) {
            return;
        }

        // ask for MED file
        ChooseMedProject ndm = new ChooseMedProject();
        int ndmResult = ndm.showOpenDialog(Core.getMainWindow().getApplicationFrame());
        if (ndmResult != OmegaTFileChooser.APPROVE_OPTION) {
            // user press 'Cancel' in project creation dialog
            return;
        }
        final File med = ndm.getSelectedFile();

        // ask for new project dir
        NewProjectFileChooser ndc = new NewProjectFileChooser();
        int ndcResult = ndc.showSaveDialog(Core.getMainWindow().getApplicationFrame());
        if (ndcResult != OmegaTFileChooser.APPROVE_OPTION) {
            // user press 'Cancel' in project creation dialog
            return;
        }
        final File dir = ndc.getSelectedFile();

        new SwingWorker<Object, Void>() {
            protected Object doInBackground() throws Exception {
                dir.mkdirs();

                final ProjectProperties newProps = new ProjectProperties(dir);
                ProjectMedProcessing.extractFromMed(med, newProps);
                // create project
                try {
                    ProjectFactory.createProject(newProps);
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }

                RecentProjects.add(dir.getAbsolutePath());

                return null;
            }

            protected void done() {
                try {
                    get();
                    SwingUtilities.invokeLater(Core.getEditor()::requestFocus);
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }
            }
        }.execute();
    }

    public static void projectCreateMED() {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        // ask for new MED file
        ChooseMedProject ndm = new ChooseMedProject();
        // default name
        String zipName = null;
        try {
            File origin = ProjectMedProcessing.getOriginMedFile(Core.getProject().getProjectProperties());
            if (origin != null) {
                zipName = origin.getName();
            }
        } catch (Exception ex) {
        }
        if (zipName == null) {
            zipName = Core.getProject().getProjectProperties().getProjectName() + "-MED.zip";
        }
        ndm.setSelectedFile(
                new File(Core.getProject().getProjectProperties().getProjectRootDir().getParentFile(), zipName));
        int ndmResult = ndm.showSaveDialog(Core.getMainWindow().getApplicationFrame());
        if (ndmResult != OmegaTFileChooser.APPROVE_OPTION) {
            // user press 'Cancel' in project creation dialog
            return;
        }
        // add .zip extension if there is no
        final File med = ndm.getSelectedFile().getName().toLowerCase().endsWith(".zip") ? ndm.getSelectedFile()
                : new File(ndm.getSelectedFile().getAbsolutePath() + ".zip");

        new SwingWorker<Object, Void>() {
            protected Object doInBackground() throws Exception {
                IMainWindow mainWindow = Core.getMainWindow();
                Cursor hourglassCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
                Cursor oldCursor = mainWindow.getCursor();
                mainWindow.setCursor(hourglassCursor);

                mainWindow.showStatusMessageRB("MW_STATUS_SAVING");

                Core.executeExclusively(true, () -> {
                    Core.getProject().saveProject(true);
                    try {
                        Core.getProject().compileProject(".*");
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                });

                ProjectMedProcessing.createMed(med, Core.getProject().getProjectProperties());

                mainWindow.showStatusMessageRB("MW_STATUS_SAVED");
                mainWindow.setCursor(oldCursor);
                return null;
            }

            protected void done() {
                try {
                    get();
                    SwingUtilities.invokeLater(Core.getEditor()::requestFocus);
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }
            }
        }.execute();
    }

    public static void projectTeamCreate() {
        UIThreadsUtil.mustBeSwingThread();

        if (Core.getProject().isProjectLoaded()) {
            return;
        }
        new SwingWorker<Object, Void>() {
            File projectRoot;

            protected Object doInBackground() throws Exception {
                Core.getMainWindow().showStatusMessageRB(null);

                final NewTeamProject dialog = new NewTeamProject(Core.getMainWindow().getApplicationFrame());
                dialog.setVisible(true);

                if (!dialog.ok) {
                    Core.getMainWindow().showStatusMessageRB("TEAM_CANCELLED");
                    return null;
                }

                IMainWindow mainWindow = Core.getMainWindow();
                Cursor hourglassCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
                Cursor oldCursor = mainWindow.getCursor();
                mainWindow.setCursor(hourglassCursor);
                Core.getMainWindow().showStatusMessageRB("CT_DOWNLOADING_PROJECT");

                // retrieve omegat.project
                projectRoot = new File(dialog.getSaveLocation());
                List<RepositoryDefinition> repos = new ArrayList<RepositoryDefinition>();
                RepositoryDefinition repo = new RepositoryDefinition();
                repos.add(repo);
                repo.setType(dialog.getRepoType());
                repo.setUrl(dialog.getRepoUrl());
                RepositoryMapping mapping = new RepositoryMapping();
                mapping.setLocal("");
                mapping.setRepository("");
                repo.getMapping().add(mapping);

                RemoteRepositoryProvider remoteRepositoryProvider = new RemoteRepositoryProvider(projectRoot,
                        repos);
                remoteRepositoryProvider.switchAllToLatest();
                for (String file : new String[] { OConsts.FILE_PROJECT,
                        OConsts.DEFAULT_INTERNAL + '/' + FilterMaster.FILE_FILTERS,
                        OConsts.DEFAULT_INTERNAL + '/' + SRX.CONF_SENTSEG }) {
                    remoteRepositoryProvider.copyFilesFromRepoToProject(file);
                }

                // update repo into
                ProjectProperties props = ProjectFileStorage.loadProjectProperties(projectRoot);
                props.setRepositories(repos);
                ProjectFileStorage.writeProjectFile(props);

                //String projectFileURL = dialog.txtRepositoryOrProjectFileURL.getText();
                //File localDirectory = new File(dialog.txtDirectory.getText());
                //                try {
                //                    localDirectory.mkdirs();
                //                    byte[] projectFile = WikiGet.getURLasByteArray(projectFileURL);
                //                    FileUtils.writeByteArrayToFile(new File(localDirectory, OConsts.FILE_PROJECT), projectFile);
                //                } catch (Exception ex) {
                //                    ex.printStackTrace();
                //                    Core.getMainWindow().displayErrorRB(ex, "TEAM_CHECKOUT_ERROR");
                //                    mainWindow.setCursor(oldCursor);
                //                    return null;
                //                }

                //                projectOpen(localDirectory);

                mainWindow.setCursor(oldCursor);
                return null;
            }

            @Override
            protected void done() {
                Core.getMainWindow().showProgressMessage(" ");
                try {
                    get();
                    if (projectRoot != null) {
                        // don't ask open if user cancelled previous dialog
                        SwingUtilities.invokeLater(() -> {
                            Core.getEditor().requestFocus();
                            projectOpen(projectRoot);
                        });

                    }
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_DOWNLOAD_TEAM_PROJECT");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_DOWNLOAD_TEAM_PROJECT");
                }
            }
        }.execute();
    }

    /**
     * Open project. Does nothing if there is already a project open.
     * Convenience method for {@link #projectOpen(File, boolean)}.
     * 
     * @param projectDirectory
     */
    public static void projectOpen(File projectDirectory) {
        projectOpen(projectDirectory, false);
    }

    /**
     * Open project. Does nothing if a project is already open and closeCurrent is false.
     * 
     * @param projectDirectory
     *            project directory or null if user must choose it
     * @param closeCurrent
     *            whether or not to close the current project first, if any
     */
    public static void projectOpen(final File projectDirectory, boolean closeCurrent) {
        UIThreadsUtil.mustBeSwingThread();

        if (Core.getProject().isProjectLoaded()) {
            if (closeCurrent) {
                // Register to try again after closing the current project.
                CoreEvents.registerProjectChangeListener(new IProjectEventListener() {
                    public void onProjectChanged(PROJECT_CHANGE_TYPE eventType) {
                        if (eventType == PROJECT_CHANGE_TYPE.CLOSE) {
                            projectOpen(projectDirectory, false);
                            CoreEvents.unregisterProjectChangeListener(this);
                        }
                    }
                });
                projectClose();
            }
            return;
        }

        final File projectRootFolder;
        if (projectDirectory == null) {
            // select existing project file - open it
            OmegaTFileChooser pfc = new OpenProjectFileChooser();
            if (OmegaTFileChooser.APPROVE_OPTION != pfc
                    .showOpenDialog(Core.getMainWindow().getApplicationFrame())) {
                return;
            }
            projectRootFolder = pfc.getSelectedFile();
        } else {
            projectRootFolder = projectDirectory;
        }

        new SwingWorker<Object, Void>() {
            protected Object doInBackground() throws Exception {

                IMainWindow mainWindow = Core.getMainWindow();
                Cursor hourglassCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
                Cursor oldCursor = mainWindow.getCursor();
                mainWindow.setCursor(hourglassCursor);

                try {
                    // convert old projects if need
                    ConvertProject.convert(projectRootFolder);
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_CONVERT_PROJECT");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_CONVERT_PROJECT");
                    mainWindow.setCursor(oldCursor);
                    return null;
                }

                // check if project okay
                ProjectProperties props;
                try {
                    props = ProjectFileStorage.loadProjectProperties(projectRootFolder.getAbsoluteFile());
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    mainWindow.setCursor(oldCursor);
                    return null;
                }

                try {
                    boolean needToSaveProperties = false;
                    if (props.hasRepositories()) {
                        // team project - non-exist directories could be created from repo
                        props.autocreateDirectories();
                    } else {
                        // not a team project - ask for non-exist directories
                        while (!props.isProjectValid()) {
                            needToSaveProperties = true;
                            // something wrong with the project - display open dialog
                            // to fix it
                            ProjectPropertiesDialog prj = new ProjectPropertiesDialog(
                                    Core.getMainWindow().getApplicationFrame(), props,
                                    new File(projectRootFolder, OConsts.FILE_PROJECT).getAbsolutePath(),
                                    ProjectPropertiesDialog.Mode.RESOLVE_DIRS);
                            prj.setVisible(true);
                            props = prj.getResult();
                            prj.dispose();
                            if (props == null) {
                                // user clicks on 'Cancel'
                                mainWindow.setCursor(oldCursor);
                                return null;
                            }
                        }
                    }

                    final ProjectProperties propsP = props;
                    Core.executeExclusively(true, () -> ProjectFactory.loadProject(propsP, true));
                    if (needToSaveProperties) {
                        Core.getProject().saveProjectProperties();
                    }
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    mainWindow.setCursor(oldCursor);
                    return null;
                }

                RecentProjects.add(projectRootFolder.getAbsolutePath());

                mainWindow.setCursor(oldCursor);
                return null;
            }

            protected void done() {
                try {
                    get();
                    SwingUtilities.invokeLater(Core.getEditor()::requestFocus);
                } catch (Exception ex) {
                    Log.logErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                    Core.getMainWindow().displayErrorRB(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }
            }
        }.execute();
    }

    /**
     * Prompt the user to reload the current project
     */
    public static void promptReload() {
        if (!Core.getProject().isProjectLoaded()) {
            return;
        }
        // asking to reload a project
        int res = JOptionPane.showConfirmDialog(Core.getMainWindow().getApplicationFrame(),
                OStrings.getString("MW_REOPEN_QUESTION"), OStrings.getString("MW_REOPEN_TITLE"),
                JOptionPane.YES_NO_OPTION);
        if (res == JOptionPane.YES_OPTION) {
            projectReload();
        }
    }

    public static void projectReload() {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        final ProjectProperties props = Core.getProject().getProjectProperties();

        new SwingWorker<Object, Void>() {
            int previousCurEntryNum = Core.getEditor().getCurrentEntryNumber();

            protected Object doInBackground() throws Exception {
                IMainWindow mainWindow = Core.getMainWindow();
                Cursor hourglassCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
                Cursor oldCursor = mainWindow.getCursor();
                mainWindow.setCursor(hourglassCursor);

                Core.executeExclusively(true, () -> {
                    Core.getProject().saveProject(true);
                    ProjectFactory.closeProject();

                    ProjectFactory.loadProject(props, true);
                });
                mainWindow.setCursor(oldCursor);
                return null;
            }

            protected void done() {
                try {
                    get();
                    SwingUtilities.invokeLater(() -> {
                        // activate entry later - after project will be loaded
                        Core.getEditor().gotoEntry(previousCurEntryNum);
                        Core.getEditor().requestFocus();
                    });
                } catch (Exception ex) {
                    processSwingWorkerException(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }
            }
        }.execute();
    }

    public static void projectSave() {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        new SwingWorker<Object, Void>() {
            protected Object doInBackground() throws Exception {
                IMainWindow mainWindow = Core.getMainWindow();
                Cursor hourglassCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
                Cursor oldCursor = mainWindow.getCursor();
                mainWindow.setCursor(hourglassCursor);

                mainWindow.showStatusMessageRB("MW_STATUS_SAVING");

                Core.executeExclusively(true, () -> Core.getProject().saveProject(true));

                mainWindow.showStatusMessageRB("MW_STATUS_SAVED");
                mainWindow.setCursor(oldCursor);
                return null;
            }

            protected void done() {
                try {
                    get();
                } catch (Exception ex) {
                    processSwingWorkerException(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }
            }
        }.execute();
    }

    public static void projectClose() {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        new SwingWorker<Object, Void>() {
            protected Object doInBackground() throws Exception {
                Core.getMainWindow().showStatusMessageRB("MW_STATUS_SAVING");

                IMainWindow mainWindow = Core.getMainWindow();
                Cursor hourglassCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
                Cursor oldCursor = mainWindow.getCursor();
                mainWindow.setCursor(hourglassCursor);

                Preferences.save();

                Core.executeExclusively(true, () -> {
                    Core.getProject().saveProject(true);
                    ProjectFactory.closeProject();
                });

                Core.getMainWindow().showStatusMessageRB("MW_STATUS_SAVED");
                mainWindow.setCursor(oldCursor);

                // fix - reset progress bar to defaults
                Core.getMainWindow().showLengthMessage(OStrings.getString("MW_SEGMENT_LENGTH_DEFAULT"));
                Core.getMainWindow()
                        .showProgressMessage(Preferences.getPreferenceEnumDefault(Preferences.SB_PROGRESS_MODE,
                                MainWindowUI.STATUS_BAR_MODE.DEFAULT) == MainWindowUI.STATUS_BAR_MODE.DEFAULT
                                        ? OStrings.getString("MW_PROGRESS_DEFAULT")
                                        : OStrings.getProgressBarDefaultPrecentageText());

                return null;
            }

            protected void done() {
                try {
                    get();
                } catch (Exception ex) {
                    processSwingWorkerException(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }
                // Restore global prefs in case project had project-specific ones
                Core.setFilterMaster(new FilterMaster(Preferences.getFilters()));
                Core.setSegmenter(new Segmenter(Preferences.getSRX()));
            }
        }.execute();
    }

    public static void projectEditProperties() {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        // displaying the dialog to change paths and other properties
        ProjectPropertiesDialog prj = new ProjectPropertiesDialog(Core.getMainWindow().getApplicationFrame(),
                Core.getProject().getProjectProperties(), Core.getProject().getProjectProperties().getProjectName(),
                ProjectPropertiesDialog.Mode.EDIT_PROJECT);
        prj.setVisible(true);
        final ProjectProperties newProps = prj.getResult();
        prj.dispose();
        if (newProps == null) {
            return;
        }

        int res = JOptionPane.showConfirmDialog(Core.getMainWindow().getApplicationFrame(),
                OStrings.getString("MW_REOPEN_QUESTION"), OStrings.getString("MW_REOPEN_TITLE"),
                JOptionPane.YES_NO_OPTION);
        if (res != JOptionPane.YES_OPTION) {
            return;
        }

        new SwingWorker<Object, Void>() {
            int previousCurEntryNum = Core.getEditor().getCurrentEntryNumber();

            protected Object doInBackground() throws Exception {
                Core.executeExclusively(true, () -> {
                    Core.getProject().saveProject(true);
                    ProjectFactory.closeProject();

                    ProjectFactory.loadProject(newProps, true);
                });
                return null;
            }

            protected void done() {
                try {
                    get();
                    // Make sure to update Editor title
                    SwingUtilities.invokeLater(() -> {
                        // activate entry later - after project will be loaded
                        Core.getEditor().gotoEntry(previousCurEntryNum);
                        Core.getEditor().requestFocus();
                    });
                } catch (Exception ex) {
                    processSwingWorkerException(ex, "PP_ERROR_UNABLE_TO_READ_PROJECT_FILE");
                }
            }
        }.execute();
    }

    public static void projectCompile() {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        new SwingWorker<Object, Void>() {
            protected Object doInBackground() throws Exception {
                Core.executeExclusively(true, () -> {
                    Core.getProject().saveProject(true);
                    try {
                        Core.getProject().compileProject(".*");
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                });
                return null;
            }

            protected void done() {
                try {
                    get();
                } catch (Exception ex) {
                    processSwingWorkerException(ex, "TF_COMPILE_ERROR");
                }
            }
        }.execute();
    }

    public static void projectSingleCompile(final String sourcePattern) {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        new SwingWorker<Object, Void>() {
            @Override
            protected Object doInBackground() throws Exception {
                Core.executeExclusively(true, () -> {
                    Core.getProject().saveProject(false);
                    try {
                        Core.getProject().compileProject(sourcePattern);
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                });
                return null;
            }

            @Override
            protected void done() {
                try {
                    get();
                } catch (Exception ex) {
                    processSwingWorkerException(ex, "TF_COMPILE_ERROR");
                }
            }
        }.execute();
    }

    public static void projectRemote(String url) {
        String dir = url.replace("/", "_").replace(':', '_');
        File projectDir = new File(StaticUtils.getConfigDir() + "/remoteProjects/" + dir);
        File projectFile = new File(projectDir, OConsts.FILE_PROJECT);

        byte[] data;
        try {
            projectDir.mkdirs();
            data = WikiGet.getURLasByteArray(url);
            FileUtils.writeByteArrayToFile(projectFile, data);
        } catch (Exception ex) {
            Log.logErrorRB(ex, "TEAM_REMOTE_RETRIEVE_ERROR", url);
            Core.getMainWindow().displayErrorRB(ex, "TEAM_REMOTE_RETRIEVE_ERROR", url);
            return;
        }

        projectOpen(projectDir);
    }

    /**
     * Copy the specified files to the specified destination. The project will be reloaded afterward.
     * <p>
     * Convenience method for {@link #projectImportFiles(String, File[], boolean)}.
     * 
     * @param destination
     *            The path to copy the files to
     * @param toImport
     *            Files to copy to destination path
     */
    public static void projectImportFiles(String destination, File[] toImport) {
        projectImportFiles(destination, toImport, true);
    }

    /**
     * Copy the specified files to the specified destination, then reload if indicated. Note that a modal
     * dialog will be shown if any of the specified files would be overwritten.
     * 
     * @param destination
     *            The path to copy the files to
     * @param toImport
     *            Files to copy to destination path
     * @param doReload
     *            If true, the project will be reloaded after the files are successfully copied
     */
    public static void projectImportFiles(String destination, File[] toImport, boolean doReload) {
        UIThreadsUtil.mustBeSwingThread();

        if (!Core.getProject().isProjectLoaded()) {
            return;
        }

        // commit the current entry first
        Core.getEditor().commitAndLeave();

        try {
            FileUtil.copyFilesTo(new File(destination), toImport, new CollisionCallback());
            if (doReload) {
                projectReload();
            }
        } catch (IOException ioe) {
            Core.getMainWindow().displayErrorRB(ioe, "MAIN_ERROR_File_Import_Failed");
        }
    }

    private static class CollisionCallback implements ICollisionCallback {
        private boolean isCanceled = false;
        private boolean yesToAll = false;

        @Override
        public boolean shouldReplace(File file, int index, int total) {
            if (isCanceled) {
                return false;
            }
            if (yesToAll) {
                return true;
            }
            FileCollisionDialog dialog = new FileCollisionDialog(Core.getMainWindow().getApplicationFrame());
            dialog.setFilename(file.getName());
            dialog.enableApplyToAll(total - index > 1);
            dialog.pack();
            dialog.setVisible(true);
            isCanceled = dialog.userDidCancel();
            if (isCanceled) {
                return false;
            }
            yesToAll = dialog.isApplyToAll() && dialog.shouldReplace();
            return yesToAll || dialog.shouldReplace();
        }

        @Override
        public boolean isCanceled() {
            return isCanceled;
        }
    };

    /**
     * Imports the file/files/folder into project's source files.
     */
    public static void doPromptImportSourceFiles() {
        OmegaTFileChooser chooser = new OmegaTFileChooser();
        chooser.setMultiSelectionEnabled(true);
        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        chooser.setDialogTitle(OStrings.getString("TF_FILE_IMPORT_TITLE"));

        int result = chooser.showOpenDialog(Core.getMainWindow().getApplicationFrame());
        if (result == OmegaTFileChooser.APPROVE_OPTION) {
            File[] selFiles = chooser.getSelectedFiles();
            projectImportFiles(Core.getProject().getProjectProperties().getSourceRoot(), selFiles);
        }
    }

    /**
     * Does wikiread
     */
    public static void doWikiImport() {
        String remote_url = JOptionPane.showInputDialog(Core.getMainWindow().getApplicationFrame(),
                OStrings.getString("TF_WIKI_IMPORT_PROMPT"), OStrings.getString("TF_WIKI_IMPORT_TITLE"),
                JOptionPane.OK_CANCEL_OPTION);
        String projectsource = Core.getProject().getProjectProperties().getSourceRoot();
        if (remote_url == null || remote_url.trim().isEmpty()) {
            // [1762625] Only try to get MediaWiki page if a string has been entered
            return;
        }
        try {
            WikiGet.doWikiGet(remote_url, projectsource);
            projectReload();
        } catch (Exception ex) {
            Log.log(ex);
            Core.getMainWindow().displayErrorRB(ex, "TF_WIKI_IMPORT_FAILED");
        }
    }

    private static void processSwingWorkerException(Exception ex, String errorCode) {
        if (ex instanceof ExecutionException) {
            Log.logErrorRB(ex.getCause(), errorCode);
            if (ex.getCause() instanceof KnownException) {
                KnownException e = (KnownException) ex.getCause();
                Core.getMainWindow().displayErrorRB(e.getCause(), e.getMessage(), e.getParams());
            } else {
                Core.getMainWindow().displayErrorRB(ex.getCause(), errorCode);
            }
        } else {
            Log.logErrorRB(ex, errorCode);
            Core.getMainWindow().displayErrorRB(ex, errorCode);
        }
    }
}