2024-10-07 00:58:29 +03:00
|
|
|
|
package Common_old.UI.Menus;
|
2024-10-07 14:22:52 +03:00
|
|
|
|
import Common.Utils.CommonUtils;
|
2024-10-07 00:58:29 +03:00
|
|
|
|
import Common_old.Current;
|
|
|
|
|
|
import _VisualDVM.Global;
|
|
|
|
|
|
import Common_old.UI.Editor.CaretInfo;
|
|
|
|
|
|
import Common_old.Utils.Utils;
|
2023-09-17 22:13:42 +03:00
|
|
|
|
import ProjectData.Files.DBProjectFile;
|
|
|
|
|
|
import ProjectData.Files.UI.Editor.SPFEditor;
|
|
|
|
|
|
import ProjectData.SapforData.Functions.FuncCall;
|
|
|
|
|
|
import ProjectData.SapforData.Functions.FuncInfo;
|
|
|
|
|
|
import ProjectData.SapforData.Functions.FunctionType;
|
|
|
|
|
|
import ProjectData.SapforData.Loops.Loop;
|
2023-11-19 02:12:44 +03:00
|
|
|
|
import Visual_DVM_2021.Passes.PassCode_2021;
|
|
|
|
|
|
import Visual_DVM_2021.Passes.Pass_2021;
|
2023-09-17 22:13:42 +03:00
|
|
|
|
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_2021.passes.get(PassCode_2021.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_2021.passes.get(PassCode_2021.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_2021.passes.get(PassCode_2021.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_2021.passes.get(PassCode_2021.SPF_ChangeSpfIntervals).Do(
|
|
|
|
|
|
((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionStart()) + 1,
|
|
|
|
|
|
((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionEnd()) + 1,
|
|
|
|
|
|
1
|
|
|
|
|
|
);
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
Global.Log.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_2021.passes.get(PassCode_2021.SPF_ChangeSpfIntervals).Do(
|
|
|
|
|
|
((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionStart()) + 1,
|
|
|
|
|
|
((RSyntaxTextArea) editor).getLineOfOffset(editor.getSelectionEnd()) + 1,
|
|
|
|
|
|
0
|
|
|
|
|
|
);
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
Global.Log.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 (Current.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 (Current.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 {
|
|
|
|
|
|
Current.getSapfor().UpdateProjectFiles(false);
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
Global.Log.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 = "Имя процедуры может содержать только английские буквы, цифры и подчеркивания, и не может начинаться с цифры.";
|
|
|
|
|
|
//-
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Выделено некорректное имя.");
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Выделено некорректное имя.");
|
|
|
|
|
|
//-
|
|
|
|
|
|
m_inline.setToolTipText(tip);
|
|
|
|
|
|
m_gotoFunction.setToolTipText(tip);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!Pass_2021.passes.get(PassCode_2021.SPF_GetGraphFunctions).isDone()) {
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Выполните проход \"Граф процедур \".");
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Выполните проход \"Граф процедур \"");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (Current.getSapfor().isIntrinsic(selectedText)) {
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Процедура является стандартной.");
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Процедура является стандартной.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
call = Current.getFile().find_func_call(selectedText);
|
|
|
|
|
|
if (call == null) {
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Вызов не найден в текущей строке.");
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Объявление процедуры уже находится в текущей строке.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
decl = Current.getProject().allFunctions.get(call.funcName);
|
|
|
|
|
|
if (decl.type.equals(FunctionType.NotFound)) {
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Объявление процедуры не найдено в проекте.");
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
2023-09-17 22:13:42 +03:00
|
|
|
|
" . Объявление процедуры не найдено в проекте.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
//---
|
|
|
|
|
|
m_inline.setEnabled(true);
|
|
|
|
|
|
m_gotoFunction.setEnabled(true);
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_inline.setText("Подставить вызов процедуры " + CommonUtils.Brackets(selectedText));
|
|
|
|
|
|
m_gotoFunction.setText("Перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText));
|
2023-09-17 22:13:42 +03:00
|
|
|
|
//--
|
|
|
|
|
|
}
|
|
|
|
|
|
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_2021.passes.get(PassCode_2021.SPF_GetIncludeDependencies).isDone()) {
|
|
|
|
|
|
m_gotoHeader.setText("Невозможно перейти к заголовочному файлу. Выполните проход \"Поиск зависимостей по включению\"");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!Current.getFile().relativeHeaders.containsKey(header_)) {
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_gotoHeader.setText("Невозможно перейти к заголовочному файлу " + CommonUtils.Brackets(header_) + " . Файл не найден среди включений текущего файла.");
|
2023-09-17 22:13:42 +03:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
header = Current.getFile().relativeHeaders.get(header_);
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_gotoHeader.setText("Переход к заголовочному файлу " + CommonUtils.Brackets(header_));
|
2023-09-17 22:13:42 +03:00
|
|
|
|
m_gotoHeader.setEnabled(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private void checkLoop() {
|
|
|
|
|
|
loop = null;
|
|
|
|
|
|
m_loop_union.setEnabled(false);
|
|
|
|
|
|
if (!Pass_2021.passes.get(PassCode_2021.SPF_GetGraphLoops).isDone()) {
|
|
|
|
|
|
m_loop_union.setText("Невозможно объединить цикл в текущей строке со следующим. " +
|
|
|
|
|
|
"Выполните проход \"Граф циклов\"");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
loop = Current.getFile().find_current_loop();
|
|
|
|
|
|
if (loop == null) {
|
|
|
|
|
|
m_loop_union.setText("Невозможно объединить цикл в текущей строке со следующим. Не найдено циклов в текущей строке.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
m_loop_union.setEnabled(true);
|
2024-10-07 14:22:52 +03:00
|
|
|
|
m_loop_union.setText("Объединить цикл в строке " + CommonUtils.Brackets(loop.line) + " со следующим");
|
2023-09-17 22:13:42 +03:00
|
|
|
|
}
|
|
|
|
|
|
@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 (Current.getSapfor().OldFiles.isEmpty()) {
|
|
|
|
|
|
m_undo.setEnabled(false);
|
|
|
|
|
|
m_undo.setText("Невозможно отменить последнюю модификацию. Модификации отсутствуют.");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
m_undo.setEnabled(true);
|
|
|
|
|
|
m_undo.setText("Отменить последнюю модификацию.");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|