boolean (@NotNull Project project, @NotNull Document document, Editor editor, @NotNull VirtualFile virtualFile, @NotNull Charset charset, @NotNull EncodingUtil.Magic8 isSafeToConvert, @NotNull EncodingUtil.Magic8 isSafeToReload) { Charset oldCharset = virtualFile.getCharset(); Runnable undo; Runnable redo; if (isSafeToConvert == EncodingUtil.Magic8.ABSOLUTELY && isSafeToReload == EncodingUtil.Magic8.ABSOLUTELY) { final EncodingManager encodingManager = EncodingProjectManager.getInstance(project); //change and forget undo = () -> encodingManager.setEncoding(virtualFile, oldCharset); redo = () -> encodingManager.setEncoding(virtualFile, charset); } else { IncompatibleEncodingDialog dialog = new IncompatibleEncodingDialog(virtualFile, charset, isSafeToReload, isSafeToConvert); dialog.show(); if (dialog.getExitCode() == IncompatibleEncodingDialog.RELOAD_EXIT_CODE) { undo = () -> EncodingUtil.reloadIn(virtualFile, oldCharset, project); redo = () -> EncodingUtil.reloadIn(virtualFile, charset, project); } else if (dialog.getExitCode() == IncompatibleEncodingDialog.CONVERT_EXIT_CODE) { undo = () -> EncodingUtil.saveIn(project, document, editor, virtualFile, oldCharset); redo = () -> EncodingUtil.saveIn(project, document, editor, virtualFile, charset); } else { return false; } } final UndoableAction action = new GlobalUndoableAction(virtualFile) { @Override public void undo() { // invoke later because changing document inside undo/redo is not allowed Application application = ApplicationManager.getApplication(); application.invokeLater(undo, ModalityState.nonModal(), project.getDisposed()); } @Override public void redo() { // invoke later because changing document inside undo/redo is not allowed Application application = ApplicationManager.getApplication(); application.invokeLater(redo, ModalityState.nonModal(), project.getDisposed()); } }; redo.run(); CommandProcessor.getInstance().executeCommand(project, () -> { UndoManager undoManager = UndoManager.getInstance(project); undoManager.undoableActionPerformed(action); }, IdeBundle.message("change.encoding.command.name", virtualFile.getName()), null, UndoConfirmationPolicy.REQUEST_CONFIRMATION); return true; }