Files
VisualSapfor/src/Visual_DVM_2021/UI/Main/ComparisonForm.java
2024-10-09 20:35:18 +03:00

357 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package Visual_DVM_2021.UI.Main;
import Common.CommonConstants;
import Common.CurrentAnchestor;
import Common.Utils.CommonUtils;
import Common.Visual.CommonUI;
import Common_old.Current;
import Common.Database.Objects.DBObject;
import _VisualDVM.Visual.Editor.BaseEditor;
import _VisualDVM.Visual.Controls.ShortLabel;
import Common_old.UI.Menus_2023.VisualiserMenuBar;
import Common_old.UI.UI;
import Common.Utils.TextLog;
import Common_old.Utils.Utils;
import Visual_DVM_2021.Passes.Pass_2021;
import javafx.util.Pair;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaHighlighter;
import org.fife.ui.rtextarea.RTextScrollPane;
import javax.swing.*;
import java.util.LinkedHashMap;
import java.util.Vector;
public abstract class ComparisonForm<T> {
public Class<T> t; //класс объектов.
//-->>
private JPanel content;
public JPanel getContent() {
return content;
}
protected JToolBar tools;
private JPanel editorPanel;
protected JLabel lObjectName;
protected JButton bApplyObject;
private JButton bPrevious;
private JButton bNext;
private JButton bCompare;
protected JButton bClose;
//-->>
ComparisonForm<T> this_ = null; //?
ComparisonForm<T> slave = null;
ComparisonForm<T> master = null;
//-->>
protected T object = null;
//-->>
protected BaseEditor Body;
private RTextScrollPane Scroll;
//-->>
public Vector<String> lines = new Vector<>(); //строки с учетом/неучетом пробелов. для сравнения
public Vector<String> visible_lines = new Vector<>(); //строки с нетронутыми пробелами. для отображения
//подсветка.
public LinkedHashMap<Integer, Pair<Integer, Boolean>> colors = new LinkedHashMap<>();
public RSyntaxTextAreaHighlighter slave_highlighter = null; //погонщик рабов
//-----
private boolean events_on = false;//относится только к мастеру, отвечает за скроллы.
private int current_diff_line = -1;
//--->>
public boolean isMaster() {
return slave != null;
}
public boolean isSlave() {
return master != null;
}
//--->>
//неперегружаемые методы
protected void RemoveObject() {
object = null;
removeObject();
showNoObject();
ClearText();
/*
if (isMaster())
slave.ClearText();
else if (isSlave())
master.ClearText();
*/
}
public void ApplyObject() {
RemoveObject();
TextLog log = new TextLog();
if (CurrentAnchestor.Check(log, getCurrentObjectName())) {
object = (T) CurrentAnchestor.get(getCurrentObjectName());
applyObject();
showObject();
} else
CommonUI.Info(log.toString());
}
public void ApplyObject(DBObject object_in){
RemoveObject();
object = (T)object_in;
applyObject();
showObject();
}
private void ShowCurrentDiff() {
Body.gotoLine_(colors.get(current_diff_line).getKey());
}
private void getLines() {
lines.clear();
visible_lines.clear();
//--
Pair<Vector<String>, Vector<String>> p = Utils.getFortranLines(getText());
lines = p.getKey();
visible_lines = p.getValue();
}
protected void ClearText() {
events_on = false;
Body.setText("объект не назначен");
}
//предполагаем что оба объекта есть и мы можем получить с них текст.
protected void Compare() throws Exception {
events_on = false;
current_diff_line = CommonConstants.Nan;
colors.clear();
//-----------------------------------------------------------------------------------------------
Body.setText("");
slave.Body.setText("");
int d = 0;
getLines();
slave.getLines();
//--------------------------------------------------------------------
Vector<String> t1 = new Vector<>();
Vector<String> t2 = new Vector<>();
//------
int old_j = 0;
int j = 0;
for (int i = 0; i < lines.size(); ++i) {
if (Utils.Contains(slave.lines, lines.get(i), old_j)) {
for (int k = old_j; k < slave.lines.size(); ++k) {
j = k;
if (Utils.CompareLines(lines.get(i), slave.lines.get(k))) {
j++;
t1.add(visible_lines.get(i));
t2.add(slave.visible_lines.get(k));
break;
} else {
t1.add("+");
t2.add("+ " + slave.visible_lines.get(k));
colors.put(d, new Pair(t2.size() - 1, true));
++d;
}
}
old_j = j;
} else {
//строки гарантированно нет.
t1.add("- " + visible_lines.get(i));
t2.add("- " + visible_lines.get(i));
colors.put(d, new Pair(t2.size() - 1, false));
++d;
}
}
//теперь граничное условие. если первый файл кончился а второй нет, его остаток это добавление.
for (int i = j; i < slave.lines.size(); ++i) {
t1.add("+");
t2.add("+ " + slave.visible_lines.get(i));
colors.put(d, new Pair(t2.size() - 1, true));
++d;
}
///----------------
Body.setText(String.join("\n", t1));
slave.Body.setText(String.join("\n", t2));
Body.setCaretPosition(0);
slave.Body.setCaretPosition(0);
//теперь покрас.
for (Integer diff_num : colors.keySet()) {
slave_highlighter.addHighlight(
slave.Body.getLineStartOffset(colors.get(diff_num).getKey()),
slave.Body.getLineEndOffset(colors.get(diff_num).getKey()),
colors.get(diff_num).getValue() ? UI.GoodLoopPainter : UI.BadLoopPainter
);
}
if (colors.size() > 0) current_diff_line = 0;
events_on = true;
}
public void Show() throws Exception {
events_on = false;
current_diff_line = CommonConstants.Nan;
colors.clear();
//----------------------------------------------------------------------------------------------
Body.setText("");
slave.Body.setText("");
int d = 0;
getLines();
slave.getLines();
//--------------------------------------------------------------------
Vector<String> t1 = new Vector<>();
Vector<String> t2 = new Vector<>();
//------
t1.addAll(visible_lines);
t2.addAll(slave.visible_lines);
//просто выясняем кто из них длиннее, и короткий дополняем пустыми строками.]
int delta = Math.abs(t1.size() - t2.size());
if (lines.size() > slave.lines.size()) {
Utils.addEmptyLines(t2, delta);
} else if (lines.size() < slave.lines.size()) {
Utils.addEmptyLines(t1, delta);
}
///----------------
Body.setText(String.join("\n", t1));
slave.Body.setText(String.join("\n", t2));
Body.setCaretPosition(0);
slave.Body.setCaretPosition(0);
events_on = true;
}
//Перегружаемые методы.
//--->>
protected abstract Current getCurrentObjectName();
protected void showNoObject() {
lObjectName.setText("?");
lObjectName.setToolTipText("Объект не назначен.");
}
protected void showObject() {
if (object instanceof DBObject) {
DBObject dbObject = (DBObject) object;
lObjectName.setText(dbObject.toString());
lObjectName.setToolTipText(dbObject.toString());
}
}
protected void removeObject() {
}
protected void applyObject() {
}
protected abstract String getText();
protected boolean fortranWrapsOn() {
return false;
}
//--->>
// protected Object ownScrollModel = null;
//---<<
public ComparisonForm(Class<T> t_in, ComparisonForm<T> slave_in) {
//-
Body = new BaseEditor();
Scroll = new RTextScrollPane(Body);
editorPanel.add(Scroll);
// ownScrollModel = Scroll.getVerticalScrollBar().getModel();
//-
t = t_in;
this_ = this;
slave = slave_in;
bPrevious.setVisible(isMaster());
bNext.setVisible(isMaster());
Scroll.setLineNumbersEnabled(true);
bApplyObject.addActionListener(e -> {
ApplyObject();
});
//--->>>
Body.setWhitespaceVisible(true);
Body.setEditable(false);
if (isMaster()) {
//<editor-fold desc="синхронизация скроллов">
slave.Scroll.getVerticalScrollBar().setModel(Scroll.getVerticalScrollBar().getModel());
slave_highlighter = (RSyntaxTextAreaHighlighter) slave.Body.getHighlighter();
//бяк быть не должно при условии что строк одинаковое количество. а это должно выполняться.
Body.addCaretListener(e -> {
if (events_on && isReady() && slave.isReady()) {
try {
int master_lineNum = Body.getCaretLineNumber();
slave.Body.setCaretPosition(slave.Body.getLineStartOffset(master_lineNum));
} catch (Exception ex) {
CommonUtils.MainLog.PrintException(ex);
}
}
});
//</editor-fold>
slave.master = this;
bPrevious.addActionListener(e -> {
if (current_diff_line != CommonConstants.Nan) {
if (current_diff_line > 0)
current_diff_line--;
else
current_diff_line = colors.size() - 1;
ShowCurrentDiff();
}
});
bNext.addActionListener(e -> {
if (current_diff_line != CommonConstants.Nan) {
if (current_diff_line < colors.size() - 1)
current_diff_line++;
else
current_diff_line = 0;
ShowCurrentDiff();
}
});
bCompare.addActionListener(e -> {
DoComparePass(isReady() && slave.isReady());
});
} else {
//рабу сравнивать не положено.
bCompare.setVisible(false);
}
//--->>>
bClose.addActionListener(e -> {
onClose();
});
}
//-->>
private void createUIComponents() {
// TODO: place custom component creation code here
lObjectName = new ShortLabel(40);
tools = new VisualiserMenuBar();
}
//для сравнения по кнопке.
public boolean isReady() {
return object != null;
}
public void onClose() {
RemoveObject();
}
public void DoComparePass(boolean startCondition) {
Pass_2021 pass = new Pass_2021() {
@Override
public String getDescription() {
return "Сравнение";
}
@Override
protected boolean needsAnimation() {
return true;
}
@Override
public boolean needsConfirmations() {
return false;
}
@Override
protected boolean canStart(Object... args) throws Exception {
return startCondition;
}
@Override
protected void body() throws Exception {
Compare();
}
};
pass.Do();
}
public void DoShowPass(boolean startCondition) {
Pass_2021 pass = new Pass_2021() {
@Override
public String getDescription() {
return "Отображение";
}
@Override
protected boolean needsAnimation() {
return false;
}
@Override
public boolean needsConfirmations() {
return false;
}
@Override
protected boolean canStart(Object... args) throws Exception {
return startCondition;
}
@Override
protected void body() throws Exception {
Show();
}
};
pass.Do();
}
}