package _VisualDVM.Visual.Menus; import Common.Utils.Utils_; import Common.Visual.Menus.TextEditorMenu; import Common.Visual.Menus.VisualiserMenuItem; import _VisualDVM.Current; import _VisualDVM.Global; import _VisualDVM.Visual.Editor.CaretInfo; import _VisualDVM.Utils; import _VisualDVM.ProjectData.Files.DBProjectFile; import _VisualDVM.ProjectData.Files.UI.Editor.SPFEditor; import _VisualDVM.ProjectData.SapforData.Functions.FuncCall; import _VisualDVM.ProjectData.SapforData.Functions.FuncInfo; import _VisualDVM.ProjectData.SapforData.Functions.FunctionType; import _VisualDVM.ProjectData.SapforData.Loops.Loop; import Visual_DVM_2021.Passes.PassCode; import Common.Passes.Pass; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class MainEditorMenu extends TextEditorMenu { FuncCall call = null; FuncInfo decl = null; Loop loop = null; DBProjectFile header = null; //------------------ JMenuItem m_comment; JMenuItem m_uncomment; JMenuItem m_inline; JMenuItem m_add_lines_to_region; JMenuItem m_remove_lines_from_region; JMenuItem m_loop_union; JMenuItem m_undo; JMenuItem m_gotoFunction; JMenuItem m_gotoHeader; //----------------- public MainEditorMenu(RSyntaxTextArea editor_in) { super(editor_in); addSeparator(); m_gotoHeader = new VisualiserMenuItem("Перейти к заголовочному файлу", "/icons/Transformations/SPF_InsertIncludesPass.png"); m_gotoHeader.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Pass.passes.get(PassCode.OpenCurrentFile).Do(header); } }); add(m_gotoHeader); addSeparator(); m_gotoFunction = new VisualiserMenuItem("Перейти к объявлению процедуры", "/icons/versions/currentVersion.png"); m_gotoFunction.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { decl.Show(true); } }); add(m_gotoFunction); m_inline = new VisualiserMenuItem("Подставить вызов процедуры", "/icons/Transformations/SPF_InlineProcedures.png"); m_inline.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { Pass.passes.get(PassCode.SPF_InlineProcedure).Do(call); } }); add(m_inline); addSeparator(); m_loop_union = new VisualiserMenuItem("Объединить цикл со следующим", "/icons/Transformations/SPF_LoopUnion.png"); m_loop_union.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { Pass.passes.get(PassCode.SPF_LoopUnionCurrent).Do(); } }); add(m_loop_union); m_add_lines_to_region = new VisualiserMenuItem("Добавить строки в область", "/icons/Menu/AddLines.png"); m_add_lines_to_region.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { try { Pass.passes.get(PassCode.SPF_ChangeSpfIntervals).Do( ((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionStart()) + 1, ((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionEnd()) + 1, 1 ); } catch (Exception ex) { Utils_.MainLog.PrintException(ex); } } }); add(m_add_lines_to_region); m_remove_lines_from_region = new VisualiserMenuItem("Удалить строки из области", "/icons/Menu/RemoveLines.png"); m_remove_lines_from_region.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { try { Pass.passes.get(PassCode.SPF_ChangeSpfIntervals).Do( ((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionStart()) + 1, ((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionEnd()) + 1, 0 ); } catch (Exception ex) { Utils_.MainLog.PrintException(ex); } } }); add(m_remove_lines_from_region); addSeparator(); m_comment = new VisualiserMenuItem("Закомментировать блок", "/icons/Editor/Comment.png"); m_comment.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { String new_ = ""; String[] data = selectedText.split("\n"); int i = 0; switch (Global.mainModule.getFile().languageName) { case fortran: for (String line : data) { if (!line.startsWith("!")) { new_ += "!" + line; } else new_ += line; if (i < data.length - 1) new_ += "\n"; ++i; } break; case c: case cpp: for (String line : data) { if (!line.startsWith("//")) { new_ += "//" + line; } else new_ += line; if (i < data.length - 1) new_ += "\n"; ++i; } break; default: new_ = selectedText; break; } editor.replaceSelection(new_); } }); add(m_comment); m_uncomment = new VisualiserMenuItem("Раскомментировать блок", "/icons/Editor/Uncomment.png"); m_uncomment.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { String new_ = ""; String[] data = selectedText.split("\n"); int i = 0; switch (Global.mainModule.getFile().languageName) { case fortran: for (String line : data) { if (line.startsWith("!")) { new_ += line.substring(1); } else new_ += line; if (i < data.length - 1) new_ += "\n"; ++i; } break; case c: case cpp: for (String line : data) { if (line.startsWith("//")) { new_ += line.substring(2); } else new_ += line; if (i < data.length - 1) new_ += "\n"; ++i; } break; default: new_ = selectedText; break; } //todo. возможно, изменить концепцию на выделенные строки? editor.replaceSelection(new_); } }); add(m_uncomment); addSeparator(); m_undo = new VisualiserMenuItem("Отменить последнюю модификацию", "/icons/Menu/Undo.png"); m_undo.addActionListener( new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { try { Global.mainModule.getSapfor().UpdateProjectFiles(false); } catch (Exception ex) { Utils_.MainLog.PrintException(ex); } } }); add(m_undo); } private void checkFunction() { call = null; decl = null; //-- m_inline.setEnabled(false); m_gotoFunction.setEnabled(false); //-- m_inline.setToolTipText(""); m_gotoFunction.setToolTipText(""); //-- if (selectedText == null) { m_inline.setText("Невозможно подставить вызов процедуры. Не выделено имя процедуры."); m_gotoFunction.setText("Невозможно перейти к объявлению процедуры. Не выделено имя процедуры"); return; } if (selectedText.contains("\n")) { m_inline.setText("Невозможно подставить вызов процедуры. Выделено несколько строк"); m_gotoFunction.setText("Невозможно перейти к объявлению процедуры. Выделено несколько строк."); return; } if (!Utils.isFunctionName(selectedText)) { String tip = "Имя процедуры может содержать только английские буквы, цифры и подчеркивания, и не может начинаться с цифры."; //- m_inline.setText("Невозможно подставить вызов процедуры " + Utils_.Brackets(selectedText) + " . Выделено некорректное имя."); m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils_.Brackets(selectedText) + " . Выделено некорректное имя."); //- m_inline.setToolTipText(tip); m_gotoFunction.setToolTipText(tip); return; } if (!Pass.passes.get(PassCode.SPF_GetGraphFunctions).isDone()) { m_inline.setText("Невозможно подставить вызов процедуры " + Utils_.Brackets(selectedText) + " . Выполните проход \"Граф процедур \"."); m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils_.Brackets(selectedText) + " . Выполните проход \"Граф процедур \""); return; } if (Global.mainModule.getSapfor().isIntrinsic(selectedText)) { m_inline.setText("Невозможно подставить вызов процедуры " + Utils_.Brackets(selectedText) + " . Процедура является стандартной."); m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils_.Brackets(selectedText) + " . Процедура является стандартной."); return; } call =Global.mainModule.getFile().find_func_call(selectedText); if (call == null) { m_inline.setText("Невозможно подставить вызов процедуры " + Utils_.Brackets(selectedText) + " . Вызов не найден в текущей строке."); m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils_.Brackets(selectedText) + " . Объявление процедуры уже находится в текущей строке."); return; } decl = Global.mainModule.getProject().allFunctions.get(call.funcName); if (decl.type.equals(FunctionType.NotFound)) { m_inline.setText("Невозможно подставить вызов процедуры " + Utils_.Brackets(selectedText) + " . Объявление процедуры не найдено в проекте."); m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils_.Brackets(selectedText) + " . Объявление процедуры не найдено в проекте."); return; } //--- m_inline.setEnabled(true); m_gotoFunction.setEnabled(true); m_inline.setText("Подставить вызов процедуры " + Utils_.Brackets(selectedText)); m_gotoFunction.setText("Перейти к объявлению процедуры " + Utils_.Brackets(selectedText)); //-- } private void checkHeader() { header = null; m_gotoHeader.setEnabled(false); //-- CaretInfo caretInfo = ((SPFEditor) editor).getCaretInfo(); if (caretInfo != null) { String header_ = Utils.extractHeaderName(caretInfo.current_line); if (header_ == null) { m_gotoHeader.setText("Невозможно перейти к заголовочному файлу. В текущей строке не найдено включений."); return; } if (!Pass.passes.get(PassCode.SPF_GetIncludeDependencies).isDone()) { m_gotoHeader.setText("Невозможно перейти к заголовочному файлу. Выполните проход \"Поиск зависимостей по включению\""); return; } if (!Global.mainModule.getFile().relativeHeaders.containsKey(header_)) { m_gotoHeader.setText("Невозможно перейти к заголовочному файлу " + Utils_.Brackets(header_) + " . Файл не найден среди включений текущего файла."); return; } header = Global.mainModule.getFile().relativeHeaders.get(header_); m_gotoHeader.setText("Переход к заголовочному файлу " + Utils_.Brackets(header_)); m_gotoHeader.setEnabled(true); } } private void checkLoop() { loop = null; m_loop_union.setEnabled(false); if (!Pass.passes.get(PassCode.SPF_GetGraphLoops).isDone()) { m_loop_union.setText("Невозможно объединить цикл в текущей строке со следующим. " + "Выполните проход \"Граф циклов\""); return; } loop = Global.mainModule.getFile().find_current_loop(); if (loop == null) { m_loop_union.setText("Невозможно объединить цикл в текущей строке со следующим. Не найдено циклов в текущей строке."); return; } m_loop_union.setEnabled(true); m_loop_union.setText("Объединить цикл в строке " + Utils_.Brackets(loop.line) + " со следующим"); } @Override public void CheckElementsVisibility() { super.CheckElementsVisibility(); m_strike.setVisible(false); m_unstrike.setVisible(false); checkFunction(); checkHeader(); checkLoop(); if (selectedText == null) { m_comment.setEnabled(false); m_uncomment.setEnabled(false); m_add_lines_to_region.setEnabled(false); m_remove_lines_from_region.setEnabled(false); m_comment.setText("Невозможно закомментировать блок. Не выделено ни одной строки."); m_uncomment.setText("Невозможно раскомментировать блок. Не выделено ни одной строки."); m_add_lines_to_region.setText("Невозможно добавить строки в область. Не выделено ни одной строки."); m_remove_lines_from_region.setText("Невозможно удалить строки из области. Не выделено ни одной строки."); } else { m_comment.setEnabled(true); m_uncomment.setEnabled(true); m_add_lines_to_region.setEnabled(true); m_remove_lines_from_region.setEnabled(true); m_comment.setText("Закомментировать блок"); m_uncomment.setText("Раскомментировать блок"); m_add_lines_to_region.setText("Добавить строки в область"); m_remove_lines_from_region.setText("Удалить строки из области"); } if (Global.mainModule.getSapfor().OldFiles.isEmpty()) { m_undo.setEnabled(false); m_undo.setText("Невозможно отменить последнюю модификацию. Модификации отсутствуют."); } else { m_undo.setEnabled(true); m_undo.setText("Отменить последнюю модификацию."); } } }