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 String getNoteText() {
    UIThreadsUtil.mustBeSwingThread();

    String text = getText();
    // Disallow empty note. Use null to indicate lack of note.
    return text.isEmpty() ? null : text;
  }
  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();
  }
  /** Clears up the pane. */
  public void clear() {
    UIThreadsUtil.mustBeSwingThread();

    setText("");
    setEditable(false);
    ste = null;
  }
  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 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 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();
  }
  /**
   * 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");
    }
  }
  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 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();
  }
  /**
   * 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();
  }
  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();
  }
  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 void setNoteText(String text) {
    UIThreadsUtil.mustBeSwingThread();

    setText(text);
    setEditable(true);
  }