345 lines
18 KiB
Java
345 lines
18 KiB
Java
package _VisualDVM.Visual.Menus;
|
||
import Common.Utils.CommonUtils;
|
||
import Common.Visual.Menus.TextEditorMenu;
|
||
import Common.Visual.Menus.VisualiserMenuItem;
|
||
import _VisualDVM.Current;
|
||
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) {
|
||
CommonUtils.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) {
|
||
CommonUtils.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 (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) {
|
||
CommonUtils.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("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Выделено некорректное имя.");
|
||
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Выделено некорректное имя.");
|
||
//-
|
||
m_inline.setToolTipText(tip);
|
||
m_gotoFunction.setToolTipText(tip);
|
||
return;
|
||
}
|
||
if (!Pass.passes.get(PassCode.SPF_GetGraphFunctions).isDone()) {
|
||
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Выполните проход \"Граф процедур \".");
|
||
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Выполните проход \"Граф процедур \"");
|
||
return;
|
||
}
|
||
if (Current.getSapfor().isIntrinsic(selectedText)) {
|
||
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Процедура является стандартной.");
|
||
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Процедура является стандартной.");
|
||
return;
|
||
}
|
||
call = Current.getFile().find_func_call(selectedText);
|
||
if (call == null) {
|
||
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Вызов не найден в текущей строке.");
|
||
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Объявление процедуры уже находится в текущей строке.");
|
||
return;
|
||
}
|
||
decl = Current.getProject().allFunctions.get(call.funcName);
|
||
if (decl.type.equals(FunctionType.NotFound)) {
|
||
m_inline.setText("Невозможно подставить вызов процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Объявление процедуры не найдено в проекте.");
|
||
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + CommonUtils.Brackets(selectedText) +
|
||
" . Объявление процедуры не найдено в проекте.");
|
||
return;
|
||
}
|
||
//---
|
||
m_inline.setEnabled(true);
|
||
m_gotoFunction.setEnabled(true);
|
||
m_inline.setText("Подставить вызов процедуры " + CommonUtils.Brackets(selectedText));
|
||
m_gotoFunction.setText("Перейти к объявлению процедуры " + CommonUtils.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 (!Current.getFile().relativeHeaders.containsKey(header_)) {
|
||
m_gotoHeader.setText("Невозможно перейти к заголовочному файлу " + CommonUtils.Brackets(header_) + " . Файл не найден среди включений текущего файла.");
|
||
return;
|
||
}
|
||
header = Current.getFile().relativeHeaders.get(header_);
|
||
m_gotoHeader.setText("Переход к заголовочному файлу " + CommonUtils.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 = Current.getFile().find_current_loop();
|
||
if (loop == null) {
|
||
m_loop_union.setText("Невозможно объединить цикл в текущей строке со следующим. Не найдено циклов в текущей строке.");
|
||
return;
|
||
}
|
||
m_loop_union.setEnabled(true);
|
||
m_loop_union.setText("Объединить цикл в строке " + CommonUtils.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 (Current.getSapfor().OldFiles.isEmpty()) {
|
||
m_undo.setEnabled(false);
|
||
m_undo.setText("Невозможно отменить последнюю модификацию. Модификации отсутствуют.");
|
||
} else {
|
||
m_undo.setEnabled(true);
|
||
m_undo.setText("Отменить последнюю модификацию.");
|
||
}
|
||
}
|
||
}
|