Перенос.

This commit is contained in:
2023-09-17 22:13:42 +03:00
parent dd2e0ca7e0
commit 629d8b8477
1239 changed files with 61161 additions and 1 deletions

495
src/Common/Current.java Normal file
View File

@@ -0,0 +1,495 @@
package Common;
import Common.Database.iDBObject;
import Common.UI.Themes.VisualiserTheme;
import Common.Utils.TextLog;
import GlobalData.Account.Account;
import GlobalData.Compiler.Compiler;
import GlobalData.Machine.Machine;
import GlobalData.Makefile.Makefile;
import GlobalData.Module.Module;
import GlobalData.RemoteFile.RemoteFile;
import GlobalData.RemoteSapfor.RemoteSapfor;
import GlobalData.RunConfiguration.RunConfiguration;
import GlobalData.Tasks.CompilationTask.CompilationTask;
import GlobalData.Tasks.RunTask.RunTask;
import GlobalData.User.User;
import ProjectData.Files.DBProjectFile;
import ProjectData.Project.db_project_info;
import ProjectData.SapforData.Functions.FuncInfo;
import ProjectData.SapforData.Regions.ParallelRegion;
import Repository.BugReport.BugReport;
import Repository.Subscribes.Subscriber;
import TestingSystem.Configuration.Configuration;
import TestingSystem.Sapfor.SapforConfiguration.SapforConfiguration;
import TestingSystem.Sapfor.SapforTask.SapforTask_2023;
import TestingSystem.Sapfor.SapforTasksPackage.SapforTasksPackage_2023;
import TestingSystem.Tasks.TestCompilationTask;
import TestingSystem.Tasks.TestRunTask;
import TestingSystem.TasksPackage.TasksPackage;
import TestingSystem.Test.Test;
import Visual_DVM_2021.Passes.UI.PassForm;
import javax.swing.tree.DefaultMutableTreeNode;
import java.io.File;
import java.util.LinkedHashMap;
public enum Current {
Undefined,
//--
SapforEtalonTaskResult,//самый левый пакет
SapforTaskResult,
//--
ComponentServerBackup,
Subscriber,
Theme,
FileGraphElement,
InlineGraphElement,
InlineGraphElement2,
IncludeGraphElement,
Component,
Project,
File,
Root,
Version,
BugReport,
Account,
DBArray,
ProjectArray,
ParallelRegionInfo,
ParallelVariant,
Machine,
User,
Compiler,
Makefile,
Module,
RunConfiguration,
EnvironmentValue,
CompilationTask,
RunTask,
ProjectNode, //узел в дереве проекта. нужен для отображения добавленных файлов
SelectedDirectory,
SelectedFile,
//текущий выбранный удаленный файл
RemoteFile,
PassForm, //текущее окно анимации. нужно для сообщений сапфора по сокету.
RunStsRecord,
//только для того, чтобы закодировать таблицу.
Array,
ParallelRegion,
Dimensions,
//----------
Warnings,
Errors,
Notes,
Recommendations,
//-
Sapfor,
//-
Scenario,
ScenarioCommand,
//-
Configuration,
Group,
//-
DVMParameterValue,
Test,
Function,
SelectedFunction,
//-
Credentials,
TestCompilationTask,
TestRunTask,
TasksPackage,
//-
DialogWindow,
//-
SapforTasksPackage,
PackageVersion,
RemoteSapfor,
SapforConfiguration,
SapforConfigurationCommand,
SapforTask,
SapforProfile,
SapforProfileSetting,
//--
ProjectView;
//-
//---
private static final LinkedHashMap<Current, Object> objects = new LinkedHashMap<>();
public static Mode mode;
public static boolean hasUI() {
return Current.mode.equals(Current.Mode.Normal);
}
public static boolean HasProject() {
return get(Project) != null;
}
public static boolean HasFile() {
return get(File) != null;
}
public static boolean HasSelectedFile() {
return get(SelectedFile) != null;
}
public static boolean HasAccount() {
return get(Account) != null;
}
public static boolean HasMachine() {
return get(Machine) != null;
}
public static boolean HasUser() {
return get(User) != null;
}
public static boolean HasCompiler() {
return get(Compiler) != null;
}
public static boolean HasRemoteFile() {
return get(RemoteFile) != null;
}
public static boolean HasMakefile() {
return get(Makefile) != null;
}
public static boolean HasRunConfiguration() {
return get(RunConfiguration) != null;
}
public static boolean HasCompilationTask() {
return get(CompilationTask) != null;
}
public static boolean HasRunTask() {
return get(RunTask) != null;
}
public static boolean HasPassForm() {
return get(PassForm) != null;
}
public static boolean HasProjectView() {
return get(ProjectView) != null;
}
//для быстрого доступа на чтение. слишком много на нем завязано.
public static db_project_info getProject() {
return (db_project_info) get(Project);
}
public static DBProjectFile getFile() {
return (DBProjectFile) get(File);
}
public static Repository.Component.Component getComponent() {
return (Repository.Component.Component) get(Component);
}
public static Repository.BugReport.BugReport getBugReport() {
return (BugReport) get(BugReport);
}
public static db_project_info getRoot() {
return (db_project_info) get(Root);
}
public static boolean HasRoot() {
return get(Root) != null;
}
public static db_project_info getVersion() {
return (db_project_info) get(Version);
}
public static Account getAccount() {
return (Account) get(Account);
}
public static boolean HasSubscriber() {
return get(Current.Subscriber) != null;
}
public static Repository.Subscribes.Subscriber getSubscriber() {
return (Subscriber) get(Current.Subscriber);
}
public static Machine getMachine() {
return (Machine) get(Current.Machine);
}
public static User getUser() {
return (User) get(Current.User);
}
public static Compiler getCompiler() {
return (Compiler) get(Current.Compiler);
}
public static CompilationTask getCompilationTask() {
return (CompilationTask) get(Current.CompilationTask);
}
public static RunTask getRunTask() {
return (RunTask) get(Current.RunTask);
}
public static RemoteFile getRemoteFile() {
return (RemoteFile) get(Current.RemoteFile);
}
public static Makefile getMakefile() {
return (Makefile) get(Current.Makefile);
}
public static Module getModule() {
return (Module) get(Current.Module);
}
public static RunConfiguration getRunConfiguration() {
return (RunConfiguration) get(Current.RunConfiguration);
}
public static Repository.Component.Sapfor.Sapfor getSapfor() {
return (Repository.Component.Sapfor.Sapfor) get(Current.Sapfor);
}
public static boolean HasGroup() {
return get(Current.Group) != null;
}
public static TestingSystem.Group.Group getGroup() {
return (TestingSystem.Group.Group) get(Current.Group);
}
//--
public static boolean HasConfiguration() {
return get(Current.Configuration) != null;
}
public static TestingSystem.Configuration.Configuration getConfiguration() {
return (Configuration) get(Current.Configuration);
}
public static SapforConfiguration getSapforConfiguration() {
return (TestingSystem.Sapfor.SapforConfiguration.SapforConfiguration) get(Current.SapforConfiguration);
}
//--
public static Test getTest() {
return (TestingSystem.Test.Test) get(Current.Test);
}
public static boolean HasTest() {
return get(Current.Test) != null;
}
public static boolean HasVersion() {
return get(Current.Version) != null;
}
public static TestCompilationTask getTestCompilationTask() {
return (TestingSystem.Tasks.TestCompilationTask) get(Current.TestCompilationTask);
}
public static boolean HasTestCompilationTask() {
return get(Current.TestCompilationTask) != null;
}
public static boolean HasTestRunTask() {
return get(Current.TestRunTask) != null;
}
public static TestRunTask getTestRunTask() {
return (TestingSystem.Tasks.TestRunTask) get(Current.TestRunTask);
}
public static RemoteFile getComponentServerBackup() {
return (RemoteFile) get(Current.ComponentServerBackup);
}
public static boolean HasComponentServerBackup() {
return get(Current.ComponentServerBackup) != null;
}
//-
public static boolean HasSapforTasksPackage() {
return get(Current.SapforTasksPackage) != null;
}
public static SapforTasksPackage_2023 getSapforTasksPackage() {
return (SapforTasksPackage_2023) get(Current.SapforTasksPackage);
}
//-
public static DefaultMutableTreeNode getProjectNode() {
return (DefaultMutableTreeNode) get(Current.ProjectNode);
}
public static DefaultMutableTreeNode getProjectCurrentParentNode() {
DefaultMutableTreeNode node = Current.getProjectNode();
//если в дереве еще никто не выделялся, берем корень.
if (node == null)
return Current.getProject().filesTreeRoot;
return (node.getUserObject() instanceof DBProjectFile) ? (DefaultMutableTreeNode) node.getParent() : node;
}
public static File getSelectedDirectory() {
return (File) get(Current.SelectedDirectory);
}
public static DBProjectFile getSelectedFile() {
return (DBProjectFile) get(Current.SelectedFile);
}
//-
public static boolean HasBugReport() {
return get(Current.BugReport) != null;
}
public static PassForm getPassForm() {
return (Visual_DVM_2021.Passes.UI.PassForm) get(Current.PassForm);
}
public static VisualiserTheme getTheme() {
return (VisualiserTheme) get(Current.Theme);
}
//--------------------------------------------------------------------------------
public static ParallelRegion getParallelRegion() {
return (ParallelRegion) get(Current.ParallelRegion);
}
public static boolean HasParallelRegion() {
return get(Current.ParallelRegion) != null;
}
public static boolean HasFunction() {
return get(Current.Function) != null;
}
public static boolean HasSelectedFunction() {
return get(Current.SelectedFunction) != null;
}
public static FuncInfo getFunction() {
return (FuncInfo) get(Current.Function);
}
public static FuncInfo getSelectionFunction() {
return (FuncInfo) get(Current.SelectedFunction);
}
public static boolean HasTasksPackage() {
return get(Current.TasksPackage) != null;
}
public static TasksPackage getTasksPackage() {
return (TasksPackage) get(Current.TasksPackage);
}
public static boolean HasScenario() {
return get(Current.Scenario) != null;
}
public static db_project_info getPackageVersion() {
return (db_project_info) get(Current.PackageVersion);
}
public static boolean HasPackageVersion() {
return get(Current.PackageVersion) != null;
}
public static GlobalData.RemoteSapfor.RemoteSapfor getRemoteSapfor() {
return (RemoteSapfor) get(RemoteSapfor);
}
public static boolean HasRemoteSapfor() {
return get(Current.RemoteSapfor) != null;
}
public static boolean HasSapforConfiguration() {
return get(Current.SapforConfiguration) != null;
}
public static boolean HasSapforTask() {
return get(Current.SapforTask) != null;
}
public static SapforTask_2023 getSapforTask() {
return (SapforTask_2023) get(Current.SapforTask);
}
public static ProjectData.ProjectView getProjectView() {
return (ProjectData.ProjectView) get(ProjectView);
}
public static boolean Check(TextLog Log, Current... names) {
for (Current name : names)
if (get(name) == null)
Log.Writeln_(name.getDescription() + " не выбран(а)");
return Log.isEmpty();
}
public static void CreateAll() {
for (Current c : values())
objects.put(c, null);
}
//-----------------------------------------
public static Object get(Current name) {
return objects.get(name);
}
public static Object set(Current name, Object object) {
objects.replace(name, object);
return object;
}
//применять только для наследников iDBObject
public static boolean CheckID(Current name, int id) {
return (get(name) != null) && (((iDBObject) get(name)).id == id);
}
public static TestingSystem.Sapfor.SapforConfigurationCommand.SapforConfigurationCommand getSapforConfigurationCommand() {
return (TestingSystem.Sapfor.SapforConfigurationCommand.SapforConfigurationCommand) get(Current.SapforConfigurationCommand);
}
public static boolean HasSapforProfile() {
return get(Current.SapforProfile)!=null;
}
public static GlobalData.SapforProfile.SapforProfile getSapforProfile(){
return (GlobalData.SapforProfile.SapforProfile) get(Current.SapforProfile);
}
//--------------------------------------------
public String getDescription() {
switch (this) {
case SapforProfile:
return "Профиль SAPFOR";
case SapforProfileSetting:
return "Настройка профиля SAPFOR";
case SapforEtalonTaskResult:
return "Задача SAPFOR(Эталон)";
case SapforTaskResult:
return "Задача SAPFOR";
case ComponentServerBackup:
return "Версия компонента для восстановления с сервера";
case Subscriber:
return "Адресат";
case SapforTask:
return "Задача SAPFOR";
case SelectedFunction:
return "Выбранный узел графа процедур";
case SapforConfigurationCommand:
return "Команда конфигурации тестирования SAPFOR";
case SapforConfiguration:
return "Конфигурация тестирования SAPFOR";
case RemoteSapfor:
return "SAPFOR";
case PackageVersion:
return "Версия пакетного режима";
case SapforTasksPackage:
return "Пакет задач SAPFOR";
case TasksPackage:
return "Пакет задач";
case Credentials:
return "Учётные данные";
case Function:
return "Функция";
case TestRunTask:
return "Задача на запуск теста";
case TestCompilationTask:
return "Задача на компиляцию теста";
case DVMParameterValue:
return "Параметр DVM системы";
case ParallelRegion:
return "Область распараллеливания";
case Group:
return "Группа тестов DVM";
case Scenario:
return "Сценарий";
case ScenarioCommand:
return "Команда сценария";
case ProjectNode:
return "текущий узел дерева проектов"; //служебка
case Test:
return "Тест";
case Sapfor:
return "SAPFOR";
case Theme:
return "Тема";
case EnvironmentValue:
return "Значение переменной окружения";
case SelectedDirectory:
return "Папка проекта";
case SelectedFile:
return "Файл проекта";
case RunConfiguration:
return "Конфигурация запуска";
case RunTask:
return "Задача на запуск";
case CompilationTask:
return "Задача на компиляцию";
case Makefile:
return "Мейкфайл";
case Module:
return "Языковой модуль мейкфайла";
case RemoteFile:
return "Удалённый файл";
case Component:
return "Компонент";
case Project:
return "Проект";
case File:
return "Файл";
case Root:
return "Корень дерева версий";
case Version:
return "Версия";
case BugReport:
return "Отчёт об ошибке";
case Account:
return "Аккаунт";
case Machine:
return "Машина";
case User:
return "Пользователь";
case Compiler:
return "Компилятор";
case DialogWindow:
return "Диалоговое окно";
default:
return "";
}
}
//---
public enum Mode {
Undefined,
Normal,
Server,
Testing,
Package
}
}

View File

@@ -0,0 +1,31 @@
package Common.Database;
public enum ColumnType {
UNDEFINED,
INT,
LONG,
DOUBLE,
STRING;
public static ColumnType valueOf(Class<?> type) {
ColumnType res = UNDEFINED;
try {
res = valueOf(type.getSimpleName().toUpperCase());
} catch (Exception ignored) {
}
return res;
}
public String getSQLType() {
String res = "";
switch (this) {
case INT:
case LONG:
res = "INTEGER";
break;
case DOUBLE:
res = "REAL";
break;
case STRING:
res = "VARCHAR";
}
return res;
}
}

View File

@@ -0,0 +1,64 @@
package Common.Database;
import Common.UI.Selectable;
import Common.Utils.Index;
import Common.Utils.Utils;
import com.sun.org.glassfish.gmbal.Description;
import java.io.Serializable;
import java.util.Objects;
public abstract class DBObject implements Selectable, Serializable {
//<editor-fold desc="Selectable">
@Description("IGNORE")
private boolean selected = false;
@Override
public boolean isSelected() {
return selected;
}
@Override
public void select(boolean flag) {
if (selected != flag) {
selected = flag;
Index counter = getSelectionCounter();
if (Objects.nonNull(counter)) {
if (selected) counter.Inc();
else counter.Dec();
}
}
}
//</editor-fold>
public Index getSelectionCounter() {
return null;
}
public boolean isVisible() {
return true;
}
public abstract Object getPK();
public String getBDialogName() {
return Utils.Brackets(getDialogName());
}
public String getDialogName() {
return getPK().toString();
}
//статус. например завершенность багрепорта или состояние задачи на запуск. как правило обладает цветным шрифтом.
//как объект будут называть по внешним ключам.
public String getFKName() {
return null;
}
public Object getEmptyFK() {
return null;
}
@Override
public String toString() {
return getBDialogName();
}
//---
public void SynchronizeFields(DBObject src){
selected = src.selected;
}
//------
public DBObject(){}
public DBObject(DBObject src){
this.SynchronizeFields(src);
}
//---------
}

View File

@@ -0,0 +1,34 @@
package Common.Database;
import java.lang.reflect.Field;
public abstract class DBTable<K, D extends DBObject> extends DataSet<K, D> {
//-
public DBTableColumn PK = null;
private Database db = null; //база данных - владелец таблицы.
public DBTable(Class<K> k_in, Class<D> d_in) {
super(k_in, d_in);
for (Field field : d.getFields()) {
DBTableColumn column = new DBTableColumn(field);
if ((!column.Ignore) && !columns.containsKey(column.Name)) {
columns.put(column.Name, column);
if (column.PrimaryKey) PK = column;
}
}
}
public Database getDb() {
return db;
}
public void setDb(Database db_in) {
db = db_in;
}
@Override
public String getPKName() {
return PK.Name;
}
@Override
public String toString() {
StringBuilder res = new StringBuilder(Name + "\n");
for (DBTableColumn c : columns.values())
res.append(c).append("\n");
return res.toString();
}
}

View File

@@ -0,0 +1,50 @@
package Common.Database;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Vector;
public class DBTableColumn {
public String Name = "";
public ColumnType type = ColumnType.UNDEFINED;
public Vector<String> attributes = new Vector<String>();
public boolean Ignore = false;
public boolean PrimaryKey = false;
public boolean AutoIncrement = false;
public Object default_value = null;
public DBTableColumn(Field field) {
ExtractAttributes(field);
PrimaryKey = attributes.contains("PRIMARY KEY");
AutoIncrement = attributes.contains("AUTOINCREMENT");
Name = field.getName();
type = (field.getType().isEnum()) ? ColumnType.STRING : ColumnType.valueOf(field.getType());
Ignore = ((Modifier.isStatic(field.getModifiers()) ||
type.equals(ColumnType.UNDEFINED) ||
attributes.contains("IGNORE")
)
);
}
public String QName() {
return "\"" + Name + "\"";
}
public void ExtractAttributes(Field field) {
attributes = new Vector<String>();
Annotation[] annotations = field.getAnnotations();
for (Annotation a : annotations) {
String[] data = a.toString().split("value=");
if (data.length > 1) {
String[] attributes_ = data[1].split("[,\")]");
for (String attribute : attributes_) {
if (attribute.length() > 0)
attributes.add(attribute);
}
}
}
}
@Override
public String toString() {
String res = QName() + " " + type.getSQLType();
if (attributes.size() > 0)
res += " " + String.join(" ", attributes);
return res;
}
}

View File

@@ -0,0 +1,253 @@
package Common.Database;
import Common.Current;
import Common.UI.DataSetControlForm;
import Common.UI.Menus_2023.DataMenuBar;
import Common.UI.Tables.ColumnFilter;
import Common.UI.UI;
import Common.UI.Windows.Dialog.DBObjectDialog;
import Common.UI.Windows.Dialog.DialogFields;
import Common.Utils.TextLog;
import Visual_DVM_2021.UI.Interface.FilterWindow;
import javax.swing.*;
import java.awt.*;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Vector;
import java.util.stream.Collectors;
public class DataSet<K, D extends DBObject> extends DataSetAnchestor {
//-
public static LinkedHashMap<Class, Object> selections = new LinkedHashMap<>();
//-
public String Name;
public Class<K> k; //класс первичного ключа.
public Class<D> d; //класс объектов.
public LinkedHashMap<K, D> Data = new LinkedHashMap<>(); //наполнение
//-
//<editor-fold desc="UI таблица">
public DataSetControlForm ui_;
protected FilterWindow f_ui;
//</editor-fold>
//-
public LinkedHashMap<Integer, ColumnFilter> columnsFilters = new LinkedHashMap<>();
public DataSet(Class<K> k_in, Class<D> d_in) {
k = k_in;
d = d_in;
Name = d.getSimpleName();
}
public void mountUI(JPanel content_in) {
UI.Clear(content_in);
//-->
ui_ = createUI();
ui_.setContent(content_in);
//-->
if (UI.menuBars.containsKey(getClass())) {
DataMenuBar bar = UI.menuBars.get(getClass());
content_in.add(bar, BorderLayout.NORTH);
setFilterUI(count -> UI.menuBars.get(getClass()).countLabel.setText(String.valueOf(count)));
if (ui_.hasCheckBox())
bar.createSelectionButtons(this);
}
content_in.add(ui_.getDataPanel(), BorderLayout.CENTER);
}
public DataSetControlForm getUi() {
return ui_;
}
public void setFilterUI(FilterWindow ui_in) {
f_ui = ui_in;
}
public void ShowUI() {
if (ui_ != null) {
ui_.Show();
if (f_ui != null)
f_ui.ShowMatchesCount(getRowCountUI());
}
}
public void ShowUI(Object key) {
if (ui_ != null) {
ui_.Show(key);
if (f_ui != null)
f_ui.ShowMatchesCount(getRowCountUI());
}
}
public void ClearUI() {
if ((ui_ != null) && ui_.isShown()) {
ui_.ClearSelection();
ui_.Clear();
if (f_ui != null)
f_ui.ShowNoMatches();
}
}
public void RefreshUI() {
if (ui_ != null) ui_.Refresh();
}
public int getRowCountUI() {
return ui_.getRowCount();
}
public void SetCurrentObjectUI(Object pk) {
if (ui_ != null) {
//todo возможно проверить, что текущий объект уже соответствует ключу, и если да, то ничего делать.
ui_.ClearSelection(); //сброс текущего объекта и всего что с ним связано.
ui_.Select(pk);
}
}
//столбы/ потом переименовать обратно в getUIColumnNames.сейчас так для скорости переноса.
public String[] getUIColumnNames() {
return new String[]{};
}
protected DataSetControlForm createUI() {
return null;
}
public boolean hasUI() {
return ui_ != null;
}
public void CheckAll(boolean flag) {
for (D object : Data.values()) {
if (object.isVisible())
object.Select(flag);
}
RefreshUI();
}
public D getFirstRecord() {
return Data.values().stream().findFirst().orElse(null);
}
public Vector<D> getOrderedRecords(Comparator<D> comparator) {
Vector<D> res = new Vector<>(Data.values());
res.sort(comparator);
return res;
}
@SuppressWarnings("unchecked")
public DBObjectDialog<D, ? extends DialogFields> getDialog() {
return null;
}
public boolean ShowAddObjectDialog(DBObject object) {
return getDialog().ShowDialog(getSingleDescription() + ": добавление", object);
}
public boolean ShowEditObjectDialog(DBObject object) {
DBObjectDialog dialog = getDialog();
dialog.edit = true;
dialog.SetEditLimits();
return dialog.ShowDialog(getSingleDescription() + ": редактирование", object);
}
public boolean ViewObject(DBObject object) {
DBObjectDialog dialog = getDialog();
dialog.SetReadonly();
dialog.ShowDialog(getSingleDescription() + ": просмотр", object);
return false;
}
public boolean ShowDeleteObjectDialog(DBObject object) {
return UI.Warning(getSingleDescription() + " " + object.getBDialogName() + " будет удален(а)");
}
public String QName() {
return "\"" + Name + "\"";
}
public String getPKName() {
return "";
} //получить имя ключевого поля. нужно для таблиц.
public String getPluralDescription() {
return "";
}
public String getSingleDescription() {
return "";
}
//времянки
public Current CurrentName() {
return Current.Undefined;
}
public boolean CheckCurrent(TextLog log) {
return Current.Check(log, CurrentName());
}
public boolean hasCurrent() {
return Current.get(CurrentName()) != null;
}
public void dropCurrent() {
Current.set(CurrentName(), null);
}
public D getCurrent() {
return (D) Current.get(CurrentName());
}
public void setCurrent(D o) {
Current.set(CurrentName(), o);
}
//-
public void put(Object key, D object) {
Data.put((K) key, object);
}
public D get(Object key) {
return Data.get(key);
}
public Object getFieldAt(D object, int columnIndex) {
return null;
}
public void clear() {
Data.clear();
}
public int size() {
return Data.size();
}
public boolean containsKey(Object key) {
return Data.containsKey(key);
}
//-
public Vector<K> getVisibleKeys() {
Comparator<D> comparator = getComparator();
Vector<K> res = new Vector<>();
if (comparator == null) {
for (K key : Data.keySet())
if (Data.get(key).isVisible())
res.add(key);
} else {
Vector<D> raw = new Vector<>();
for (D object : Data.values()) {
if (object.isVisible())
raw.add(object);
}
raw.sort(comparator);
for (D object : raw)
res.add((K) object.getPK());
}
return res;
}
protected Comparator<D> getComparator() {
return null;
}
public int getCheckedCount() {
return (int) Data.values().stream().filter(d -> d.isVisible() && d.isSelected()).count();
}
public Vector<D> getCheckedItems() {
return Data.values().stream().filter(d -> d.isVisible() && d.isSelected()).collect(Collectors.toCollection(Vector::new));
}
public Vector<K> getCheckedKeys() {
return Data.values().stream().filter(DBObject::isSelected).map(d -> (K) d.getPK()).collect(Collectors.toCollection(Vector::new));
}
//--
public void SaveLastSelections() {
if (hasUI()) {
Object lastPk = null;
if ((CurrentName() != Current.Undefined) && (getCurrent() != null))
lastPk = getCurrent().getPK();
if (!selections.containsKey(getClass()))
selections.put(getClass(), lastPk);
else selections.replace(getClass(), lastPk);
}
}
public void RestoreLastSelections() {
if (hasUI()) {
Object lastPk = selections.get(getClass());
// if (lastPk != null) UI.Info(this.getClass() + ":" + lastPk.toString());
if ((CurrentName() != Current.Undefined) && (lastPk != null)) {
// UI.Info(lastPk.toString());
// System.out.println(ui);
// UI.Info("+");
ui_.Select(lastPk);
}
}
}
//---
// применить значение фильтра к фильру объекта напирмер Message.filterValue = text;
public void changeColumnFilterValue(int columnIndex, String text) {
}
public Object getColumnFilterValue(int columnIndex) {
return "";
}
}

View File

@@ -0,0 +1,11 @@
package Common.Database;
import java.util.LinkedHashMap;
public abstract class DataSetAnchestor {
//чтобы обмануть стирание типов во всех параметризованных полях. используется не во всех потомках.
//ибо не все наборы данных относятся к базам.
public LinkedHashMap<String, DBTableColumn> columns = new LinkedHashMap<>();
//то же самое. на самом деле внешние ключи бывают только у таблиц бд
public LinkedHashMap<Class<? extends DBObject>, FKBehaviour> getFKDependencies() {
return new LinkedHashMap<>();
}
}

View File

@@ -0,0 +1,274 @@
package Common.Database;
import Common.Global;
import Common.Utils.Utils;
import Repository.RepositoryRefuseException;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.Vector;
//самый общий интерфейс базы данных, независимо от реализации.
public abstract class Database {
//------------------------------
public LinkedHashMap<Class<? extends DBObject>, DBTable> tables = new LinkedHashMap<>(); //таблицы
protected File file = null;
public Database(File file_in) {
file = file_in;
}
public File getFile() {
return file;
}
public void setFile(File file_in) {
file = file_in;
}
//<editor-fold desc="Общая часть">
public void Connect() throws Exception {
// UI.Print(DebugPrintLevel.Database, "соединение с базой данных " + file.getAbsolutePath());
connect();
}
public void prepareTablesStatements() throws Exception {
}
public void Disconnect() throws Exception {
// UI.Print(DebugPrintLevel.Database, "закрытие соединения с базой данных " + file.getAbsolutePath());
disconnect();
}
public void BeginTransaction() throws Exception {
// UI.Print(DebugPrintLevel.Database, "BEGIN TRANSACTION:");
beginTransaction();
}
public void Commit() throws Exception {
// UI.Print(DebugPrintLevel.Database, "COMMIT");
commit();
}
public void CreateAllTables() throws Exception {
BeginTransaction();
initAllTables(); // все добавления новых таблиц - туть.
for (DBTable table : tables.values()) {
CreateTable(table);
table.setDb(this);
}
Commit();
}
//схема как с проходами. в методе initAllTables добавляем все таблицы через уникальные конструкторы
public void addTable(DBTable table) {
tables.put(table.d, table);
}
public void Synchronize() throws Exception {
BeginTransaction();
for (DBTable table : tables.values())
LoadAll(table);
Init(); //перегружаемая часть синхронизации.
Commit();
}
public void LoadAllTablesWithoutInit() throws Exception {
BeginTransaction();
for (DBTable table : tables.values())
LoadAll(table);
Commit();
}
public <K, D extends DBObject> void LoadAll(DBTable<K, D> table) throws Exception {
table.Data.clear();
loadAll(table);
}
public DBObject Insert(DBObject o) throws Exception {
DBTable table = tables.get(o.getClass());
insert(table, o);
table.Data.put(o.getPK(), o);
return o;
}
public DBObject InsertWithCheck(DBObject o) throws Exception {
DBTable table = tables.get(o.getClass());
if (!table.Data.containsKey(o.getPK())) {
insert(table, o);
table.Data.put(o.getPK(), o);
} else
throw new RepositoryRefuseException("Таблица " + Utils.Brackets(table.Name) + " уже содержит объект с ключом " + Utils.Brackets(o.getPK().toString()));
return o;
}
public DBObject InsertWithCheck_(DBObject o) throws Exception {
DBTable table = tables.get(o.getClass());
if (!table.Data.containsKey(o.getPK())) {
insert(table, o);
table.Data.put(o.getPK(), o);
return o;
}
return null;
}
// не работает с автоинкрементом.
public DBObject UpdateWithCheck(DBObject to_update) throws Exception {
DBTable table = tables.get(to_update.getClass());
if (table.Data.containsKey(to_update.getPK())) {
DBObject o = (DBObject) table.Data.get(to_update.getPK());
o.SynchronizeFields(to_update);
update(table, o);
return o;
} else {
insert(table, to_update);
table.Data.put(to_update.getPK(), to_update);
return to_update;
}
}
public DBObject DeleteWithCheck(DBObject to_delete) throws Exception {
DBTable table = tables.get(to_delete.getClass());
if (table.Data.containsKey(to_delete.getPK())) {
DBObject o = (DBObject) table.Data.get(to_delete.getPK());
delete(table, o);
table.Data.remove(o.getPK());
return o;
} else
throw new RepositoryRefuseException("Таблица " + Utils.Brackets(table.Name) + " не содержит объект с ключом " + Utils.Brackets(to_delete.getPK().toString()));
}
// не работает с автоинкрементом.
public DBObject getObjectCopyByPK(Class table_class, Object pk) throws Exception {
DBTable table = tables.get(table_class);
Object res_ = table_class.newInstance();
DBObject res = (DBObject) res_;
if (table.Data.containsKey(pk)) {
DBObject original = (DBObject) table.Data.get(pk);
res.SynchronizeFields(original);
} else {
table_class.getField(table.getPKName()).set(res, pk); //инче просто синхроним пк. и вставляем
insert(table, res);
}
return res;
}
public boolean checkObjectExistense(Class table_class, Object pk) throws Exception {
DBTable table = tables.get(table_class);
return table.containsKey(pk);
}
public Vector<Object> getObjectsCopies(Class table_class, Vector<Object> keys) {
Vector<Object> res = new Vector<>();
DBTable table = tables.get(table_class);
for (Object key : keys)
if (table.containsKey(key))
res.add(table.Data.get(key));
return res;
}
public void Delete(DBObject o) throws Exception {
DBTable table = tables.get(o.getClass());
delete(table, o);
table.Data.remove(o.getPK());
}
public void DeleteAll(Class<? extends DBObject> c) throws Exception {
DBTable table = tables.get(c);
deleteAll(table);
table.Data.clear();
}
//не вполне обычный случай. подразумевается что поле объекта изменено
//этот же метод закрепляет изменение в бд
//в дальнейшем возможно сделать новое значение поля 2 параметром метода?
public void Update(DBObject o) throws Exception {
DBTable table = tables.get(o.getClass());
update(table, o);
}
public void ResetAI(Class<? extends DBObject> c) throws Exception {
resetAI(tables.get(c));
}
//</editor-fold>
//<editor-fold desc="работа с внешними ключами">
public <O extends DBObject, F extends DBObject> Vector<DBObject> getVectorByFK(O owner, Class<F> fk_class) {
Vector<DBObject> res = new Vector<>();
try {
for (Object o : tables.get(fk_class).Data.values()) {
if (fk_class.getField(owner.getFKName()).get(o).equals(owner.getPK())) res.add((DBObject) o);
}
} catch (Exception e) {
Global.Log.PrintException(e);
}
return res;
}
public <F extends DBObject> void DeleteByFK(DBObject master, Class<F> fk_class) throws Exception {
Vector<DBObject> to_delete = getVectorByFK(master, fk_class);
BeginTransaction();
for (DBObject object : to_delete)
Delete(object);
Commit();
}
//-----------
public <F extends DBObject> void DropByFK(DBObject master, Class<F> fk_class) throws Exception {
Vector<DBObject> to_drop = getVectorByFK(master, fk_class);
BeginTransaction();
for (DBObject object : to_drop) {
fk_class.getField(master.getFKName()).set(object, master.getEmptyFK());
Update(object);
}
Commit();
}
public <K, O extends DBObject, F extends DBObject> LinkedHashMap<K, F> getMapByFK(O owner, Class<F> fk_class, Class<K> key_class) {
LinkedHashMap<K, F> res = new LinkedHashMap<>();
try {
for (Object o : tables.get(fk_class).Data.values()) {
F f = (F) o;
if (fk_class.getField(owner.getFKName()).get(f).equals(owner.getPK())) res.put((K) f.getPK(), f);
}
} catch (Exception e) {
Global.Log.PrintException(e);
}
return res;
}
public <O extends DBObject, F extends iDBObject> LinkedHashMap<Integer, F> getMapByFKi(O owner, Class<F> fk_class) {
return getMapByFK(owner, fk_class, java.lang.Integer.class);
}
//-
public <O extends DBObject, F extends DBObject> Vector<String> getVectorStringByFK(O owner, Class<F> fk_class) {
Vector<String> res = new Vector<>();
try {
for (Object o : tables.get(fk_class).Data.values()) {
if (fk_class.getField(owner.getFKName()).get(o).equals(owner.getPK())) res.add(o.toString());
}
} catch (Exception e) {
Global.Log.PrintException(e);
}
return res;
}
//безопасное получение объекта по первичному ключу.
public <O extends DBObject> O getByPK(Class<O> class_in, Object pk, Object undefined_pk) {
return ((!pk.equals(undefined_pk)) && tables.get(class_in).Data.containsKey(pk)) ?
(O) (tables.get(class_in).Data.get(pk)) : null;
}
public <O extends iDBObject> O getById(Class<O> class_in, int pk) {
return getByPK(class_in, pk, Utils.Nan);
}
public <G, O extends DBObject, F extends DBObject> LinkedHashMap<G, F> getByFKAndGroupBy(O owner, Class<F> fk_class, String group_field, Class<G> group_class) {
LinkedHashMap<G, F> res = new LinkedHashMap<>();
try {
for (Object o : tables.get(fk_class).Data.values()) {
F f = (F) o;
if (fk_class.getField(owner.getFKName()).get(f).equals(owner.getPK()))
res.put((G) (fk_class.getField(group_field).get(f)), f);
}
} catch (Exception e) {
Global.Log.PrintException(e);
}
return res;
}
//</editor-fold>
//<editor-fold desc="Перегружаемая часть">
//-
protected abstract void connect() throws Exception;
protected abstract void disconnect() throws Exception;
//-
protected abstract void beginTransaction() throws Exception;
protected abstract void commit() throws Exception;
//-
protected abstract boolean TableExists(DBTable table) throws Exception;
protected abstract void CreateTable(DBTable table) throws Exception;
protected abstract <K, D extends DBObject> void loadAll(DBTable<K, D> table) throws Exception;
protected abstract void initAllTables() throws Exception;
//перегружаемая часть синхронизации
public void Init() throws Exception {
}
protected abstract void insert(DBTable table, DBObject o) throws Exception;
protected abstract void delete(DBTable table, DBObject o) throws Exception;
protected abstract void deleteAll(DBTable table) throws Exception;
protected abstract void update(DBTable table, DBObject o) throws Exception;
protected abstract void resetAI(DBTable table) throws Exception;
//-
public void SaveLastSelections() {
for (DataSet dataSet : tables.values())
dataSet.SaveLastSelections();
}
public void RestoreLastSelections() {
for (DataSet dataSet : tables.values())
dataSet.RestoreLastSelections();
}
}

View File

@@ -0,0 +1,9 @@
package Common.Database;
public class FKBehaviour {
public FKDataBehaviour data; //поведение данных внешнего ключа при удалении/модификации
public FKCurrentObjectBehaviuor ui; //поведение интерфейсов таблиц внешнего ключа при показе текущего объекта.
public FKBehaviour(FKDataBehaviour data_in, FKCurrentObjectBehaviuor ui_in) {
data = data_in;
ui = ui_in;
}
}

View File

@@ -0,0 +1,5 @@
package Common.Database;
public enum FKCurrentObjectBehaviuor {
PASSIVE,
ACTIVE
}

View File

@@ -0,0 +1,7 @@
package Common.Database;
//поведение таблиц имеющих внешние ключи
public enum FKDataBehaviour {
NONE,
DROP,
DELETE
}

View File

@@ -0,0 +1,261 @@
package Common.Database.SQLITE;
import Common.Database.DBObject;
import Common.Database.DBTable;
import Common.Database.DBTableColumn;
import Common.Database.Database;
import Common.UI.UI;
import Common.Utils.Utils;
import Visual_DVM_2021.Passes.PassException;
import javafx.util.Pair;
import java.io.File;
import java.sql.*;
import java.util.LinkedHashMap;
import java.util.Vector;
import static Common.Utils.Utils.requireNonNullElse;
public abstract class SQLiteDatabase extends Database {
protected Connection conn = null;
protected Statement statement = null;
protected ResultSet resSet = null;
public LinkedHashMap<Class<? extends DBObject>, PreparedStatement> insertStatements = new LinkedHashMap<>();
public LinkedHashMap<Class<? extends DBObject>, PreparedStatement> updateStatements = new LinkedHashMap<>();
public LinkedHashMap<Class<? extends DBObject>, PreparedStatement> deleteStatements = new LinkedHashMap<>();
//->>
public SQLiteDatabase(File file_in) {
super(file_in);
}
@Override
protected void connect() throws Exception {
Class.forName("org.sqlite.JDBC");
for (int i = 0; i < 5; ++i) {
try {
conn = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath());
break;
} catch (Exception ex) {
ex.printStackTrace();
conn = null;
System.gc();
Utils.sleep(2000);
}
}
if (conn == null)
throw new PassException("Внутренняя ошибка sqlite. Не удалось установить соединение за 5 попыток.");
statement = conn.createStatement();
}
@Override
protected void disconnect() throws Exception {
if (conn != null) {
conn.close();
conn = null;
}
if (statement != null) {
statement.close();
statement = null;
}
if (resSet != null) {
resSet.close();
resSet = null;
}
for (PreparedStatement preparedStatement : insertStatements.values()) {
if (preparedStatement != null)
preparedStatement.close();
}
for (PreparedStatement preparedStatement : updateStatements.values()) {
if (preparedStatement != null)
preparedStatement.close();
}
for (PreparedStatement preparedStatement : deleteStatements.values()) {
if (preparedStatement != null)
preparedStatement.close();
}
insertStatements.clear();
updateStatements.clear();
deleteStatements.clear();
//-->>
System.gc();
//->>
}
@Override
protected void beginTransaction() throws Exception {
conn.setAutoCommit(false);
}
@Override
protected void commit() throws Exception {
conn.commit();
conn.setAutoCommit(true);
}
@Override
protected boolean TableExists(DBTable table) throws Exception {
int count = 0;
resSet = statement.executeQuery("SELECT count(*) FROM 'sqlite_master' WHERE type=\"table\" AND name=" + table.QName());
if (resSet.next())
count = resSet.getInt(1);
return count > 0;
}
@Override
public void CreateTable(DBTable table) throws Exception {
if (table.columns.size() > 0) {
if (TableExists(table)) {
Vector<String> existing_columns = new Vector<>();
Vector<String> columns_to_create = new Vector<>();
//предполагаем что первичный ключ и атрибуты не изменятся.
//и что не будет столбов с одинаковыми именами но разными типами.
resSet = statement.executeQuery("pragma table_info(" + table.QName() + ")");
while (resSet.next())
existing_columns.add(resSet.getString(2));
//-
for (String target_column : table.columns.keySet()) {
if (!existing_columns.contains(target_column))
columns_to_create.add(target_column);
}
for (String cn : columns_to_create)
statement.execute("ALTER TABLE " + table.QName() + " ADD COLUMN " + table.columns.get(cn));
} else {
String cmd = "CREATE TABLE if not exists " + table.QName() + " ";
Vector<String> columns_names = new Vector<>();
for (DBTableColumn column : table.columns.values())
columns_names.add(column.toString());
cmd += Utils.RBrackets(String.join(",", columns_names));
statement.execute(cmd);
}
}
}
@Override
public void prepareTablesStatements() throws Exception {
for (DBTable table : tables.values()) {
//---
Vector<String> column_names = new Vector<>();
Vector<String> column_values = new Vector<>();
for (DBTableColumn column : table.columns.values()) {
if (!column.AutoIncrement) {
column_names.add(column.QName());
column_values.add("?");
}
}
insertStatements.put(table.d, conn.prepareStatement(
"INSERT OR REPLACE INTO " + table.QName() + " " +
Utils.RBrackets(String.join(",", column_names)) + " " + "VALUES " +
Utils.RBrackets(String.join(",", column_values))));
//------------------------------------------------------------------------------->>
Vector<String> new_values = new Vector();
for (DBTableColumn column : table.columns.values()) {
if (!column.AutoIncrement) {
new_values.add(column.QName() + "=?");
}
}
updateStatements.put(table.d, conn.prepareStatement(
"UPDATE " + table.QName() + " " +
"SET " + String.join(",", new_values) + " " +
"WHERE (" + table.PK.QName() + "=?)"
));
//---------------------------------------------------------------------------------->>>
deleteStatements.put(table.d, conn.prepareStatement("DELETE FROM " + table.QName() + " WHERE " + table.PK.QName() + " = ?"));
}
}
@Override
protected void delete(DBTable table, DBObject o) throws Exception {
PreparedStatement ps = deleteStatements.get(table.d);
ps.setObject(1, o.getPK());
ps.executeUpdate();
}
protected <K, D extends DBObject> Pair<K, D> readRecord(DBTable<K, D> table) throws Exception {
D o = table.d.newInstance();
for (DBTableColumn column : table.columns.values()) {
Object field_value = null;
switch (column.type) {
case DOUBLE:
field_value = requireNonNullElse(resSet.getDouble(column.Name), 0);
break;
case UNDEFINED:
break;
case INT:
field_value = requireNonNullElse(resSet.getInt(column.Name), 0);
break;
case LONG:
field_value = requireNonNullElse(resSet.getLong(column.Name), 0);
break;
case STRING:
if (table.d.getField(column.Name).getType().isEnum()) {
Class enum_class = Class.forName(table.d.getField(column.Name).getType().getName());
String string = resSet.getString(column.Name);
Object[] enum_constants = enum_class.getEnumConstants();
if (string != null) {
try {
field_value = Enum.valueOf(enum_class, string);
} catch (Exception ignore) {
System.out.println(Utils.Brackets(string) + "not found");
field_value = enum_constants[0];
System.out.println(field_value);
}
} else field_value = enum_constants[0];
} else
field_value = requireNonNullElse(resSet.getString(column.Name), "");
break;
}
if (field_value != null) {
table.d.getField(column.Name).set(o, field_value);
} else
throw new PassException("Ошибка при загрузке поля " + Utils.Brackets(column.Name) + " класса " + Utils.Brackets(table.d.getSimpleName()));
}
return new Pair<>((K) o.getPK(), o);
}
@Override
protected <K, D extends DBObject> void loadAll(DBTable<K, D> table) throws Exception {
resSet = statement.executeQuery("SELECT * FROM " + table.QName());
while (resSet.next()) {
Pair<K, D> record = readRecord(table);
table.Data.put(record.getKey(), record.getValue());
}
}
@Override
protected void insert(DBTable table, DBObject o) throws Exception {
PreparedStatement ps = insertStatements.get(table.d);
if (ps == null)
UI.Info("INSERT NULL");
int i = 1;
for (DBTableColumn column : table.columns.values()) {
if (!column.AutoIncrement) {
ps.setObject(i, o.getClass().getField(column.Name).get(o));
++i;
}
}
ps.execute();
//-->
for (DBTableColumn column : table.columns.values()) {
if (column.AutoIncrement) {
resSet = statement.executeQuery("SELECT MAX(" + column.QName() + ") AS LAST FROM " + table.QName());
String maxId = resSet.getString("LAST");
int intMaxId = Integer.parseInt(maxId);
o.getClass().getField(column.Name).set(o, intMaxId);
break;
}
}
}
@Override
protected void update(DBTable table, DBObject o) throws Exception {
PreparedStatement ps = updateStatements.get(table.d);
if (ps == null)
UI.Info("UPDATE NULL");
int i = 1;
for (DBTableColumn column : table.columns.values()) {
if (!column.AutoIncrement) {
ps.setObject(i, o.getClass().getField(column.Name).get(o));
++i;
}
}
ps.setObject(i, o.getPK());
ps.executeUpdate();
}
@Override
protected void deleteAll(DBTable table) throws Exception {
statement.executeUpdate("DELETE FROM " + table.QName());
}
@Override
protected void resetAI(DBTable table) throws Exception {
statement.executeUpdate("UPDATE SQLITE_SEQUENCE SET SEQ = 0 WHERE NAME =" + table.QName());
}
//--
//https://stackoverflow.com/questions/8558099/sqlite-query-with-byte-where-clause
}

View File

@@ -0,0 +1,43 @@
package Common.Database;
import Common.UI.Menus_2023.StableMenuItem;
import Common.Utils.Utils;
import javax.swing.*;
public class TableFilter<D extends DBObject> {
DataSet table;
public JMenuItem menuItem; //пункт меню фильтра. ( возможно потом сделать и кнопку)
String description;
boolean active = false; //включен ли фильтр
public int count = 0;
protected boolean validate(D object) {
return true;
}
public boolean Validate(D object) {
boolean valid;
if (valid=validate(object))
count++;
return !active || valid;
}
static String getNotActiveIconPath() {
return "/icons/NotPick.png";
}
static String getActiveIconPath() {
return "/icons/Pick.png";
}
public TableFilter(DataSet table_in, String description_in) {
table = table_in;
menuItem = new StableMenuItem((description = description_in)+" (0)");
menuItem.addActionListener(e -> {
active = !active;
Mark();
table.ShowUI();
});
Mark();
}
public void Mark() {
menuItem.setIcon(Utils.getIcon(active ? getActiveIconPath() : getNotActiveIconPath()));
}
public void ShowDescriptionAndCount() {
menuItem.setText(description + " " + Utils.RBrackets(count));
}
}

View File

@@ -0,0 +1,30 @@
package Common.Database;
import Common.Utils.Utils;
import com.sun.org.glassfish.gmbal.Description;
//автоинкрементальный ключ
public class iDBObject extends DBObject {
@Description("PRIMARY KEY,AUTOINCREMENT")
public int id;
@Override
public Object getPK() {
return id;
}
@Override
public String getFKName() {
return getClass().getSimpleName().toLowerCase() + "_id";
}
@Override
public Object getEmptyFK() {
return Utils.Nan;
}
//---
@Override
public void SynchronizeFields(DBObject src) {
super.SynchronizeFields(src);
id = ((iDBObject)src).id;
}
public iDBObject(){}
public iDBObject(iDBObject src){
this.SynchronizeFields(src);
}
}

View File

@@ -0,0 +1,6 @@
package Common.Database;
public abstract class iDBTable<D extends iDBObject> extends DBTable<Integer, D> {
public iDBTable(Class<D> d_in) {
super(Integer.class, d_in);
}
}

View File

@@ -0,0 +1,35 @@
package Common.Database;
import Common.Utils.Utils;
import com.sun.org.glassfish.gmbal.Description;
public abstract class nDBObject extends DBObject {
String getClassNameL() {
return getClass().getSimpleName().toLowerCase();
}
@Description("PRIMARY KEY, UNIQUE")
public String id = "";
@Override
public Object getPK() {
return id;
}
@Override
public String getFKName() {
return getClassNameL() + "_id";
}
@Override
public Object getEmptyFK() {
return "";
}
public void genName() {
id = Utils.getDateName(getClassNameL());
}
//-
@Override
public void SynchronizeFields(DBObject src) {
super.SynchronizeFields(src);
id = ((nDBObject)src).id;
}
public nDBObject(nDBObject src){
this.SynchronizeFields(src);
}
public nDBObject(){}
}

View File

@@ -0,0 +1,32 @@
package Common.Database;
import java.util.Date;
//объект репозитория. ключ имя, и есть данные отправителя.
public class rDBObject extends nDBObject {
public String sender_name = "";
public String sender_address = "";
public String description = "";
//-
public long date = 0;
public long change_date;
public Date getDate() {
return new Date(date);
}
public Date getChangeDate() {
return new Date(change_date);
}
@Override
public void SynchronizeFields(DBObject src) {
super.SynchronizeFields(src);
rDBObject r = (rDBObject) src;
sender_name = r.sender_name;
sender_address = r.sender_address;
description = r.description;
date = r.date;
change_date = r.change_date;
}
public rDBObject(rDBObject src) {
this.SynchronizeFields(src);
}
public rDBObject() {
}
}

403
src/Common/Global.java Normal file
View File

@@ -0,0 +1,403 @@
package Common;
import Common.Database.DataSet;
import Common.UI.Menus_2023.ComponentsMenuBar.ComponentsMenuBar;
import Common.UI.UI;
import Common.Utils.Utils;
import GlobalData.GlobalDatabase;
import GlobalData.Settings.DBSetting;
import GlobalData.Settings.SettingName;
import ProjectData.ProjectView;
import Repository.Component.*;
import Repository.Component.PerformanceAnalyzer.PerformanceAnalyzer;
import Repository.Component.Sapfor.MessagesServer;
import Repository.Component.Sapfor.Sapfor_F;
import Repository.Component.Sapfor.TransformationPermission;
import Repository.Server.ComponentsServer;
import TestingSystem.TestingServer;
import Visual_DVM_2021.Passes.All.PerformSapforTasksPackage;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import Visual_DVM_2021.UI.Interface.Loggable;
import org.apache.commons.io.FileUtils;
import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
import org.fife.ui.rsyntaxtextarea.TokenMakerFactory;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.util.Vector;
public class Global {
//кронтаб и перезагрузка
//https://snipp.ru/raznoe/crontab
// /var/spool/cron/crontabs/testuser что менять
//https://saribzhanov.ru/tehno/perezagruzka-ubuntu-po-cron/ //раз в сутки
//testuser ALL=NOPASSWD:/sbin/reboot
//0 2 2,15 * * reboot &>/var/log/reboot.log
//https://unix.stackexchange.com/questions/117148/how-can-i-run-reboot-as-a-normal-user-without-needing-to-enter-a-password
public static final String ServerAddress = "alex-freenas.ddns.net";
public static final String MailAddress = "sapfor.tracker@internet.ru";
// public static final String MailPassword = "3s4w9e5fs3c1a89AA"; основной пароль.
public static final String MailPassword = "knKn2PpfrC348ZxHtMnT"; //пароль для сапфора как внешнего приложения.
public static final String dateNaN = "NaN";
//--------------------------------------------------
//текущая папка системы. в отличие от шарпа никогда не должна меняться.
public static final String components = "Components";
public static final String data = "Data";
public static final String Bugs = "Bugs";
public static final String BackUps = "BackUps";
public static final String DataBackUps = "DataBackUps";
public static final String Temp = "Temp";
public static final String Projects = "Projects";
public static final String CompilationTasks = "CompilationTasks";
public static final String RunTasks = "RunTasks";
public static final String Sts = "Sts";
public static final String Repo = "Repo";
public static final String Tests = "Tests";
public static final String Packages = "Packages";
public static final String PerformanceAnalyzer = "PerformanceAnalyzer";
public static GlobalProperties properties = new GlobalProperties();
//</editor-fold>
//------------------------------------------------------
public static boolean enable_text_changed = false;
//---
public static boolean files_multiselection = false;
public static boolean versions_multiselection = false;
//---
public static TransformationPermission transformationPermission = TransformationPermission.None;
//??
public static DataSet<ComponentType, Component> Components = null;
public static MessagesServer messagesServer = null;
//--------------------------------------------------
public static GlobalDatabase db = null;
public static String[] admins_mails = new String[]{
"vmk-post@yandex.ru",
"79854210702@ya.ru"
};
//-
public static String Home;
public static File ComponentsDirectory;
public static File DataDirectory;
public static File BugReportsDirectory;
public static File BackUpsDirectory;
public static File TempDirectory;
public static File ProjectsDirectory;
public static File CompilationTasksDirectory;
public static File RunTasksDirectory;
public static File StsDirectory;
public static File RepoDirectory;
public static File TestsDirectory;
public static File PerformanceAnalyzerDirectory;
public static File DataBackUpsDirectory;
public static File PackagesDirectory;
public static File SapforPackagesDirectory;
//------------------------------------------------------------------
public static Visualiser visualiser = null;
public static Visualizer_2 visualizer_2 = null;
public static PerformanceAnalyzer performanceAnalyzer = null;
//------------------------------------------------------------------
public static ComponentsServer componentsServer = new ComponentsServer();
public static TestingServer testingServer = new TestingServer();
//------------------------------------------------------------------
public static boolean isWindows;
public static int bad_state = 0;
public static int need_update = 0;
public static int need_publish = 0;
//------------------------------------------------------------------------
public static Loggable Log;
public static void SynschronizeProperties() {
//---- NEW -----
try {
File new_propertiesFile = Paths.get(Home, "properties").toFile();
if (new_propertiesFile.exists()) {
String packed = FileUtils.readFileToString(new_propertiesFile, Charset.defaultCharset());
properties = Utils.gson.fromJson(packed, GlobalProperties.class);
}
//пусть всегда в него пишет. с учетом того, что новые настройки могут появиться.
FileUtils.writeStringToFile(new_propertiesFile, Utils.jsonToPrettyFormat(Utils.gson.toJson(properties)));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void CheckVisualiserDirectories() {
Utils.CheckDirectory(ComponentsDirectory = Paths.get(Home, components).toFile());
Utils.CheckAndCleanDirectory(TempDirectory = Paths.get(Home, Temp).toFile());
Utils.CheckDirectory(DataDirectory = Paths.get(Home, data).toFile());
//-
Utils.CheckDirectory(RepoDirectory = Paths.get(Home, Repo).toFile());
Utils.CheckDirectory(BugReportsDirectory = Paths.get(Home, Bugs).toFile());
Utils.CheckDirectory(BackUpsDirectory = Paths.get(Home, BackUps).toFile());
Utils.CheckDirectory(ProjectsDirectory = Paths.get(Home, Projects).toFile());
Utils.CheckDirectory(CompilationTasksDirectory = Paths.get(Home, CompilationTasks).toFile());
Utils.CheckDirectory(RunTasksDirectory = Paths.get(Home, RunTasks).toFile());
Utils.CheckDirectory(StsDirectory = Paths.get(Home, Sts).toFile());
Utils.CheckDirectory(TestsDirectory = Paths.get(Home, Tests).toFile());
Utils.CheckDirectory(PerformanceAnalyzerDirectory = Paths.get(Home, PerformanceAnalyzer).toFile());
Utils.CheckDirectory(SapforPackagesDirectory = Paths.get(Home, "SapforTasksPackages").toFile());
}
public static void CheckServerDirectories() {
Utils.CheckDirectory(ComponentsDirectory = Paths.get(Home, components).toFile());
Utils.CheckAndCleanDirectory(TempDirectory = Paths.get(Home, Temp).toFile());
Utils.CheckDirectory(DataDirectory = Paths.get(Home, data).toFile());
//-
Utils.CheckDirectory(BugReportsDirectory = Paths.get(Home, Bugs).toFile());
Utils.CheckDirectory(DataBackUpsDirectory = Paths.get(Home, DataBackUps).toFile());
}
public static void CheckTestingSystemDirectories() {
Utils.CheckDirectory(ComponentsDirectory = Paths.get(Home, components).toFile());
Utils.CheckAndCleanDirectory(TempDirectory = Paths.get(Home, Temp).toFile());
Utils.CheckDirectory(DataDirectory = Paths.get(Home, data).toFile());
//-
Utils.CheckDirectory(TestsDirectory = Paths.get(Home, Tests).toFile());
Utils.CheckDirectory(RepoDirectory = Paths.get(Home, Repo).toFile());
Utils.CheckDirectory(PackagesDirectory = Paths.get(Home, Packages).toFile());
}
public static void CreateLog() {
Log = new Loggable() {
@Override
public String getLogHomePath() {
return Paths.get(Home, "Components").toString();
}
@Override
public String getLogName() {
return "VisualDVM";
}
};
Log.ClearLog();
}
//-
public static void FinishApplication() {
try {
if (db != null) db.Disconnect();
if (componentsServer.db != null)
componentsServer.db.Disconnect();
if (testingServer.db != null)
testingServer.db.Disconnect();
if (visualizer_2 != null)
visualizer_2.Shutdown();
if (messagesServer != null)
messagesServer.Shutdown();
if (performanceAnalyzer != null)
performanceAnalyzer.Shutdown();
} catch (Exception ex) {
if (Log != null) {
Log.PrintException(ex);
} else {
ex.printStackTrace();
}
}
System.exit(0);
}
public static void ActivateDB() throws Exception {
db = new GlobalDatabase();
db.Connect();
db.CreateAllTables();
db.prepareTablesStatements();
db.Synchronize();
}
public static void RefreshUpdatesStatus() {
Components.RefreshUI();
ValidateComponentsStates();
if (UI.HasNewMainWindow())
UI.getMainWindow().ShowUpdatesIcon();
}
public static boolean ValidateComponentsStates() {
bad_state = need_update = need_publish = 0;
for (Component component : Components.Data.values()) {
if (component.isVisible()) {
switch (component.getState()) {
case Not_found:
case Unknown_version:
case Old_version:
if (component.isNecessary())
bad_state++;
component.Select(true);
break;
case Needs_update:
need_update++;
component.Select(true);
break;
case Needs_publish:
need_publish++;
break;
default:
component.Select(false);
break;
}
}
}
return (bad_state == 0);
}
public static DBSetting getSetting(SettingName settingName) throws Exception {
switch (Current.mode) {
case Normal:
return db.settings.get(settingName);
default:
return null;
}
}
public static void changeSetting(SettingName settingName, Object new_value) throws Exception {
Pass_2021.passes.get(PassCode_2021.UpdateSetting).Do(settingName, new_value);
}
public static String packSapforSettings() {
Vector<String> res_ = new Vector<>();
Vector<SettingName> forbidden = new Vector<>();
forbidden.add(SettingName.GCOVLimit);
forbidden.add(SettingName.Precompilation);
forbidden.add(SettingName.DVMConvertationOptions);
forbidden.add(SettingName.SaveModifications);
for (DBSetting setting : db.settings.getSettingsByOwner(ComponentType.SapforOptions)) {
if (!forbidden.contains(setting.Name))
res_.add(setting.Value);
}
return String.join("|", res_);
}
//--
public static void NormalMode(int port) throws Exception {
isWindows = System.getProperty("os.name").startsWith("Windows");
CheckVisualiserDirectories();
CreateLog();
//-
visualizer_2 = new Visualizer_2(port);
visualizer_2.Connect();
visualizer_2.refreshPid();
//если делать раньше, то не удастся убить сервер.
if (Utils.ContainsCyrillic(Global.Home)) {
UI.Info("В пути к корневой папке " + Utils.DQuotes(Global.Home) + "\n" +
"Найдены русские буквы.\n" +
"Визуализатор завершает работу."); //
FinishApplication();
}
messagesServer = new MessagesServer();
messagesServer.Start();
//создание списков служебных объектов
Current.CreateAll();
UI.CreateAll();
Pass_2021.CreateAll();
Utils.init();
//единственное меню до остальных.
UI.menuBars.put(ComponentsSet.class, new ComponentsMenuBar());
Components = new ComponentsSet();
Current.set(Current.ProjectView, ProjectView.Files);
Components.put(ComponentType.Visualiser, visualiser = new Visualiser());
Components.put(ComponentType.Sapfor_F, (Component) Current.set(Current.Sapfor, new Sapfor_F()));
Components.put(ComponentType.Visualizer_2, visualizer_2);
Components.put(ComponentType.PerformanceAnalyzer, performanceAnalyzer = new PerformanceAnalyzer());
Components.put(ComponentType.Instruction, new Instruction());
//-
for (Component component : Components.Data.values())
if (component.isVisible()) component.InitialVersionCheck();
//-
UI.CreateComponentsForm();
AbstractTokenMakerFactory atmf = (AbstractTokenMakerFactory) TokenMakerFactory.getDefaultInstance();
atmf.putMapping("text/FortranSPF", "Common.UI.Themes.FortranSPFTokenMaker");
atmf.putMapping("text/FreeFortranSPF", "Common.UI.Themes.FreeFortranSPFTokenMaker");
// FoldParserManager.get().addFoldParserMapping("text/FortranSPF", new FortranFolder()); блоки кода. todo
//-------->>
//-------->>
if (properties.AutoUpdateSearch)
Pass_2021.passes.get(PassCode_2021.GetComponentsActualVersions).Do();
ValidateComponentsStates();
if ((need_update > 0) || (bad_state > 0)) {
boolean flag = true;
do {
UI.ShowComponentsWindow();
if (flag = (!ValidateComponentsStates())) {
if (!UI.Question("Найдено " + bad_state + " некорректных необходимых компонент.Работа визуализатора невозможна.\n" +
"Вернуться к окну компонент"
)) {
UI.Info("Визуализатор завершает работу.");
FinishApplication();
}
}
} while (flag);
}
//---
ActivateDB(); //тут current getAccount; роль по умолчанию всегда неизвестна.
///--------------
Pass_2021.passes.get(PassCode_2021.CheckAccount).Do();
//---------------
componentsServer.ActivateDB();
testingServer.ActivateDB();
//-- чисто чтобы создать таблицы. соединения на стороне клиента не предвидится.
testingServer.SetCurrentAccountDB(Current.getAccount().email);
//--->>>
if (db.settings.get(SettingName.AutoBugReportsLoad).toBoolean())
Pass_2021.passes.get(PassCode_2021.SynchronizeBugReports).Do();
//--
if (db.settings.get(SettingName.AutoTestsLoad).toBoolean())
Pass_2021.passes.get(PassCode_2021.SynchronizeTests).Do();
Pass_2021.CheckAllStats();
Current.getSapfor().refreshPid(); //без сапфора сюда это все равно не дойдет.
UI.CreateMenus();
UI.CreateWindows();
}
public static void ServerMode() throws Exception {
isWindows = false;
CheckServerDirectories();
CreateLog();
componentsServer = new ComponentsServer();
componentsServer.ActivateDB();
componentsServer.Start();
System.exit(0);
}
public static void TestingSystemMode() throws Exception {
isWindows = false;
CheckTestingSystemDirectories();
CreateLog();
testingServer = new TestingServer();
testingServer.ActivateDB();
testingServer.Start();
System.exit(0);
}
public static void PackageMode() throws Exception {
Log = new Loggable() {
@Override
public String getLogHomePath() {
return Home;
}
@Override
public String getLogName() {
return "PackageMode";
}
};
Log.ClearLog();
//--
Pass_2021 pass = new PerformSapforTasksPackage();
pass.Do(Home);
//--
}
//---
public static void Init(String... args) {
System.out.println("VisualSapfor.jar started..");
Home = System.getProperty("user.dir"); //если Linux, дает без слеша в конце !!!
System.out.println("home directory is" + Utils.Brackets(Home));
//---
SynschronizeProperties();
Current.mode = properties.Mode;
System.out.println("mode is " + Current.mode);
try {
switch (Current.mode) {
case Normal:
NormalMode(Integer.parseInt(args[1]));
break;
case Server:
ServerMode();
break;
case Testing:
TestingSystemMode();
break;
case Package:
PackageMode();
break;
case Undefined:
break;
}
} catch (Exception ex) {
System.out.println("VISUALISER FAILED");
ex.printStackTrace();
if (Global.Log != null)
Global.Log.PrintException(ex);
FinishApplication();
}
}
}

View File

@@ -0,0 +1,87 @@
package Common;
import com.google.gson.annotations.Expose;
import java.io.File;
import java.nio.file.Paths;
public class GlobalProperties extends Properties {
@Expose
public Current.Mode Mode = Current.Mode.Normal;
//---
@Expose
public int SocketTimeout = 5000;
@Expose
public boolean OldServer = false;
//---
@Expose
public String SMTPHost = "smtp.mail.ru";
@Expose
public int SMTPPort = 465;
@Expose
public int MailSocketPort = 465;
//---
@Expose
public String BackupWorkspace = "_sapfor_x64_backups";
@Expose
public int BackupHour = 5;
@Expose
public int BackupMinute = 0;
@Expose
public boolean EmailAdminsOnStart = false;
//---
@Expose
public boolean AutoUpdateSearch = true;
// настройки визуализатора. по крайней мере, флаги.
@Expose
public boolean ConfirmPassesStart = true;
@Expose
public boolean ShowPassesDone = true;
@Expose
public boolean FocusPassesResult = true;
//-
@Expose
public String GlobalDBName = "db7.sqlite";
@Expose
public String ProjectDBName = "new_project_base.sqlite";
@Expose
public String BugReportsDBName = "bug_reports.sqlite";
@Expose
public String TestsDBName = "tests.sqlite";
//-
@Expose
public int ComponentsWindowWidth = 650;
@Expose
public int ComponentsWindowHeight = 250;
//-
@Expose
public String VisualiserPath = "";
@Expose
public String Sapfor_FPath = "";
@Expose
public String Visualizer_2Path = "";
@Expose
public String InstructionPath = "";
@Expose
public String PerformanceAnalyzerPath = "";
@Expose
public int ComponentsBackUpsCount=10;
@Expose
public long SapforTaskMaxId = 0; //вероятно, временно. когда перейдем на удаленную машину.
//-
@Override
public String getFieldDescription(String fieldName) {
switch (fieldName) {
case "ShowPassesDone":
return "Сообщать об успешном выполнении проходов";
case "ConfirmPassesStart":
return "Запрашивать подтверждения начала выполнения проходов";
case "FocusPassesResult":
return "Переходить на результирующую вкладку проходов по их завершении";
default:
return "?";
}
}
@Override
public File getFile() {
return Paths.get(System.getProperty("user.dir"),"properties").toFile();
}
}

View File

@@ -0,0 +1,3 @@
package Common;
public class PackageModeSupervisor {
}

View File

@@ -0,0 +1,50 @@
package Common;
import Common.UI.Menus_2023.StableMenuItem;
import Common.Utils.Utils;
import org.apache.commons.io.FileUtils;
import javax.swing.*;
import java.io.File;
public abstract class Properties {
public void addFlagMenuItem(JMenu menu, String fieldName) {
JMenuItem menu_item = new StableMenuItem(getFieldDescription(fieldName),
getFlag(fieldName) ? "/icons/Pick.png" : "/icons/NotPick.png");
//-
menu_item.addActionListener(e -> {
switchFlag(fieldName);
Update();
menu_item.setIcon(Utils.getIcon(getFlag(fieldName) ? "/icons/Pick.png" : "/icons/NotPick.png"));
});
menu.add(menu_item);
}
public boolean getFlag(String fieldName) {
boolean field = false;
try {
field = (boolean) GlobalProperties.class.getField(fieldName).get(this);
//
} catch (Exception ex) {
ex.printStackTrace();
}
return field;
}
public void switchFlag(String fieldName) {
boolean field = false;
try {
field = (boolean) GlobalProperties.class.getField(fieldName).get(this);
GlobalProperties.class.getField(fieldName).set(this, !field);
//
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void Update() {
try {
FileUtils.write(getFile(), Utils.jsonToPrettyFormat(Utils.gson.toJson(this)));
} catch (Exception e) {
e.printStackTrace();
}
}
//--
public abstract String getFieldDescription(String fieldName);
public abstract File getFile();
}

View File

@@ -0,0 +1,9 @@
package Common.UI.ComboBox;
import Common.UI.Menus.TextComboBoxMenu;
import javax.swing.*;
public class StyledTextComboBox extends JComboBox<String> {
public StyledTextComboBox() {
setComponentPopupMenu(new TextComboBoxMenu(this));
}
}

View File

@@ -0,0 +1,53 @@
package Common.UI;
import Common.Global;
import javax.swing.*;
import java.awt.*;
//класс, представляющий собой прокручиваемую панель, на которой лежит нечто.
public class ControlForm<C extends Component> {
public C control = null;
protected Class<C> control_class;
protected JPanel content; //задник.
public JScrollPane scroll = null;
public ControlForm(Class<C> class_in) {
control_class = class_in;
setContent(new JPanel(new BorderLayout()));
}
//нужно будет вывестии сделать нормальные формы для деревьев а не ручное создание.
public JPanel getContent() {
return content;
}
public void setContent(JPanel content_in) {
content = content_in;
}
//-
public void Show() {
Clear();
CreateControl();
//------------------------
scroll = new JScrollPane(control);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
public void CreateControl() {
try {
control = control_class.newInstance();
} catch (Exception e) {
Global.Log.PrintException(e);
}
}
public boolean isShown() {
return control != null;
}
public void Clear() {
control = null; //очищено.
}
public void Refresh() {
if (control != null)
refresh();
}
//-
protected void refresh() {
} //перерисовать контрол.
}

View File

@@ -0,0 +1,19 @@
package Common.UI;
import Common.Current;
import java.awt.*;
public class ControlWithCurrentForm<C extends Component> extends ControlForm<C> {
public ControlWithCurrentForm(Class<C> class_in) {
super(class_in);
}
//-
public Current CurrentName() {
return Current.Undefined;
}
public void ShowCurrentObject() throws Exception {
}
public void ShowNoCurrentObject() throws Exception {
}
public void MouseAction2() throws Exception {
}
}

View File

@@ -0,0 +1,7 @@
package Common.UI;
import Common.Database.DBObject;
public interface DataControl {
DBObject getRowObject(int rowIndex); //получить объект, сответствующий данной строке.
void SelectRowByPK(Object pk);
//выделить строку где лежит объект с данным первичным ключом.
}

View File

@@ -0,0 +1,13 @@
package Common.UI;
import Common.Current;
public interface DataControl_OLD {
//todo скорее всего устареет.
default Current getCurrent() {
return Current.Undefined;
}
//-?
default void ShowCurrentObject() throws Exception {
}
default void ShowNoCurrentObject() throws Exception {
}
}

View File

@@ -0,0 +1,329 @@
package Common.UI;
import Common.Current;
import Common.Database.DBObject;
import Common.Database.DBTable;
import Common.Database.DataSet;
import Common.Database.FKBehaviour;
import Common.Global;
import Common.UI.Menus.TableMenu;
import Common.UI.Tables.ColumnInfo;
import Common.UI.Tables.DataTable;
import Common.UI.Tables.Grid.GridAnchestor;
import Common.Utils.Utils;
import GlobalData.Grid.Grid;
import javax.swing.*;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Vector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static Common.UI.Tables.TableEditors.EditorSelect;
import static Common.UI.Tables.TableRenderers.RendererSelect;
public class DataSetControlForm extends ControlWithCurrentForm<DataTable> {
protected JPanel dataPanel;
protected DataSet dataSource;
public JPanel getDataPanel() {
return dataPanel;
}
protected int current_row_i;
protected boolean events_on = true;
protected String colNamesAndSizes = "";
protected Vector<ColumnInfo> columns = new Vector<>();
public DataSetControlForm(DataSet dataSource_in) {
this(dataSource_in, DataTable.class);
}
public DataSetControlForm(DataSet dataSource_in, Class tableClass) {
super(tableClass);
dataSource = dataSource_in;
//---
dataPanel = new JPanel(new BorderLayout());
content.add(dataPanel, BorderLayout.CENTER);
}
@Override
public void Show() {
super.Show();
dataPanel.add(scroll);
dataPanel.updateUI();
}
@Override
public void Clear() {
super.Clear();
UI.Clear(dataPanel);
}
public DataSet getDataSource() {
return dataSource;
}
@Override
public Current CurrentName() {
return getDataSource().CurrentName();
}
public void SaveColumns() {
if (Global.db != null) {
try {
if ((CurrentName() != Current.Undefined)) {
Vector<String> widths = IntStream.range(0, columns.size()).mapToObj(i -> String.valueOf(control.getColumnModel().getColumn(i).getWidth())).collect(Collectors.toCollection(Vector::new));
String packed = String.join("|", widths);
Grid grid;
if (Global.db.grids.containsKey(CurrentName())) {
grid = Global.db.grids.get(CurrentName());
} else {
grid = new Grid(CurrentName());
Global.db.Insert(grid);
}
grid.sizes = packed;
Global.db.Update(grid);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public boolean hasCheckBox() {
return false;
}
private Vector<String> getHeaders() {
return columns.stream().map(ColumnInfo::getName).collect(Collectors.toCollection(Vector::new));
}
protected void CreateColumnsInfo() {
columns.clear();
columns.add(new ColumnInfo(getDataSource().getPKName()));
if (hasCheckBox()) {
columns.add(new ColumnInfo("", RendererSelect, EditorSelect));
columns.get(1).setMinWidth(25);
columns.get(1).setMaxWidth(25);
}
Arrays.stream(getDataSource().getUIColumnNames()).forEach(name -> columns.add(new ColumnInfo(name)));
AdditionalInitColumns();
}
protected void AdditionalInitColumns() {
//уточнение инфы по столбцам.
}
@SuppressWarnings("unchecked")
@Override
public void CreateControl() {
CreateColumnsInfo();
GridAnchestor table_data_model = new GridAnchestor(getHeaders(), dataSource.getVisibleKeys()) {
@SuppressWarnings("unchecked")
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object key = data.get(rowIndex);
if (columnIndex == 0)
return key;
DBObject object = getDataSource().get((key));
if ((columnIndex == 1) && hasCheckBox())
return object.isSelected();
return getDataSource().getFieldAt(object, columnIndex);
}
@Override
public boolean isCellEditable(int row, int col) {
return columns.get(col).isEditable();
}
//------------------------------------------------------------------------------------
@Override
public void setValueAt(Object value, int row, int col) {
fireTableCellUpdated(row, col);
}
};
control = new DataTable(table_data_model) {
@Override
public TableMenu CreateMenu() {
return new TableMenu(this);
}
//строго говоря эта штука нужна только для рендереров и едиторов клеток.
@Override
public DBObject getRowObject(int rowIndex) {
//вот так делать НЕЛЬЗЯ. модель только для внутреннего пользования
// Object key = table_data_model.data.get(rowIndex);
//из таблицы можно пользоваться только getValueAt
//иначе сортировка не будет работать.
Object key = getValueAt(rowIndex, 0);
return getDataSource().get(key);
}
//-----------------------------NEW-------------------------------------
@Override
public void CorrectColumnsSizes() {
if ((Global.db != null) && CurrentName() != Current.Undefined && Global.db.grids.containsKey(CurrentName())) {
//Undefined может оказаться в таблице, например если енум устарел. Поэтому надо проверять.
if (!getColumnsProfile().equalsIgnoreCase(colNamesAndSizes)) {
Grid grid = Global.db.grids.get(CurrentName());
String[] data = grid.sizes.split("\\|");
for (int i = 0; i < columns.size(); ++i) {
if (i <= (data.length - 1)) {
int width = Integer.parseInt(data[i]);
getColumnModel().getColumn(i).setPreferredWidth(width);
getColumnModel().getColumn(i).setWidth(width);
}
}
}
} else
super.CorrectColumnsSizes(); //обычный авторазмер.
}
public String getColumnsProfile() {
String res = "";
for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
if (i > 0) res += ",";
TableColumn column = getColumnModel().getColumn(i);
res += column.getHeaderValue();
res += ":";
res += column.getWidth();
}
return res;
}
@Override
public void Init() {
for (int i = 0; i < columns.size(); i++) {
ColumnInfo columnInfo = columns.get(i);
if (columnInfo.isVisible()) {
if (columnInfo.hasRenderer())
getColumnModel().getColumn(i).setCellRenderer(UI.TableRenderers.get(columnInfo.getRenderer()));
if (columnInfo.hasEditor())
getColumnModel().getColumn(i).setCellEditor(UI.TableEditors.get(columnInfo.getEditor()));
if (columnInfo.hasMaxWidth())
getColumnModel().getColumn((i)).setMaxWidth(columnInfo.getMaxWidth());
if (columnInfo.hasMinWidth())
getColumnModel().getColumn((i)).setMinWidth(columnInfo.getMinWidth());
} else {
getColumnModel().getColumn(i).setMinWidth(0);
getColumnModel().getColumn(i).setMaxWidth(0);
}
}
//обновление в БД при ручном изменении размера столбиков.--------->>
getTableHeader().addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent arg0) {
System.out.println("Header mouse released");
String new_colNamesAndSizes = getColumnsProfile();
// check if changed, if yes, persist...
if (!colNamesAndSizes.equals(new_colNamesAndSizes)) {
colNamesAndSizes = new_colNamesAndSizes;
SaveColumns();
System.out.println("columns updated");
}
}
});
//------------------------->>
}
};
if (CurrentName() != Current.Undefined) {
current_row_i = Utils.Nan;
ListSelectionModel selModel = control.getSelectionModel();
selModel.addListSelectionListener(e -> {
int row = control.getSelectedRow();
if ((row >= 0)) {
if (row != current_row_i) {
current_row_i = row;
// System.out.println("current row_i="+current_row_i);
getDataSource().setCurrent(control.getRowObject(row));
if (events_on) {
try {
ShowCurrentObject();
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
}
} else {
current_row_i = Utils.Nan;
// System.out.println("no current row_i="+current_row_i);
getDataSource().dropCurrent();
if (events_on) {
try {
ShowNoCurrentObject();
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
}
});
//двойной клик мыши.------------------------------------------------------
control.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getClickCount() == 2) && (dataSource.getCurrent() != null)) {
try {
MouseAction2();
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
}
});
//----------------------------------------------------------------------------
//при переотображении таблицы скидываем текущий объект!!
getDataSource().dropCurrent();
try {
ShowNoCurrentObject();
} catch (Exception e) {
Global.Log.PrintException(e);
}
}
//---
/*
if (hasCheckBox()) {
TableColumn column = control.getColumnModel().getColumn(1)
column.setHeaderRenderer(new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return null;
}
});
}
*/
}
@Override
protected void refresh() {
control.CorrectSizes();
}
public void Show(Object pk) {
Show();
Select(pk);
}
public void Select(Object pk) {
if (isShown())
control.SelectRowByPK(pk);
}
public void ClearSelection() {
if (isShown())
control.clearSelection(); //строка сбросится сама. благодаря сбросу события выбора
}
public int getRowCount() {
return control.getRowCount();
}
@Override
public void ShowCurrentObject() throws Exception {
if (dataSource instanceof DBTable) {
DBTable table = (DBTable) dataSource;
for (Class dep : table.getFKDependencies().keySet()) {
FKBehaviour behaviour = table.getFKDependencies().get(dep);
switch (behaviour.ui) {
case ACTIVE:
table.getDb().tables.get(dep).ShowUI();
break;
case PASSIVE:
break;
}
}
}
}
@Override
public void ShowNoCurrentObject() throws Exception {
if (dataSource instanceof DBTable) {
DBTable table = (DBTable) dataSource;
for (Class dep : table.getFKDependencies().keySet()) {
FKBehaviour behaviour = table.getFKDependencies().get(dep);
switch (behaviour.ui) {
case ACTIVE:
table.getDb().tables.get(dep).ClearUI();
break;
case PASSIVE:
break;
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
package Common.UI;
public enum DebugPrintLevel {
Undefined,
Passes,
Project;
public String getDescription() {
return toString();
}
public boolean isEnabled() {
switch (this) {
case Passes:
return true;
default:
return false;
}
}
}

View File

@@ -0,0 +1,33 @@
package Common.UI.DragDrop;
import javax.swing.*;
/**
* A simple example showing how to use {@link FileDrop}
*
* @author Robert Harder, rob@iharder.net
*/
public class ExampleDrop {
/*
/** Runs a sample program that shows dropped files */
public static void kek(String[] args) {
javax.swing.JFrame frame = new javax.swing.JFrame("FileDrop");
//javax.swing.border.TitledBorder dragBorder = new javax.swing.border.TitledBorder( "Drop 'em" );
final javax.swing.JTextArea text = new javax.swing.JTextArea();
frame.getContentPane().add(
new javax.swing.JScrollPane(text),
java.awt.BorderLayout.CENTER);
new FileDrop(System.out, text, /*dragBorder,*/ new FileDrop.Listener() {
public void filesDropped(java.io.File[] files) {
for (int i = 0; i < files.length; i++) {
try {
text.append(files[i].getCanonicalPath() + "\n");
} // end try
catch (java.io.IOException e) {
}
} // end for: through each dropped file
} // end filesDropped
}); // end FileDrop.Listener
frame.setBounds(100, 100, 300, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} // end main
}

View File

@@ -0,0 +1,792 @@
package Common.UI.DragDrop;
import Common.Global;
import java.awt.datatransfer.DataFlavor;
import java.io.*;
/**
* This class makes it easy to drag and drop files from the operating
* system to a Java program. Any <tt>java.awt.Component</tt> can be
* dropped onto, but only <tt>javax.swing.JComponent</tt>s will indicate
* the drop event with a changed border.
* <p/>
* To use this class, construct a new <tt>FileDrop</tt> by passing
* it the target component and a <tt>Listener</tt> to receive notification
* when file(s) have been dropped. Here is an example:
* <p/>
* <code><pre>
* JPanel myPanel = new JPanel();
* new FileDrop( myPanel, new FileDrop.Listener()
* { public void filesDropped( java.io.File[] files )
* {
* // handle file drop
* ...
* } // end filesDropped
* }); // end FileDrop.Listener
* </pre></code>
* <p/>
* You can specify the border that will appear when files are being dragged by
* calling the constructor with a <tt>javax.swing.border.Border</tt>. Only
* <tt>JComponent</tt>s will show any indication with a border.
* <p/>
* You can turn on some debugging features by passing a <tt>PrintStream</tt>
* object (such as <tt>System.out</tt>) into the full constructor. A <tt>null</tt>
* value will result in no extra debugging information being output.
* <p/>
*
* <p>I'm releasing this code into the Public Domain. Enjoy.
* </p>
* <p><em>Original author: Robert Harder, rharder@usa.net</em></p>
* <p>2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.</p>
*
* @author Robert Harder
* @author rharder@users.sf.net
* @version 1.0.1
*/
public class FileDrop {
// Default border color
private static final java.awt.Color defaultBorderColor = new java.awt.Color(0f, 0f, 1f, 0.25f);
// BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
private static final String ZERO_CHAR_STRING = "" + (char) 0;
/**
* Discover if the running JVM is modern enough to have drag and drop.
*/
private static Boolean supportsDnD;
private transient javax.swing.border.Border normalBorder;
private transient java.awt.dnd.DropTargetListener dropListener;
/**
* Constructs a {@link FileDrop} with a default light-blue border
* and, if <var>c</var> is a {@link java.awt.Container}, recursively
* sets all elements contained within as drop targets, though only
* the top level container will change borders.
*
* @param c Component on which files will be dropped.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final java.awt.Component c,
final Listener listener) {
this(null, // Logging stream
c, // Drop target
javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor), // Drag border
true, // Recursive
listener);
} // end constructor
/**
* Constructor with a default border and the option to recursively set drop targets.
* If your component is a <tt>java.awt.Container</tt>, then each of its children
* database.Objects.components will also listen for drops, though only the parent will change borders.
*
* @param c Component on which files will be dropped.
* @param recursive Recursively set children as drop targets.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final java.awt.Component c,
final boolean recursive,
final Listener listener) {
this(null, // Logging stream
c, // Drop target
javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor), // Drag border
recursive, // Recursive
listener);
} // end constructor
/**
* Constructor with a default border and debugging optionally turned on.
* With Debugging turned on, more status messages will be displayed to
* <tt>out</tt>. A common way to use this constructor is with
* <tt>System.out</tt> or <tt>System.err</tt>. A <tt>null</tt> value for
* the parameter <tt>out</tt> will result in no debugging output.
*
* @param out PrintStream to record debugging info or null for no debugging.
* @param out
* @param c Component on which files will be dropped.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final PrintStream out,
final java.awt.Component c,
final Listener listener) {
this(out, // Logging stream
c, // Drop target
javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor),
false, // Recursive
listener);
} // end constructor
/**
* Constructor with a default border, debugging optionally turned on
* and the option to recursively set drop targets.
* If your component is a <tt>java.awt.Container</tt>, then each of its children
* database.Objects.components will also listen for drops, though only the parent will change borders.
* With Debugging turned on, more status messages will be displayed to
* <tt>out</tt>. A common way to use this constructor is with
* <tt>System.out</tt> or <tt>System.err</tt>. A <tt>null</tt> value for
* the parameter <tt>out</tt> will result in no debugging output.
*
* @param out PrintStream to record debugging info or null for no debugging.
* @param out
* @param c Component on which files will be dropped.
* @param recursive Recursively set children as drop targets.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final PrintStream out,
final java.awt.Component c,
final boolean recursive,
final Listener listener) {
this(out, // Logging stream
c, // Drop target
javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, defaultBorderColor), // Drag border
recursive, // Recursive
listener);
} // end constructor
/**
* Constructor with a specified border
*
* @param c Component on which files will be dropped.
* @param dragBorder Border to use on <tt>JComponent</tt> when dragging occurs.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final java.awt.Component c,
final javax.swing.border.Border dragBorder,
final Listener listener) {
this(
null, // Logging stream
c, // Drop target
dragBorder, // Drag border
false, // Recursive
listener);
} // end constructor
/**
* Constructor with a specified border and the option to recursively set drop targets.
* If your component is a <tt>java.awt.Container</tt>, then each of its children
* database.Objects.components will also listen for drops, though only the parent will change borders.
*
* @param c Component on which files will be dropped.
* @param dragBorder Border to use on <tt>JComponent</tt> when dragging occurs.
* @param recursive Recursively set children as drop targets.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final java.awt.Component c,
final javax.swing.border.Border dragBorder,
final boolean recursive,
final Listener listener) {
this(
null,
c,
dragBorder,
recursive,
listener);
} // end constructor
/**
* Constructor with a specified border and debugging optionally turned on.
* With Debugging turned on, more status messages will be displayed to
* <tt>out</tt>. A common way to use this constructor is with
* <tt>System.out</tt> or <tt>System.err</tt>. A <tt>null</tt> value for
* the parameter <tt>out</tt> will result in no debugging output.
*
* @param out PrintStream to record debugging info or null for no debugging.
* @param c Component on which files will be dropped.
* @param dragBorder Border to use on <tt>JComponent</tt> when dragging occurs.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final PrintStream out,
final java.awt.Component c,
final javax.swing.border.Border dragBorder,
final Listener listener) {
this(
out, // Logging stream
c, // Drop target
dragBorder, // Drag border
false, // Recursive
listener);
} // end constructor
/**
* Full constructor with a specified border and debugging optionally turned on.
* With Debugging turned on, more status messages will be displayed to
* <tt>out</tt>. A common way to use this constructor is with
* <tt>System.out</tt> or <tt>System.err</tt>. A <tt>null</tt> value for
* the parameter <tt>out</tt> will result in no debugging output.
*
* @param out PrintStream to record debugging info or null for no debugging.
* @param c Component on which files will be dropped.
* @param dragBorder Border to use on <tt>JComponent</tt> when dragging occurs.
* @param recursive Recursively set children as drop targets.
* @param listener Listens for <tt>filesDropped</tt>.
* @since 1.0
*/
public FileDrop(
final PrintStream out,
final java.awt.Component c,
final javax.swing.border.Border dragBorder,
final boolean recursive,
final Listener listener) {
if (supportsDnD()) { // Make a drop listener
dropListener = new java.awt.dnd.DropTargetListener() {
public void dragEnter(java.awt.dnd.DropTargetDragEvent evt) {
log(out, "FileDrop: dragEnter event.");
// Is this an acceptable drag event?
if (isDragOk(out, evt)) {
// If it's a Swing component, set its border
if (c instanceof javax.swing.JComponent) {
javax.swing.JComponent jc = (javax.swing.JComponent) c;
normalBorder = jc.getBorder();
log(out, "FileDrop: normal border saved.");
jc.setBorder(dragBorder);
log(out, "FileDrop: drag border set.");
} // end if: JComponent
// Acknowledge that it's okay to enter
//evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
evt.acceptDrag(java.awt.dnd.DnDConstants.ACTION_COPY);
log(out, "FileDrop: event accepted.");
} // end if: drag ok
else { // Reject the drag event
evt.rejectDrag();
log(out, "FileDrop: event rejected.");
} // end else: drag not ok
} // end dragEnter
public void dragOver(java.awt.dnd.DropTargetDragEvent evt) { // This is called continually as long as the mouse is
// over the drag target.
} // end dragOver
public void drop(java.awt.dnd.DropTargetDropEvent evt) {
log(out, "FileDrop: drop event.");
try { // Get whatever was dropped
java.awt.datatransfer.Transferable tr = evt.getTransferable();
// Is it a file list?
if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
// Say we'll take it.
//evt.acceptDrop ( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
evt.acceptDrop(java.awt.dnd.DnDConstants.ACTION_COPY);
log(out, "FileDrop: file list accepted.");
// Get a useful list
java.util.List fileList = (java.util.List)
tr.getTransferData(DataFlavor.javaFileListFlavor);
java.util.Iterator iterator = fileList.iterator();
// Convert list to array
File[] filesTemp = new File[fileList.size()];
fileList.toArray(filesTemp);
final File[] files = filesTemp;
// Alert listener to drop.
if (listener != null)
listener.filesDropped(files);
// Mark that drop is completed.
evt.getDropTargetContext().dropComplete(true);
log(out, "FileDrop: drop complete.");
} // end if: file list
else // this section will check for a reader flavor.
{
// Thanks, Nathan!
// BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
DataFlavor[] flavors = tr.getTransferDataFlavors();
boolean handled = false;
for (int zz = 0; zz < flavors.length; zz++) {
if (flavors[zz].isRepresentationClassReader()) {
// Say we'll take it.
//evt.acceptDrop ( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
evt.acceptDrop(java.awt.dnd.DnDConstants.ACTION_COPY);
log(out, "FileDrop: reader accepted.");
Reader reader = flavors[zz].getReaderForText(tr);
BufferedReader br = new BufferedReader(reader);
if (listener != null)
listener.filesDropped(createFileArray(br, out));
// Mark that drop is completed.
evt.getDropTargetContext().dropComplete(true);
log(out, "FileDrop: drop complete.");
handled = true;
break;
}
}
if (!handled) {
log(out, "FileDrop: not a file list or reader - abort.");
evt.rejectDrop();
}
// END 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
} // end else: not a file list
} // end try
catch (IOException io) {
log(out, "FileDrop: IOException - abort:");
Global.Log.PrintException(io);
evt.rejectDrop();
} // end catch IOException
catch (java.awt.datatransfer.UnsupportedFlavorException ufe) {
log(out, "FileDrop: UnsupportedFlavorException - abort:");
Global.Log.PrintException(ufe);
evt.rejectDrop();
} // end catch: UnsupportedFlavorException
finally {
// If it's a Swing component, reset its border
if (c instanceof javax.swing.JComponent) {
javax.swing.JComponent jc = (javax.swing.JComponent) c;
jc.setBorder(normalBorder);
log(out, "FileDrop: normal border restored.");
} // end if: JComponent
} // end finally
} // end drop
public void dragExit(java.awt.dnd.DropTargetEvent evt) {
log(out, "FileDrop: dragExit event.");
// If it's a Swing component, reset its border
if (c instanceof javax.swing.JComponent) {
javax.swing.JComponent jc = (javax.swing.JComponent) c;
jc.setBorder(normalBorder);
log(out, "FileDrop: normal border restored.");
} // end if: JComponent
} // end dragExit
public void dropActionChanged(java.awt.dnd.DropTargetDragEvent evt) {
log(out, "FileDrop: dropActionChanged event.");
// Is this an acceptable drag event?
if (isDragOk(out, evt)) { //evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
evt.acceptDrag(java.awt.dnd.DnDConstants.ACTION_COPY);
log(out, "FileDrop: event accepted.");
} // end if: drag ok
else {
evt.rejectDrag();
log(out, "FileDrop: event rejected.");
} // end else: drag not ok
} // end dropActionChanged
}; // end DropTargetListener
// Make the component (and possibly children) drop targets
makeDropTarget(out, c, recursive);
} // end if: supports dnd
else {
log(out, "FileDrop: Drag and drop is not supported with this JVM");
} // end else: does not support DnD
} // end constructor
private static boolean supportsDnD() { // Static Boolean
if (supportsDnD == null) {
boolean support = false;
try {
Class arbitraryDndClass = Class.forName("java.awt.dnd.DnDConstants");
support = true;
} // end try
catch (Exception e) {
support = false;
} // end catch
supportsDnD = new Boolean(support);
} // end if: first time through
return supportsDnD.booleanValue();
} // end supportsDnD
private static File[] createFileArray(BufferedReader bReader, PrintStream out) {
try {
java.util.List list = new java.util.ArrayList();
String line = null;
while ((line = bReader.readLine()) != null) {
try {
// kde seems to append a 0 char to the end of the reader
if (ZERO_CHAR_STRING.equals(line)) continue;
File file = new File(new java.net.URI(line));
list.add(file);
} catch (Exception ex) {
log(out, "Error with " + line + ": " + ex.getMessage());
}
}
return (File[]) list.toArray(new File[list.size()]);
} catch (IOException ex) {
log(out, "FileDrop: IOException");
}
return new File[0];
}
/**
* Outputs <tt>message</tt> to <tt>out</tt> if it's not null.
*/
private static void log(PrintStream out, String message) { // Log message if requested
// if (out != null)
// UI.Print(DebugPrintLevel.DragDrop, message);
} // end log
/**
* Removes the drag-and-drop hooks from the component and optionally
* from the all children. You should call this if you add and remove
* database.Objects.components after you've set up the drag-and-drop.
* This will recursively unregister all database.Objects.components contained within
* <var>c</var> if <var>c</var> is a {@link java.awt.Container}.
*
* @param c The component to unregister as a drop target
* @since 1.0
*/
public static boolean remove(java.awt.Component c) {
return remove(null, c, true);
} // end remove
/**
* Removes the drag-and-drop hooks from the component and optionally
* from the all children. You should call this if you add and remove
* database.Objects.components after you've set up the drag-and-drop.
*
* @param out Optional {@link PrintStream} for logging drag and drop messages
* @param c The component to unregister
* @param recursive Recursively unregister database.Objects.components within a container
* @since 1.0
*/
public static boolean remove(PrintStream out, java.awt.Component c, boolean recursive) { // Make sure we support dnd.
if (supportsDnD()) {
log(out, "FileDrop: Removing drag-and-drop hooks.");
c.setDropTarget(null);
if (recursive && (c instanceof java.awt.Container)) {
java.awt.Component[] comps = ((java.awt.Container) c).getComponents();
for (int i = 0; i < comps.length; i++)
remove(out, comps[i], recursive);
return true;
} // end if: recursive
else return false;
} // end if: supports DnD
else return false;
} // end remove
// END 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
private void makeDropTarget(final PrintStream out, final java.awt.Component c, boolean recursive) {
// Make drop target
final java.awt.dnd.DropTarget dt = new java.awt.dnd.DropTarget();
try {
dt.addDropTargetListener(dropListener);
} // end try
catch (java.util.TooManyListenersException e) {
Global.Log.PrintException(e);
log(out, "FileDrop: Drop will not work due to previous error. Do you have another listener attached?");
} // end catch
// Listen for hierarchy changes and remove the drop target when the parent gets cleared out.
c.addHierarchyListener(new java.awt.event.HierarchyListener() {
public void hierarchyChanged(java.awt.event.HierarchyEvent evt) {
log(out, "FileDrop: Hierarchy changed.");
java.awt.Component parent = c.getParent();
if (parent == null) {
c.setDropTarget(null);
log(out, "FileDrop: Drop target cleared from component.");
} // end if: null parent
else {
new java.awt.dnd.DropTarget(c, dropListener);
log(out, "FileDrop: Drop target added to component.");
} // end else: parent not null
} // end hierarchyChanged
}); // end hierarchy listener
if (c.getParent() != null)
new java.awt.dnd.DropTarget(c, dropListener);
if (recursive && (c instanceof java.awt.Container)) {
// Get the container
java.awt.Container cont = (java.awt.Container) c;
// Get it's database.Objects.components
java.awt.Component[] comps = cont.getComponents();
// Set it's database.Objects.components as listeners also
for (int i = 0; i < comps.length; i++)
makeDropTarget(out, comps[i], recursive);
} // end if: recursively set database.Objects.components as listener
} // end dropListener
/**
* Determine if the dragged data is a file list.
*/
private boolean isDragOk(final PrintStream out, final java.awt.dnd.DropTargetDragEvent evt) {
boolean ok = false;
// Get data flavors being dragged
DataFlavor[] flavors = evt.getCurrentDataFlavors();
// See if any of the flavors are a file list
int i = 0;
while (!ok && i < flavors.length) {
// BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
// Is the flavor a file list?
final DataFlavor curFlavor = flavors[i];
if (curFlavor.equals(DataFlavor.javaFileListFlavor) ||
curFlavor.isRepresentationClassReader()) {
ok = true;
}
// END 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
i++;
} // end while: through flavors
// If logging is enabled, show data flavors
if (out != null) {
if (flavors.length == 0)
log(out, "FileDrop: no data flavors.");
for (i = 0; i < flavors.length; i++)
log(out, flavors[i].toString());
} // end if: logging enabled
return ok;
} // end isDragOk
/* ******** I N N E R I N T E R F A C E L I S T E N E R ******** */
/**
* Implement this inner interface to listen for when files are dropped. For example
* your class declaration may begin like this:
* <code><pre>
* public class MyClass implements FileDrop.Listener
* ...
* public void filesDropped( java.io.File[] files )
* {
* ...
* } // end filesDropped
* ...
* </pre></code>
*
* @since 1.1
*/
public interface Listener {
/**
* This method is called when files have been successfully dropped.
*
* @param files An array of <tt>File</tt>s that were dropped.
* @since 1.0
*/
void filesDropped(File[] files);
} // end inner-interface Listener
/* ******** I N N E R C L A S S ******** */
/**
* This is the event that is passed to the
* {@link FileDropListener#filesDropped filesDropped(...)} method in
* your {@link FileDropListener} when files are dropped onto
* a registered drop target.
*
* <p>I'm releasing this code into the Public Domain. Enjoy.</p>
*
* @author Robert Harder
* @author rob@iharder.net
* @version 1.2
*/
public static class Event extends java.util.EventObject {
private final File[] files;
/**
* Constructs an {@link Event} with the array
* of files that were dropped and the
* {@link FileDrop} that initiated the event.
*
* @param files The array of files that were dropped
* @source The event source
* @since 1.1
*/
public Event(File[] files, Object source) {
super(source);
this.files = files;
} // end constructor
/**
* Returns an array of files that were dropped on a
* registered drop target.
*
* @return array of files that were dropped
* @since 1.1
*/
public File[] getFiles() {
return files;
} // end getFiles
} // end inner class Event
/* ******** I N N E R C L A S S ******** */
/**
* At last an easy way to encapsulate your custom objects for dragging and dropping
* in your Java programs!
* When you need to create a {@link java.awt.datatransfer.Transferable} object,
* use this class to wrap your object.
* For example:
* <pre><code>
* ...
* MyCoolClass myObj = new MyCoolClass();
* Transferable xfer = new TransferableObject( myObj );
* ...
* </code></pre>
* Or if you need to know when the data was actually dropped, like when you're
* moving data out of a list, say, you can use the {@link Fetcher}
* inner class to return your object Just in Time.
* For example:
* <pre><code>
* ...
* final MyCoolClass myObj = new MyCoolClass();
*
* TransferableObject.Fetcher fetcher = new TransferableObject.Fetcher()
* { public Object getObject(){ return myObj; }
* }; // end fetcher
*
* Transferable xfer = new TransferableObject( fetcher );
* ...
* </code></pre>
* <p>
* The {@link DataFlavor} associated with
* {@link TransferableObject} has the representation class
* <tt>net.iharder.dnd.TransferableObject.class</tt> and MIME type
* <tt>application/x-net.iharder.dnd.TransferableObject</tt>.
* This data flavor is accessible via the static
* {@link #DATA_FLAVOR} property.
*
*
* <p>I'm releasing this code into the Public Domain. Enjoy.</p>
*
* @author Robert Harder
* @author rob@iharder.net
* @version 1.2
*/
public static class TransferableObject implements java.awt.datatransfer.Transferable {
/**
* The MIME type for {@link #DATA_FLAVOR} is
* <tt>application/x-net.iharder.dnd.TransferableObject</tt>.
*
* @since 1.1
*/
public final static String MIME_TYPE = "application/x-net.iharder.dnd.TransferableObject";
/**
* The default {@link DataFlavor} for
* {@link TransferableObject} has the representation class
* <tt>net.iharder.dnd.TransferableObject.class</tt>
* and the MIME type
* <tt>application/x-net.iharder.dnd.TransferableObject</tt>.
*
* @since 1.1
*/
public final static DataFlavor DATA_FLAVOR =
new DataFlavor(TransferableObject.class, MIME_TYPE);
private Fetcher fetcher;
private Object data;
private DataFlavor customFlavor;
/**
* Creates a new {@link TransferableObject} that wraps <var>data</var>.
* Along with the {@link #DATA_FLAVOR} associated with this class,
* this creates a custom data flavor with a representation class
* determined from <code>data.getClass()</code> and the MIME type
* <tt>application/x-net.iharder.dnd.TransferableObject</tt>.
*
* @param data The data to transfer
* @since 1.1
*/
public TransferableObject(Object data) {
this.data = data;
this.customFlavor = new DataFlavor(data.getClass(), MIME_TYPE);
} // end constructor
/**
* Creates a new {@link TransferableObject} that will return the
* object that is returned by <var>fetcher</var>.
* No custom data flavor is set other than the default
* {@link #DATA_FLAVOR}.
*
* @param fetcher The {@link Fetcher} that will return the data object
* @see Fetcher
* @since 1.1
*/
public TransferableObject(Fetcher fetcher) {
this.fetcher = fetcher;
} // end constructor
/**
* Creates a new {@link TransferableObject} that will return the
* object that is returned by <var>fetcher</var>.
* Along with the {@link #DATA_FLAVOR} associated with this class,
* this creates a custom data flavor with a representation class <var>dataClass</var>
* and the MIME type
* <tt>application/x-net.iharder.dnd.TransferableObject</tt>.
*
* @param dataClass The {@link Class} to use in the custom data flavor
* @param fetcher The {@link Fetcher} that will return the data object
* @see Fetcher
* @since 1.1
*/
public TransferableObject(Class dataClass, Fetcher fetcher) {
this.fetcher = fetcher;
this.customFlavor = new DataFlavor(dataClass, MIME_TYPE);
} // end constructor
/**
* Returns the custom {@link DataFlavor} associated
* with the encapsulated object or <tt>null</tt> if the {@link Fetcher}
* constructor was used without passing a {@link Class}.
*
* @return The custom data flavor for the encapsulated object
* @since 1.1
*/
public DataFlavor getCustomDataFlavor() {
return customFlavor;
} // end getCustomDataFlavor
/* ******** T R A N S F E R A B L E M E T H O D S ******** */
/**
* Returns a two- or three-element array containing first
* the custom data flavor, if one was created in the constructors,
* second the default {@link #DATA_FLAVOR} associated with
* {@link TransferableObject}, and third the
* {@link DataFlavor.stringFlavor}.
*
* @return An array of supported data flavors
* @since 1.1
*/
public DataFlavor[] getTransferDataFlavors() {
if (customFlavor != null)
return new DataFlavor[]
{customFlavor,
DATA_FLAVOR,
DataFlavor.stringFlavor
}; // end flavors array
else
return new DataFlavor[]
{DATA_FLAVOR,
DataFlavor.stringFlavor
}; // end flavors array
} // end getTransferDataFlavors
/**
* Returns the data encapsulated in this {@link TransferableObject}.
* If the {@link Fetcher} constructor was used, then this is when
* the {@link Fetcher#getObject getObject()} method will be called.
* If the requested data flavor is not supported, then the
* {@link Fetcher#getObject getObject()} method will not be called.
*
* @param flavor The data flavor for the data to return
* @return The dropped data
* @since 1.1
*/
public Object getTransferData(DataFlavor flavor)
throws java.awt.datatransfer.UnsupportedFlavorException, IOException {
// Native object
if (flavor.equals(DATA_FLAVOR))
return fetcher == null ? data : fetcher.getObject();
// String
if (flavor.equals(DataFlavor.stringFlavor))
return fetcher == null ? data.toString() : fetcher.getObject().toString();
// We can't do anything else
throw new java.awt.datatransfer.UnsupportedFlavorException(flavor);
} // end getTransferData
/**
* Returns <tt>true</tt> if <var>flavor</var> is one of the supported
* flavors. Flavors are supported using the <code>equals(...)</code> method.
*
* @param flavor The data flavor to check
* @return Whether or not the flavor is supported
* @since 1.1
*/
public boolean isDataFlavorSupported(DataFlavor flavor) {
// Native object
if (flavor.equals(DATA_FLAVOR))
return true;
// String
return flavor.equals(DataFlavor.stringFlavor);
// We can't do anything else
} // end isDataFlavorSupported
/* ******** I N N E R I N T E R F A C E F E T C H E R ******** */
/**
* Instead of passing your data directly to the {@link TransferableObject}
* constructor, you may want to know exactly when your data was received
* in case you need to remove it from its source (or do anyting else to it).
* When the {@link #getTransferData getTransferData(...)} method is called
* on the {@link TransferableObject}, the {@link Fetcher}'s
* {@link #getObject getObject()} method will be called.
*
* @author Robert Harder
* @version 1.1
* @copyright 2001
* @since 1.1
*/
public interface Fetcher {
/**
* Return the object being encapsulated in the
* {@link TransferableObject}.
*
* @return The dropped object
* @since 1.1
*/
Object getObject();
} // end inner interface Fetcher
} // end class TransferableObject
} // end class FileDrop

View File

@@ -0,0 +1,154 @@
package Common.UI.Editor;
import Common.Current;
import Common.Global;
import Common.UI.Menus.StyledPopupMenu;
import Common.UI.Menus.TextEditorMenu;
import Common.UI.Themes.ThemeElement;
import Common.UI.UI;
import Common.UI.Windows.Dialog.DialogFields;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.net.URI;
public class BaseEditor extends RSyntaxTextArea implements ThemeElement, DialogFields {
private final StyledPopupMenu menu;
// protected int changesCount = 0;
// protected int insertsCount = 0;
// protected int removesCount = 0;
// protected boolean ctrlZ = false;
protected String startText = "";
private boolean search_enabled = true;
public BaseEditor() {
setTabSize(6);
setPaintTabLines(true);
setCodeFoldingEnabled(true);
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.isControlDown()) {
switch (e.getKeyCode()) {
case KeyEvent.VK_ADD: //num lock +
case KeyEvent.VK_EQUALS: //+
FontUp();
break;
case KeyEvent.VK_SUBTRACT: //num lock -
case KeyEvent.VK_MINUS: //-
FontDown();
break;
case KeyEvent.VK_S:
saveText();
break;
//todo переход в нужную строку по ctrl+g?
case KeyEvent.VK_Z:
if (getText().equals(startText)) {
UI.Info("Начальная версия текста достигнута.");
e.consume();
}
break;
}
}
}
});
setPopupMenu(menu = createMenu());
applyTheme();
//-
this.setHyperlinksEnabled(true);
HyperlinkListener listener = new HyperlinkListener() {
@Override
public void hyperlinkUpdate(HyperlinkEvent event) {
if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
try {
Desktop.getDesktop().browse(new URI(event.getURL().toString()));
} catch (Exception ioe) {
System.err.println("Error loading url from link: " + ioe);
}
}
}
};
this.addHyperlinkListener(listener);
}
@Override
public void setText(String t) {
super.setText(t);
startText = t;
}
public void setSearchEnabled(boolean f_in) {
search_enabled = f_in;
}
protected StyledPopupMenu createMenu() {
return new TextEditorMenu(this);
}
private void changeFont(int size) {
if ((size > 1) && (size < 48)) {
setFont(getFont().deriveFont((float) size));
saveFont();
}
}
protected void saveFont() {
}
protected void saveText() {
}
public void ClearSelection() {
setSelectionStart(0);
setSelectionEnd(0);
}
public void gotoLine(int LineNum) {
gotoLine_(LineNum - 1);
}
//без вычитания.
public void gotoLine_(int LineNum) {
//requestFocus();
try {
//особеннсть контрола.
//нельзя полностью скинуть текущую позицию. пэтому если надо
//освежить 0 строку, передергиваем до последней.
if (LineNum == 0)
setCaretPosition(getLineStartOffset(getLineCount() - 1));
ClearSelection();
if (LineNum > 0) {
setCaretPosition(getLineStartOffset(LineNum));
setSelectionStart(getLineStartOffset(LineNum));
setSelectionEnd(getLineStartOffset(LineNum));
}
} catch (Exception ex) {
Global.Log.Print("Не удалось перейти на строку " + LineNum);
Global.Log.PrintException(ex);
}
}
//------------------------------------------
public void FontUp() {
changeFont(getFont().getSize() + 1);
}
public void FontDown() {
changeFont(getFont().getSize() - 1);
}
@Override
public void applyTheme() {
float font_size = (float) getFont().getSize();
Current.getTheme().getEditorTheme().apply(this);
setFont(getFont().deriveFont(font_size));
menu.applyTheme();
//меню связано с редактором. поэтому тема меняется только вместе с ним.
}
@Override
public Component getContent() {
return this;
}
public void ShowBegin() {
setCaretPosition(0);
}
public boolean lineIsVisible(int lineNum) {
boolean res = false;
Rectangle rectangle = this.getVisibleRect();
try {
res = rectangle.contains(rectangle.x, yForLine(lineNum));
} catch (Exception ex) {
ex.printStackTrace();
}
return res;
}
}

View File

@@ -0,0 +1,30 @@
package Common.UI.Editor;
import Common.Global;
import ProjectData.Files.UI.Editor.SPFEditor;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
public class CaretInfo {
public String current_line = ""; //полный текст текущей строки
public String before = ""; //кусок строки перед кареткой
public String after = ""; //кусок строки после каретки
public String prefix_word = ""; //слово перед кареткой
public String suffix_word = ""; //слово после каретки
public CaretInfo(RSyntaxTextArea Body) {
try {
int start = Body.getLineStartOffset(Body.getCaretLineNumber());
int before_length = Body.getCaretOffsetFromLineStart();
int end = Body.getLineEndOffset(Body.getCaretLineNumber());
int after_length = end - start - before_length;
before = Body.getText(start, before_length).toUpperCase();
after = Body.getText(start + before_length, after_length).toUpperCase();
//нужно чтобы перевод строки не влезал
after = after.replace("\n", "");
current_line = (before + after);
prefix_word = SPFEditor.getLastWord(before, ' ', ',', ':', '.', '(', ')');
suffix_word = SPFEditor.getFirstWord(after, ' ', ',', ':', '.', '(', ')');
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
public CaretInfo() {
}
}

View File

@@ -0,0 +1,8 @@
package Common.UI.Editor;
public class Viewer extends BaseEditor {
public Viewer() {
setLineWrap(true);
setWrapStyleWord(true);
setEditable(false);
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Common.UI.EmptyDialogFields">
<grid id="27dc6" binding="content" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children/>
</grid>
</form>

View File

@@ -0,0 +1,12 @@
package Common.UI;
import Common.UI.Windows.Dialog.DialogFields;
import javax.swing.*;
import java.awt.*;
public class EmptyDialogFields implements DialogFields {
private JPanel content;
@Override
public Component getContent() {
return content;
}
}

View File

@@ -0,0 +1,15 @@
package Common.UI.Label;
import javax.swing.*;
public class ShortLabel extends JLabel {
int max = 0;
public ShortLabel(int max_in) {
max = max_in;
}
@Override
public void setText(String text_in) {
if ((max > 0) && (text_in.length() > max)) {
super.setText(text_in.substring(0, max - 1) + "...");
} else super.setText(text_in);
setToolTipText(text_in);
}
}

View File

@@ -0,0 +1,10 @@
package Common.UI.List;
import Common.Current;
import Common.UI.Themes.VisualiserFonts;
public class HyperlinksStyledList extends StyledList {
@Override
public void applyTheme() {
super.applyTheme();
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Hyperlink));
}
}

View File

@@ -0,0 +1,17 @@
package Common.UI.List;
import Common.Current;
import Common.UI.Themes.ThemeElement;
import Common.UI.Themes.VisualiserFonts;
import javax.swing.*;
public class StyledList extends JList implements ThemeElement {
public StyledList() {
setFont(Current.getTheme().Fonts.get(VisualiserFonts.TreePlain));
applyTheme();
}
@Override
public void applyTheme() {
setBackground(Current.getTheme().table_background);
setForeground(Current.getTheme().foreground);
}
}

View File

@@ -0,0 +1,30 @@
package Common.UI.Menus;
import Common.Current;
import Common.Global;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class AttachementsMenu extends StyledPopupMenu {
JMenuItem mscreenshot;
JMenuItem mExplorer;
public AttachementsMenu() {
add(mscreenshot = Pass_2021.passes.get(PassCode_2021.MakeScreenShot).createMenuItem());
addSeparator();
mExplorer = new VisualiserMenuItem("Открыть вложения в проводнике...", "/icons/Explorer.png");
mExplorer.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().open(Current.getProject().getAttachmentsDirectory());
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
});
add(mExplorer);
}
}

View File

@@ -0,0 +1,24 @@
package Common.UI.Menus;
import Common.Current;
import ProjectData.Files.LanguageStyle;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class FileStyleMenu extends StyledPopupMenu {
public FileStyleMenu() {
for (LanguageStyle s : LanguageStyle.values()) {
JMenuItem m = new VisualiserMenuItem(s.getDescription());
m.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (Current.getFile().UpdateStyle(s)) {
Current.getSapfor().ResetAllAnalyses();
Current.getFile().form.ShowStyle();
}
}
});
add(m);
}
}
}

View File

@@ -0,0 +1,35 @@
package Common.UI.Menus;
import Common.UI.Trees.StyledTree;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
public class GraphMenu<T extends StyledTree> extends StyledPopupMenu {
public T tree;
public GraphMenu(T tree_in, String branches_name) {
tree = tree_in;
JMenuItem m = null;
m = new VisualiserMenuItem("Свернуть все " + branches_name);
m.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tree.CollapseAll();
}
});
add(m);
m = new VisualiserMenuItem("Развернуть все " + branches_name);
m.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
tree.ExpandAll();
}
});
add(m);
}
public GraphMenu(T tree) {
this(tree, tree.getBranchesName());
}
public void Show(MouseEvent mouseEvent) {
show(tree, mouseEvent.getX(), mouseEvent.getY());
}
}

View File

@@ -0,0 +1,342 @@
package Common.UI.Menus;
import Common.Current;
import Common.Global;
import Common.UI.Editor.CaretInfo;
import Common.Utils.Utils;
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;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
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 = "Имя процедуры может содержать только английские буквы, цифры и подчеркивания, и не может начинаться с цифры.";
//-
m_inline.setText("Невозможно подставить вызов процедуры " + Utils.Brackets(selectedText) +
" . Выделено некорректное имя.");
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils.Brackets(selectedText) +
" . Выделено некорректное имя.");
//-
m_inline.setToolTipText(tip);
m_gotoFunction.setToolTipText(tip);
return;
}
if (!Pass_2021.passes.get(PassCode_2021.SPF_GetGraphFunctions).isDone()) {
m_inline.setText("Невозможно подставить вызов процедуры " + Utils.Brackets(selectedText) +
" . Выполните проход \"Граф процедур \".");
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils.Brackets(selectedText) +
" . Выполните проход \"Граф процедур \"");
return;
}
if (Current.getSapfor().isIntrinsic(selectedText)) {
m_inline.setText("Невозможно подставить вызов процедуры " + Utils.Brackets(selectedText) +
" . Процедура является стандартной.");
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils.Brackets(selectedText) +
" . Процедура является стандартной.");
return;
}
call = Current.getFile().find_func_call(selectedText);
if (call == null) {
m_inline.setText("Невозможно подставить вызов процедуры " + Utils.Brackets(selectedText) +
" . Вызов не найден в текущей строке.");
m_gotoFunction.setText("Невозможно перейти к объявлению процедуры " + Utils.Brackets(selectedText) +
" . Объявление процедуры уже находится в текущей строке.");
return;
}
decl = Current.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_2021.passes.get(PassCode_2021.SPF_GetIncludeDependencies).isDone()) {
m_gotoHeader.setText("Невозможно перейти к заголовочному файлу. Выполните проход \"Поиск зависимостей по включению\"");
return;
}
if (!Current.getFile().relativeHeaders.containsKey(header_)) {
m_gotoHeader.setText("Невозможно перейти к заголовочному файлу " + Utils.Brackets(header_) + " . Файл не найден среди включений текущего файла.");
return;
}
header = Current.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_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);
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 (Current.getSapfor().OldFiles.isEmpty()) {
m_undo.setEnabled(false);
m_undo.setText("Невозможно отменить последнюю модификацию. Модификации отсутствуют.");
} else {
m_undo.setEnabled(true);
m_undo.setText("Отменить последнюю модификацию.");
}
}
}

View File

@@ -0,0 +1,18 @@
package Common.UI.Menus;
import Common.Current;
import Common.UI.Themes.VisualiserFonts;
import Common.Utils.Utils;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import javax.swing.*;
public class PassesSubMenu extends JMenu {
public PassesSubMenu(String title, String icon, PassCode_2021... passes) {
super(title);
setIcon(Utils.getIcon(icon));
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
for (PassCode_2021 code : passes) {
add(Pass_2021.passes.get(code).createMenuItem());
}
}
}

View File

@@ -0,0 +1,135 @@
package Common.UI.Menus;
import Common.Current;
import Common.Global;
import Common.UI.Menus_2023.LanguagesSubmenu;
import Common.UI.Menus_2023.StableMenuItem;
import Common.UI.Menus_2023.StylesSubmenu;
import Common.UI.Menus_2023.TypesSubmenu;
import Common.UI.Trees.StyledTree;
import Common.UI.UI;
import Common.Utils.Utils;
import ProjectData.Files.FileType;
import ProjectData.Files.LanguageStyle;
import ProjectData.LanguageName;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class ProjectFilesMenu extends GraphMenu {
VisualiserMenuItem m_select_all;
VisualiserMenuItem m_unselect_all;
VisualiserMenuItem m_multiselection;
JMenu mLanguage;
JMenu mStyle;
JMenu mType;
public ProjectFilesMenu(StyledTree tree) {
super(tree, "подпапки");
addSeparator();
JMenuItem m = new VisualiserMenuItem("Открыть в проводнике...", "/icons/Explorer.png");
m.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().open(Current.getProject().Home);
} catch (Exception ex) {
Global.Log.PrintException(ex);
}
}
});
add(m);
addSeparator();
add(new PassesSubMenu("Добавить", "/icons/RedAdd.png",
PassCode_2021.AddFile,
PassCode_2021.CreateEmptyDirectory,
PassCode_2021.ImportFiles));
addSeparator();
add(new PassesSubMenu("Переименовать", "/icons/Menu/Rename.png",
PassCode_2021.RenameFile,
PassCode_2021.RenameDirectory));
add(new VisualiserMenuItem("Удалить текущий проект", "/icons/Delete.png") {
{
addActionListener(e -> {
if (Current.HasProject()) {
UI.getVersionsWindow().getVersionsForm().getTree().SelectNode(Current.getProject().node);
Pass_2021.passes.get(PassCode_2021.DeleteVersion).Do();
}
});
}
});
addSeparator();
m_multiselection = new VisualiserMenuItem("Массовый режим работы с файлами");
m_multiselection.setIcon(Utils.getIcon(Global.files_multiselection ? "/icons/Pick.png" : "/icons/NotPick.png"));
m_multiselection.addActionListener(e -> {
Global.files_multiselection = !Global.files_multiselection;
m_multiselection.setIcon(Utils.getIcon(Global.files_multiselection ? "/icons/Pick.png" : "/icons/NotPick.png"));
Current.getProject().SelectAllFiles(false);
UI.getMainWindow().getProjectWindow().RefreshProjectFiles();
//-
});
add(m_multiselection);
addSeparator();
//-
m_select_all = new StableMenuItem("Выбрать всё", "/icons/SelectAll.png");
m_select_all.addActionListener(e -> {
Current.getProject().SelectAllFiles(true);
tree.updateUI();
});
add(m_select_all);
m_unselect_all = new StableMenuItem("Отменить всё", "/icons/UnselectAll.png");
m_unselect_all.addActionListener(e -> {
Current.getProject().SelectAllFiles(false);
tree.updateUI();
});
add(m_unselect_all);
//--------------------------------------------------
add(mLanguage = new LanguagesSubmenu(PassCode_2021.SetSelectedFilesLanguage.getDescription()) {
@Override
public void action(LanguageName languageName) {
Pass_2021.passes.get(PassCode_2021.SetSelectedFilesLanguage).Do(languageName);
}
});
add(mStyle = new StylesSubmenu(PassCode_2021.SetSelectedFilesStyle.getDescription()) {
@Override
public void action(LanguageStyle languageStyle) {
Pass_2021.passes.get(PassCode_2021.SetSelectedFilesStyle).Do(languageStyle);
}
});
add(mType = new TypesSubmenu(PassCode_2021.SetSelectedFilesType.getDescription()) {
@Override
public void action(FileType fileType) {
Pass_2021.passes.get(PassCode_2021.SetSelectedFilesType).Do(fileType);
}
});
//--------------------------------------------------
add(Pass_2021.passes.get(PassCode_2021.ExcludeSelectedFiles).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.IncludeSelectedFiles).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.ExcludeFile).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.IncludeFile).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.DeleteFile).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.DeleteDirectory).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.DeleteSelectedFiles).createMenuItem());
}
@Override
public void CheckElementsVisibility() {
m_select_all.setVisible(Global.files_multiselection);
m_unselect_all.setVisible(Global.files_multiselection);
mLanguage.setVisible(Global.files_multiselection);
mStyle.setVisible(Global.files_multiselection);
mType.setVisible(Global.files_multiselection);
//-
Pass_2021.passes.get(PassCode_2021.ExcludeFile).setControlsVisible(!Global.files_multiselection);
Pass_2021.passes.get(PassCode_2021.IncludeFile).setControlsVisible(!Global.files_multiselection);
//-
Pass_2021.passes.get(PassCode_2021.DeleteFile).setControlsVisible(!Global.files_multiselection);
Pass_2021.passes.get(PassCode_2021.DeleteDirectory).setControlsVisible(!Global.files_multiselection);
//--
Pass_2021.passes.get(PassCode_2021.ExcludeSelectedFiles).setControlsVisible(Global.files_multiselection);
Pass_2021.passes.get(PassCode_2021.IncludeSelectedFiles).setControlsVisible(Global.files_multiselection);
Pass_2021.passes.get(PassCode_2021.DeleteSelectedFiles).setControlsVisible(Global.files_multiselection);
}
}

View File

@@ -0,0 +1,18 @@
package Common.UI.Menus;
import Common.Current;
import Common.Global;
import Common.UI.Themes.VisualiserFonts;
import Common.Utils.Utils;
import javax.swing.*;
public class PropertiesSubmenu extends JMenu {
public PropertiesSubmenu(String title, String icon, String... settings) {
super(title);
if (icon != null)
setIcon(Utils.getIcon(icon));
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
for (String name : settings) {
Global.properties.addFlagMenuItem(this, name);
}
}
}

View File

@@ -0,0 +1,86 @@
package Common.UI.Menus;
import Common.Current;
import Common.UI.Menus_2023.StableMenuItem;
import Common.UI.Selectable;
import Common.UI.Trees.DataTree;
import Common.UI.Trees.SelectableTree;
import Common.Utils.Utils;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public abstract class SelectionTreeMenu extends GraphMenu<DataTree> {
VisualiserMenuItem m_select_for_current;
VisualiserMenuItem m_unselect_for_current;
VisualiserMenuItem m_select_all;
VisualiserMenuItem m_unselect_all;
public SelectionTreeMenu(SelectableTree tree_in) {
super(tree_in, "");
addSeparator();
//-
m_select_all = new StableMenuItem("Выбрать всё", "/icons/SelectAll.png");
m_select_all.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SelectAll(true);
tree.updateUI();
}
});
add(m_select_all);
m_unselect_all = new StableMenuItem("Отменить всё", "/icons/UnselectAll.png");
m_unselect_all.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SelectAll(false);
tree.updateUI();
}
});
add(m_unselect_all);
addSeparator();
m_select_for_current = new VisualiserMenuItem("");
m_select_for_current.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Object o = Current.get(tree.getCurrent());
if (o instanceof Selectable) {
((Selectable) o).SelectAllChildren(true);
}
tree.updateUI();
}
});
add(m_select_for_current);
//--------
m_unselect_for_current = new VisualiserMenuItem("");
m_unselect_for_current.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Object o = Current.get(tree.getCurrent());
if (o instanceof Selectable) {
((Selectable) o).SelectAllChildren(false);
}
tree.updateUI();
}
});
//-------
add(m_unselect_for_current);
}
public abstract Class getTargetClass(); //для кого позволяется выбирать всех потомков.
public abstract void SelectAll(boolean select);
@Override
public void CheckElementsVisibility() {
Object current = Current.get(tree.getCurrent());
if ((current != null) && (current.getClass().equals(getTargetClass()))) {
String name = ((Selectable) current).getSelectionText();
m_select_for_current.setText("Выбрать всё для " +
Utils.Brackets(name));
m_unselect_for_current.setText("Отменить выбор всех для " +
Utils.Brackets(name));
//-
m_select_for_current.setVisible(true);
m_unselect_for_current.setVisible(true);
} else {
m_select_for_current.setVisible(false);
m_unselect_for_current.setVisible(false);
}
}
}

View File

@@ -0,0 +1,38 @@
package Common.UI.Menus;
import Common.Current;
import Common.UI.Themes.ThemeElement;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class StyledPopupMenu extends JPopupMenu implements ThemeElement {
public StyledPopupMenu() {
addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
CheckElementsVisibility();
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
});
}
private void refreshTheme_r(MenuElement element) {
element.getComponent().setBackground(Current.getTheme().background);
element.getComponent().setForeground(Current.getTheme().foreground);
for (MenuElement se : element.getSubElements())
refreshTheme_r(se);
}
@Override
public void applyTheme() {
setBackground(Current.getTheme().background);
setForeground(Current.getTheme().foreground);
refreshTheme_r(this);
}
public void CheckElementsVisibility() {
applyTheme();
}
}

View File

@@ -0,0 +1,29 @@
package Common.UI.Menus;
import Common.Utils.Utils;
import javax.swing.*;
public class TableMenu extends StyledPopupMenu {
int row = Utils.Nan;
int column = Utils.Nan;
Object target = null;
//-
JTable owner = null;
VisualiserMenuItem mcopy;
public TableMenu(JTable owner_in) {
owner = owner_in;
mcopy = new VisualiserMenuItem("Копировать текст текущей ячейки", "/icons/Editor/Copy.png");
//если удалось нажать значит все условия выполнены
mcopy.addActionListener(e -> Utils.CopyToClipboard(target.toString()));
add(mcopy);
}
@Override
public void CheckElementsVisibility() {
row = owner.getSelectedRow();
column = owner.getSelectedColumn();
if ((row >= 0) && (column >= 0)) {
target = owner.getValueAt(row, column);
mcopy.setVisible(true);
} else mcopy.setVisible(false);
super.CheckElementsVisibility();
}
}

View File

@@ -0,0 +1,28 @@
package Common.UI.Menus;
import GlobalData.Tasks.TaskState;
import javax.swing.*;
import java.awt.event.ActionListener;
public class TestsCompilationFilterMenu extends StyledPopupMenu{
public void CreateStateItem(TaskState state, ActionListener listener){
JMenuItem m = new VisualiserMenuItem(state.getDescription());
m.addActionListener(listener);
add(m);
}
public TestsCompilationFilterMenu(){
for (TaskState taskState: TaskState.values()){
switch (taskState){
case Queued:
case FailedToQueue:
case NoSuchTask:
case AbortingByUser:
break;
case Waiting:
CreateStateItem(taskState, e -> {
});
break;
}
}
}
}

View File

@@ -0,0 +1,42 @@
package Common.UI.Menus;
import Common.UI.UI;
import Common.Utils.Utils;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class TextComboBoxMenu extends StyledPopupMenu {
protected JComboBox<String> box;
protected String selectedText = null;
//-------------------------------------------------
JMenuItem m_copy;
JMenuItem m_paste;
//-------------------------------------------------
public TextComboBoxMenu(JComboBox<String> box_in) {
box = box_in;
m_copy = new VisualiserMenuItem("Копировать", "/icons/Editor/Copy.png");
m_copy.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Utils.CopyToClipboard(box.getSelectedItem().toString());
}
});
add(m_copy);
m_paste = new VisualiserMenuItem("Вставить", "/icons/Editor/Paste.png");
m_paste.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
UI.TrySelect(box, Utils.getFromClipboard());
}
});
add(m_paste);
}
@Override
public void CheckElementsVisibility() {
boolean visible_ = box.getSelectedIndex() >= 0;
m_paste.setVisible(visible_);
m_copy.setVisible(visible_);
super.CheckElementsVisibility();
}
}

View File

@@ -0,0 +1,86 @@
package Common.UI.Menus;
import Common.Utils.Utils;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.event.ActionEvent;
import java.util.Vector;
public class TextEditorMenu extends StyledPopupMenu {
protected JTextComponent editor;
protected String selectedText = null;
//-------------------------------------------------
JMenuItem m_cut;
JMenuItem m_copy;
JMenuItem m_paste;
protected JMenuItem m_strike;
protected JMenuItem m_unstrike;
//-------------------------------------------------
public TextEditorMenu(JTextComponent editor_in) {
editor = editor_in;
m_cut = new VisualiserMenuItem("Вырезать", "/icons/Editor/Cut.png");
m_cut.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
editor.cut();
}
});
add(m_cut);
m_copy = new VisualiserMenuItem("Копировать", "/icons/Editor/Copy.png");
m_copy.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
editor.copy();
}
});
add(m_copy);
m_paste = new VisualiserMenuItem("Вставить", "/icons/Editor/Paste.png");
m_paste.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
editor.paste();
}
});
add(m_paste);
//--
m_strike = new VisualiserMenuItem("Вычеркнуть","/icons/Editor/Strikethrough.png");
m_strike.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String[] data = selectedText.split("\n");
Vector<String> new_data = new Vector<>();
for (String line: data){
new_data.add(Utils.strikeThrough(line));
}
editor.replaceSelection(String.join("\n", new_data));
}
});
add(m_strike);
m_unstrike = new VisualiserMenuItem("Отменить вычёркивание","/icons/Editor/NoStrike.png");
m_unstrike.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String[] data = selectedText.split("\n");
Vector<String> new_data = new Vector<>();
for (String line: data){
new_data.add(Utils.noStrikeThrough(line));
}
editor.replaceSelection(String.join("\n", new_data));
}
});
add(m_unstrike);
}
@Override
public void CheckElementsVisibility() {
selectedText = editor.getSelectedText();
m_cut.setVisible(editor.isEditable() && (selectedText != null));
m_paste.setVisible(editor.isEditable());
m_copy.setVisible(selectedText != null);
m_strike.setVisible(editor.isEditable() && (selectedText != null));
m_unstrike.setVisible(editor.isEditable() && (selectedText != null));
super.CheckElementsVisibility();
}
}

View File

@@ -0,0 +1,53 @@
package Common.UI.Menus;
import Common.Current;
import Common.Global;
import Common.UI.Menus_2023.StableMenuItem;
import Common.UI.Trees.DataTree;
import Common.UI.UI;
import Common.Utils.Utils;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
public class VersionsMenu extends GraphMenu<DataTree> {
VisualiserMenuItem m_select_all;
VisualiserMenuItem m_unselect_all;
VisualiserMenuItem m_multiselection;
public VersionsMenu(DataTree tree) {
super(tree, "подверсии");
add(Pass_2021.passes.get(PassCode_2021.DeleteSubversions).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.DeleteLonelyM).createMenuItem());
addSeparator();
m_multiselection = new VisualiserMenuItem("Массовый режим работы с версиями");
m_multiselection.setIcon(Utils.getIcon(Global.versions_multiselection ? "/icons/Pick.png" : "/icons/NotPick.png"));
m_multiselection.addActionListener(e -> {
Global.versions_multiselection = !Global.versions_multiselection;
m_multiselection.setIcon(Utils.getIcon(Global.versions_multiselection ? "/icons/Pick.png" : "/icons/NotPick.png"));
Current.getRoot().SelectAllVersions(false);
UI.getVersionsWindow().getVersionsForm().getTree().updateUI();
});
add(m_multiselection);
addSeparator();
add(Pass_2021.passes.get(PassCode_2021.DeleteVersion).createMenuItem());
//-
m_select_all = new StableMenuItem("Выбрать всё, кроме резервных копий","/icons/SelectAll.png");
m_select_all.addActionListener(e -> {
Current.getRoot().SelectAllVersions(true);
tree.updateUI();
});
add(m_select_all);
m_unselect_all = new StableMenuItem("Отменить всё","/icons/UnselectAll.png");
m_unselect_all.addActionListener(e -> {
Current.getRoot().SelectAllVersions(false);
tree.updateUI();
});
add(m_unselect_all);
add(Pass_2021.passes.get(PassCode_2021.DeleteSelectedVersions).createMenuItem());
}
@Override
public void CheckElementsVisibility() {
Pass_2021.passes.get(PassCode_2021.DeleteSelectedVersions).setControlsVisible(!Global.versions_multiselection);
Pass_2021.passes.get(PassCode_2021.DeleteSelectedVersions).setControlsVisible(Global.versions_multiselection);
Pass_2021.passes.get(PassCode_2021.DeleteVersion).setControlsVisible(!Global.versions_multiselection);
m_select_all.setVisible(Global.versions_multiselection);
m_unselect_all.setVisible(Global.versions_multiselection);
}
}

View File

@@ -0,0 +1,21 @@
package Common.UI.Menus;
import Common.Current;
import Common.UI.Themes.VisualiserFonts;
import Common.Utils.Utils;
import javax.swing.*;
public class VisualiserMenuItem extends JMenuItem {
public VisualiserMenuItem(String text) {
super(text, null);
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
}
public VisualiserMenuItem(String text, String icon_path) {
super(text);
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
if (icon_path != null)
setIcon(Utils.getIcon(icon_path));
}
public VisualiserMenuItem(){
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
}
}

View File

@@ -0,0 +1,17 @@
package Common.UI.Menus_2023.BugReportsMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class BugReportsMenuBar extends DataMenuBar {
public BugReportsMenuBar() {
super("отчёты об ошибках",
PassCode_2021.SynchronizeBugReports,
PassCode_2021.DownloadAllBugReportsArchives,
PassCode_2021.AddBugReport,
PassCode_2021.PublishBugReport,
PassCode_2021.OpenBugReportTestProject,
PassCode_2021.OpenBugReport,
PassCode_2021.UpdateBugReportProgress,
PassCode_2021.CloseBugReport,
PassCode_2021.DeleteBugReport);
}
}

View File

@@ -0,0 +1,13 @@
package Common.UI.Menus_2023.CompilersMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class CompilersMenuBar extends DataMenuBar {
public CompilersMenuBar() {
super("компиляторы",
PassCode_2021.AddCompiler,
PassCode_2021.EditCompiler,
PassCode_2021.DeleteCompiler,
PassCode_2021.ShowCompilerVersion,
PassCode_2021.ShowCompilerHelp);
}
}

View File

@@ -0,0 +1,27 @@
package Common.UI.Menus_2023.ComponentsMenuBar;
import Common.Current;
import Common.UI.Menus_2023.DataMenuBar;
import Common.UI.Menus_2023.VisualiserMenu;
import Common.UI.Themes.VisualiserFonts;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
public class ComponentsMenuBar extends DataMenuBar {
public ComponentsMenuBar() {
super("компоненты");
addMenus(
new VisualiserMenu(
"Восстановление предыдущей версии компонента", "/icons/Resurrect.png") {
{
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
add(Pass_2021.passes.get(PassCode_2021.ResurrectComponent).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.ResurrectComponentFromServer).createMenuItem());
}
}
);
addPasses(PassCode_2021.InstallComponentFromFolder,
PassCode_2021.UpdateSelectedComponents,
PassCode_2021.PublishComponent,
PassCode_2021.ShowComponentChangesLog);
Pass_2021.passes.get(PassCode_2021.PublishComponent).setControlsVisible(false);
}
}

View File

@@ -0,0 +1,33 @@
package Common.UI.Menus_2023.ConfigurationsMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class ConfigurationsMenuBar extends DataMenuBar {
public ConfigurationsMenuBar() {
super("конфигурации");
/*
add(new MenuBarButton() {
{
setText("Оповещение по email");
setToolTipText("Оповещение о прогрессе выполнения пакета тестов");
Mark();
addActionListener(e -> {
email = !email;
Mark();
});
}
public void Mark() {
setIcon(Utils.getIcon(email ? "/icons/Pick.png" : "/icons/NotPick.png"));
}
});
*/
addPasses(
PassCode_2021.EditMachineKernels,
PassCode_2021.StartTests,
PassCode_2021.PublishConfiguration,
PassCode_2021.CopyConfigurations,
PassCode_2021.EditConfiguration,
PassCode_2021.DeleteSelectedConfigurations
);
}
}

View File

@@ -0,0 +1,11 @@
package Common.UI.Menus_2023.DVMParametersMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class DVMParametersMenuBar extends DataMenuBar {
public DVMParametersMenuBar() {
super("параметры",
PassCode_2021.AddDVMParameter,
PassCode_2021.EditDVMParameter,
PassCode_2021.DeleteDVMParameter);
}
}

View File

@@ -0,0 +1,54 @@
package Common.UI.Menus_2023;
import Common.Database.DataSet;
import Visual_DVM_2021.Passes.PassCode_2021;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class DataMenuBar extends VisualiserMenuBar {
public JLabel countLabel = null;
JButton selectAllButton = null;
JButton unselectAllButton = null;
//-
public ActionListener selectAllListener = null;
public ActionListener unselectAllListener = null;
//-
public DataMenuBar(String dataName, PassCode_2021... passes) {
// Font font = Current.getTheme().Fonts.get(VisualiserFonts.TreeBoldItalic).deriveFont(12.0F);
add(new JLabel(dataName + " "));
add(countLabel = new JLabel("?"));
addPasses(passes);
}
public void createSelectionButtons(DataSet dataSet) {
java.awt.Dimension d = new Dimension(25, 25);
if (selectAllButton == null) {
add(selectAllButton = new MenuBarButton() {
{
setIcon("/icons/SelectAll.png");
setToolTipText("Выбрать всё");
setPreferredSize(d);
setMinimumSize(d);
setMaximumSize(d);
}
}, 0);
}
if (unselectAllButton == null) {
add(unselectAllButton = new MenuBarButton() {
{
setIcon("/icons/UnselectAll.png");
setToolTipText("Отменить всё");
setPreferredSize(d);
setMinimumSize(d);
setMaximumSize(d);
}
}, 1);
}
if (selectAllListener != null) {
selectAllButton.removeActionListener(selectAllListener); }
selectAllButton.addActionListener(selectAllListener = e -> dataSet.CheckAll(true));
if (unselectAllListener != null) {
unselectAllButton.removeActionListener(unselectAllListener);
}
unselectAllButton.addActionListener(unselectAllListener = e -> dataSet.CheckAll(false));
}
}

View File

@@ -0,0 +1,12 @@
package Common.UI.Menus_2023.EnvironmentValuesMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class EnvironmentValuesMenuBar extends DataMenuBar {
public EnvironmentValuesMenuBar() {
super("переменные окружения", PassCode_2021.AddEnvironmentValue,
PassCode_2021.EditEnvironmentValue,
PassCode_2021.DeleteEnvironmentValue,
PassCode_2021.PickCompilerEnvironments
);
}
}

View File

@@ -0,0 +1,49 @@
package Common.UI.Menus_2023.FastAccessMenuBar;
import Common.Global;
import Common.UI.Menus_2023.VisualiserMenuBar;
import Common.UI.UI;
import GlobalData.Settings.SettingName;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import javax.swing.*;
import java.awt.*;
import java.util.LinkedHashMap;
public class FastAccessMenuBar extends VisualiserMenuBar {
LinkedHashMap<PassCode_2021, JButton> passesButtons = new LinkedHashMap<>();
public FastAccessMenuBar() {
Refresh();
}
@Override
public void setSizeLimits() {
//если задавать PreffredSize 0, скролл НЕ РАБОТАЕТ. Магия!
}
public void showPass(Pass_2021 pass) {
JButton button = null;
if (passesButtons.containsKey(pass.code()))
button = passesButtons.get((pass.code()));
else {
button = pass.createButton();
passesButtons.put(pass.code(), button);
}
add(button);
Dimension d = button.getPreferredSize();
button.setPreferredSize(new Dimension(d.width, 30));
revalidate();
repaint();
}
public void Refresh() {
UI.Clear(this);
int i = 1;
for (Pass_2021 pass : Pass_2021.FAPasses) {
if (pass.stats.HasUsages()) {
showPass(pass);
++i;
if (i > (Global.db.settings.get(SettingName.FastAccessPassesCount).toInt32())) break;
}
}
}
public void Drop(){
UI.Clear(this);
}
}

View File

@@ -0,0 +1,84 @@
package Common.UI.Menus_2023.FileMenuBar;
import Common.UI.Menus_2023.MenuBarButton;
import Common.UI.Menus_2023.VisualiserMenuBar;
import Common.UI.UI;
import ProjectData.Files.UI.Editor.SPFEditor;
import Visual_DVM_2021.Passes.PassCode_2021;
import javax.swing.*;
import java.awt.*;
public class FileMenuBar extends VisualiserMenuBar {
public JSpinner sToGo;
JLabel LineCountLabel;
public JLabel CurrentSymbolLabel;
SPFEditor editor;
FileSettingsMenu fileSettingsMenu;
public FileMenuBar(SPFEditor editor_in) {
editor = editor_in;
add(new MenuBarButton() {
{
setToolTipText("Поиск(Ctrl+F)");
setIcon("/icons/LastOpened.png");
addActionListener(e -> UI.ShowSearchForm());
}
});
addPasses(PassCode_2021.Save);
add(new MenuBarButton() {
{
setToolTipText("Увеличить шрифт(Ctrl+'+')");
setIcon("/icons/Editor/Font+.png");
addActionListener(e -> editor.FontUp());
}
});
add(new MenuBarButton() {
{
setToolTipText("Уменьшить шрифт(Ctrl+'-')");
setIcon("/icons/Editor/Font-.png");
addActionListener(e -> editor.FontDown());
}
});
add(new MenuBarButton() {
boolean isOn = false;
{
setToolTipText("Отображать спецсимволы");
setIcon("/icons/Editor/ShowNoSigns.png");
addActionListener(e-> {
isOn = !isOn;
if (isOn) {
setIcon("/icons/Editor/ShowAllSigns.png");
setToolTipText("Скрыть спецсимволы");
editor.setWhitespaceVisible(true);
editor.setEOLMarkersVisible(true);
} else {
setIcon("/icons/Editor/ShowNoSigns.png");
setToolTipText("Отображать спецсимволы");
editor.setWhitespaceVisible(false);
editor.setEOLMarkersVisible(false);
}
});
}
});
add(new JLabel(" Строка "));
add(sToGo = new JSpinner());
sToGo.setPreferredSize(new Dimension(60, 25));
sToGo.setMaximumSize(new Dimension(60, 25));
add(new JLabel(" из "));
add(LineCountLabel = new JLabel("?"));
add(new JLabel(" | "));
add(new JLabel("Позиция "));
add(CurrentSymbolLabel = new JLabel());
add(new JSeparator());
addMenus(fileSettingsMenu = new FileSettingsMenu());
//--
// addPasses(PassCode_2021.CloseCurrentFile);
//-
setPreferredSize(new Dimension(0, 30));
}
public void ShowLinesCount() {
LineCountLabel.setText(String.valueOf(editor.getLineCount()));
}
//-
public void ShowLanguage(){fileSettingsMenu.ShowLanguage();}
public void ShowType(){fileSettingsMenu.ShowType();}
public void ShowStyle(){fileSettingsMenu.ShowStyle();}
}

View File

@@ -0,0 +1,63 @@
package Common.UI.Menus_2023.FileMenuBar;
import Common.Current;
import Common.UI.Menus_2023.LanguagesSubmenu;
import Common.UI.Menus_2023.StylesSubmenu;
import Common.UI.Menus_2023.TypesSubmenu;
import Common.UI.Menus_2023.VisualiserMenu;
import Common.UI.UI;
import ProjectData.Files.FileType;
import ProjectData.Files.LanguageStyle;
import ProjectData.LanguageName;
import javax.swing.*;
public class FileSettingsMenu extends VisualiserMenu {
JMenu mLanguage;
JMenu mStyle;
JMenu mType;
public FileSettingsMenu() {
super("Настройки файла", "/icons/Settings.png");
add(mLanguage = new LanguagesSubmenu() {
@Override
public void action(LanguageName languageName) {
if (Current.getFile().UpdateLanguage(languageName)) {
Current.getSapfor().ResetAllAnalyses();
Current.getFile().form.ShowLanguage();
UI.getMainWindow().getProjectWindow().getFilesTreeForm().getTree().RefreshNode(Current.getFile().node);
}
}
});
ShowLanguage();
//--
add(mStyle = new StylesSubmenu() {
@Override
public void action(LanguageStyle languageStyle) {
if (Current.getFile().UpdateStyle(languageStyle)) {
Current.getSapfor().ResetAllAnalyses();
Current.getFile().form.ShowStyle();
}
}
});
ShowStyle();
//--
add(mType = new TypesSubmenu() {
@Override
public void action(FileType fileType) {
if (Current.getFile().UpdateType(fileType)) {
Current.getSapfor().ResetAllAnalyses();
UI.getMainWindow().getProjectWindow().getFilesTreeForm().getTree().RefreshNode(Current.getFile().node);
Current.getFile().form.ShowType();
}
}
});
ShowType();
}
public void ShowLanguage() {
mLanguage.setText("Язык: " + Current.getFile().languageName.getDescription());
}
public void ShowStyle() {
mStyle.setText("Стиль: " + Current.getFile().style.getDescription());
}
public void ShowType() {
mType.setText("Тип: " + Current.getFile().fileType.getDescription());
}
}

View File

@@ -0,0 +1,42 @@
package Common.UI.Menus_2023.GroupsMenuBar;
import Common.Global;
import Common.UI.Menus_2023.DataMenuBar;
import Common.UI.Menus_2023.MenuBarButton;
import Common.Utils.Utils;
import TestingSystem.Group.GroupInterface;
import Visual_DVM_2021.Passes.PassCode_2021;
import javax.swing.*;
public class GroupsMenuBar extends DataMenuBar {
public GroupsMenuBar() {
super("группы", PassCode_2021.SynchronizeTests, PassCode_2021.DownloadGroup, PassCode_2021.ConvertCorrectnessTests, PassCode_2021.PublishGroup, PassCode_2021.CopyGroups, PassCode_2021.EditGroup, PassCode_2021.DeleteSelectedGroups);
add(new JSeparator());
add(new MenuBarButton() {
{
setText("Свои");
setToolTipText("Отображать только группы тестов авторства пользователя");
Mark();
addActionListener(e -> {
GroupInterface.filterMyOnly = !GroupInterface.filterMyOnly;
Mark();
Global.testingServer.db.groups.ShowUI();
});
}
public void Mark() {
setIcon(Utils.getIcon(GroupInterface.filterMyOnly ? "/icons/Pick.png" : "/icons/NotPick.png"));
}
});
}
public void addFilters(JMenu typesFilterMenu, JMenu languagesFilterMenu) {
filters = addMenus(typesFilterMenu, languagesFilterMenu);
}
JMenuBar filters= null;
public void DropFilters() {
if (filters != null) {
remove(filters);
filters = null;
}
revalidate();
repaint();
}
}

View File

@@ -0,0 +1,34 @@
package Common.UI.Menus_2023;
import Common.Utils.Utils;
import ProjectData.LanguageName;
import javax.swing.*;
import java.awt.event.ActionEvent;
public abstract class LanguagesSubmenu extends VisualiserMenu {
public LanguagesSubmenu() {
this("Язык");
}
public LanguagesSubmenu(String text) {
super(text, "/icons/Language.png", true);
for (LanguageName languageName : LanguageName.values()) {
if (languageName.equals(LanguageName.fortran) ||
(languageName.equals(LanguageName.c) ||
(languageName.equals(LanguageName.cpp)))) {
JMenuItem languageItem = new StableMenuItem(languageName.getDescription());
String li = languageName.getIcon();
if (!li.isEmpty())
languageItem.setIcon(Utils.getIcon(li));
languageItem.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
action(languageName);
}
});
add(languageItem);
}
}
}
public abstract void action(LanguageName languageName);
}

View File

@@ -0,0 +1,11 @@
package Common.UI.Menus_2023.MachinesMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class MachinesMenuBar extends DataMenuBar {
public MachinesMenuBar() {
super("машины",
PassCode_2021.AddMachine,
PassCode_2021.EditMachine,
PassCode_2021.DeleteMachine);
}
}

View File

@@ -0,0 +1,14 @@
package Common.UI.Menus_2023.MainMenuBar;
import Common.UI.Menus_2023.VisualiserMenu;
import Repository.Component.Sapfor.Sapfor;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
public class AnalysesMenu extends VisualiserMenu {
public AnalysesMenu() {
super("Анализаторы","/icons/Analyses.png" );
for (PassCode_2021 code : Sapfor.getAnalysesCodes())
add(Pass_2021.passes.get(code).createMenuItem());
addSeparator();
add(Pass_2021.passes.get(PassCode_2021.SPF_GetGCovInfo).createMenuItem());
}
}

View File

@@ -0,0 +1,20 @@
package Common.UI.Menus_2023.MainMenuBar;
import Common.UI.Menus_2023.VisualiserMenu;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
public class GlobalCleaningMenu extends VisualiserMenu {
public GlobalCleaningMenu() {
super("Очистка", "/icons/Clean.png", false);
add(Pass_2021.passes.get(PassCode_2021.DropLastProjects).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.DropFastAccess).createMenuItem());
addSeparator();
add(Pass_2021.passes.get(PassCode_2021.DeleteDownloadedBugReports).createMenuItem());
addSeparator();
add(Pass_2021.passes.get(PassCode_2021.DropAnalyses).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.CleanAnalyses).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.DropSavedArrays).createMenuItem());
add(Pass_2021.passes.get(PassCode_2021.DeleteDebugResults).createMenuItem());
addSeparator();
add(Pass_2021.passes.get(PassCode_2021.ResetCurrentProject).createMenuItem());
}
}

View File

@@ -0,0 +1,48 @@
package Common.UI.Menus_2023.MainMenuBar;
import Common.Global;
import Common.UI.Menus.VisualiserMenuItem;
import Common.UI.Menus_2023.VisualiserMenu;
import GlobalData.DBLastProject.DBLastProject;
import GlobalData.Settings.SettingName;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import javax.swing.*;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.Vector;
public class LastOpenedProjectsMenu extends VisualiserMenu {
public LastOpenedProjectsMenu() {
super("Недавние проекты", "/icons/LastOpened.png");
addMenuListener(new MenuListener() {
@Override
public void menuSelected(MenuEvent e) {
removeAll();
Vector<DBLastProject> projects = Global.db.lastProjects.getOrdered();
int k = 1;
for (DBLastProject p : projects) {
if (new File(p.HomePath).exists() && p.lastOpened != 0) {
VisualiserMenuItem i = new VisualiserMenuItem(p.HomePath);
i.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
Pass_2021.passes.get(PassCode_2021.OpenCurrentProject).Do(new File(p.HomePath));
}
});
add(i);
++k;
if (k > (Global.db.settings.get(SettingName.LastOpenedProjectsCount).toInt32())) break;
}
}
}
@Override
public void menuDeselected(MenuEvent e) {
}
@Override
public void menuCanceled(MenuEvent e) {
}
});
}
}

View File

@@ -0,0 +1,87 @@
package Common.UI.Menus_2023.MainMenuBar;
import Common.Global;
import Common.UI.Menus_2023.MenuBarButton;
import Common.UI.Menus_2023.VisualiserMenuBar;
import Common.UI.UI;
import Repository.Component.PerformanceAnalyzer.PerformanceAnalyzer;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
import javax.swing.*;
import java.awt.*;
public class MainMenuBar extends VisualiserMenuBar {
JMenu analyses;
JMenu transformations;
MenuBarButton components;
public MainMenuBar() {
addMenus(new LastOpenedProjectsMenu());
addPasses(PassCode_2021.OpenCurrentProject, PassCode_2021.CreateEmptyProject);
addMenus(
analyses = new AnalysesMenu(),
transformations = new TransformationsMenu(),
new GlobalCleaningMenu(),
new VisualiserSettingsMenu()
);
add(components = new MenuBarButton() {
{
setToolTipText("Компоненты");
setIcon("/icons/ComponentsActual.png");
addActionListener(e -> {
if (PerformanceAnalyzer.isActive) {
UI.Info("Перед работой с компонентами закройте анализатор производительности!");
} else {
Pass_2021.passes.get(PassCode_2021.GetComponentsActualVersions).Do();
Global.RefreshUpdatesStatus();
UI.ShowComponentsWindow();
}
});
}
});
add(new MenuBarButton() {
{
setIcon("/icons/Comparsion.png");
setToolTipText("Анализатор статистик");
addActionListener(e -> {
Global.performanceAnalyzer.Start();
});
}
});
addPasses(PassCode_2021.ShowInstruction);
//-
setPreferredSize(new Dimension(0, 30));
//---
/*
add(new MenuBarButton() {
{
setIcon("/icons/Apply.png");
setToolTipText("Test");
addActionListener(e -> {
Current.getProject().hasSubdirectories();
});
}
});
*/
//---
ShowProject(false);
}
public void ShowUpdatesIcon() {
components.setIcon(
(Global.need_update > 0) || (Global.bad_state > 0)
? "/icons/ComponentsNeedUpdate.gif"
: (Global.need_publish > 0 ? "/icons/ComponentsNeedPublish_2023.gif" : "/icons/ComponentsActual.png"));
}
public void ShowProject(boolean flag) {
analyses.setEnabled(flag);
transformations.setEnabled(flag);
Pass_2021[] cleaningPasses = new Pass_2021[]{
Pass_2021.passes.get(PassCode_2021.DropAnalyses),
Pass_2021.passes.get(PassCode_2021.DropSavedArrays),
Pass_2021.passes.get(PassCode_2021.CleanAnalyses),
Pass_2021.passes.get(PassCode_2021.DeleteDebugResults),
Pass_2021.passes.get(PassCode_2021.ResetCurrentProject)
};
for (Pass_2021 pass: cleaningPasses){
pass.setControlsEnabled(flag);
}
}
}

View File

@@ -0,0 +1,19 @@
package Common.UI.Menus_2023.MainMenuBar;
import Visual_DVM_2021.UI.Interface.CallbackWindow;
import Visual_DVM_2021.UI.Interface.ProjectWindow;
import Visual_DVM_2021.UI.Interface.TestingWindow;
public interface MainWindow {
void Show();
void ShowProject();
void ShowNoProject();
ProjectWindow getProjectWindow();
CallbackWindow getCallbackWindow();
//-
void ShowUpdatesIcon();
void FocusProject();
void FocusCallback();
void FocusTesting();
TestingWindow getTestingWindow();
void ShowTestingTab();
void HideTestingTab();
}

View File

@@ -0,0 +1,36 @@
package Common.UI.Menus_2023.MainMenuBar;
import Common.UI.Menus.PassesSubMenu;
import Common.UI.Menus_2023.VisualiserMenu;
import Repository.Component.Sapfor.Sapfor;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
public class TransformationsMenu extends VisualiserMenu {
public TransformationsMenu() {
super("Преобразования", "/icons/Transformations.png");
add(new PassesSubMenu("Циклы", "/icons/Menu/Loops.png",
Sapfor.getLoopsTransformationsCodes()));
addSeparator();
add(new PassesSubMenu("Приватные переменные", "/icons/Menu/Privates.png",
Sapfor.getPrivatesTransformationsCodes()));
addSeparator();
add(new PassesSubMenu("Процедуры", "/icons/Menu/Functions.png",
Sapfor.getProceduresTransformationsCodes()));
addSeparator();
add(new PassesSubMenu("DVM директивы", "/icons/Menu/Dvm.png",
Sapfor.getDVMTransformationsCodes()));
addSeparator();
add(new PassesSubMenu("Интервалы", "/icons/Menu/Intervals.png",
Sapfor.getIntervalsTransformationsCodes()
));
addSeparator();
add(new PassesSubMenu("Области распараллеливания", "/icons/Menu/Regions.png",
Sapfor.getRegionsTransformationsCodes()
));
addSeparator();
add(new PassesSubMenu("Предобработка проекта", "/icons/Menu/Preprocessing.png",
Sapfor.getPreparationTransformationsCodes()
)
);
add(Pass_2021.passes.get(PassCode_2021.SPF_SharedMemoryParallelization).createMenuItem());
}
}

View File

@@ -0,0 +1,47 @@
package Common.UI.Menus_2023.MainMenuBar;
import Common.Global;
import Common.UI.Menus.PropertiesSubmenu;
import Common.UI.Menus_2023.SettingsSubmenu;
import Common.UI.Menus_2023.VisualiserMenu;
import GlobalData.Settings.SettingName;
public class VisualiserSettingsMenu extends VisualiserMenu {
public VisualiserSettingsMenu() {
super("Настройки визуализатора", "/icons/Settings.png");
//-
add(new PropertiesSubmenu("Подтверждения и уведомления", null,
"ShowPassesDone",
"ConfirmPassesStart",
"FocusPassesResult"
));
add(new SettingsSubmenu("Компактность отображения", null,
SettingName.SmallScreen,
SettingName.ShowFullTabsNames,
SettingName.ShowFullArraysDeclarations,
SettingName.FastAccessPassesCount,
SettingName.LastOpenedProjectsCount
));
if (Global.isWindows) {
add(new SettingsSubmenu("Компиляция на локальной машине", null,
SettingName.LocalMakePathWindows,
SettingName.Kernels
));
} else {
add(new SettingsSubmenu("Компиляция на локальной машине", null,
SettingName.Kernels
));
}
add(new SettingsSubmenu("Синхронизация", null,
SettingName.AutoBugReportsLoad,
SettingName.AutoTestsLoad
));
add(new SettingsSubmenu("Сравнение", null,
SettingName.ExtensionsOn,
SettingName.RegisterOn,
SettingName.SpacesOn,
SettingName.EmptyLinesOn,
SettingName.FortranWrapsOn,
SettingName.ComparsionDiffMergeOn
));
add(Global.db.settings.get(SettingName.Workspace).getMenuItem());
}
}

View File

@@ -0,0 +1,14 @@
package Common.UI.Menus_2023.MakefilesMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class MakefilesMenuBar extends DataMenuBar {
public MakefilesMenuBar() {
super("мейкфайлы",
PassCode_2021.Compile,
PassCode_2021.AddMakefile,
PassCode_2021.EditMakefile,
PassCode_2021.DeleteMakefile);
addSeparator();
addPasses(PassCode_2021.ShowMakefilePreview, PassCode_2021.EditProjectCompilationMaxtime);
}
}

View File

@@ -0,0 +1,32 @@
package Common.UI.Menus_2023;
import Common.Current;
import Common.UI.Themes.VisualiserFonts;
import Common.Utils.Utils;
import javax.swing.*;
import java.awt.*;
//https://java-online.ru/swing-jbutton.xhtml
public class MenuBarButton extends JButton {
public MenuBarButton() {
super();
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
//
setBorderPainted(false);
setContentAreaFilled(false);
setOpaque(false);
//setFocusPainted(false);
//-
setMinimumSize(new Dimension(38, 30)); //иначе сужаются вертикально.
}
@Override
protected void paintComponent(Graphics g) {
if (getModel().isPressed()) {
g.setColor(new Color(163, 184, 204));
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g);
}
public void setIcon(String icon_path) {
setIcon(Utils.getIcon(icon_path));
}
}

View File

@@ -0,0 +1,8 @@
package Common.UI.Menus_2023.ModulesMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class ModulesMenuBar extends DataMenuBar {
public ModulesMenuBar() {
super("языковые модули", PassCode_2021.EditModule);
}
}

View File

@@ -0,0 +1,25 @@
package Common.UI.Menus_2023;
import Visual_DVM_2021.Passes.Pass_2021;
import java.awt.*;
public class PassButton extends MenuBarButton implements PassControl {
public PassButton(Pass_2021 pass, boolean tab) {
setText(pass.getButtonText());
setToolTipText(pass.getDescription());
if (pass.getIconPath() != null) {
if (tab) {
setIcon(pass.getTabIcon());
setPreferredSize(new Dimension(18,18));
setMaximumSize(new Dimension(18,18));
setMinimumSize(new Dimension(18,18));
}
else
setIcon(pass.getIconPath());
}
addActionListener(pass.getControlAction());
pass.controls.add(this);
}
public PassButton(Pass_2021 pass) {
this(pass, false);
}
}

View File

@@ -0,0 +1,7 @@
package Common.UI.Menus_2023;
public interface PassControl {
void setIcon(String icon_path);
void setEnabled(boolean flag);
void setVisible(boolean flag);
void setToolTipText(String text);
}

View File

@@ -0,0 +1,17 @@
package Common.UI.Menus_2023;
import Common.UI.Menus.VisualiserMenuItem;
import Common.Utils.Utils;
import Visual_DVM_2021.Passes.Pass_2021;
public class PassMenuItem extends VisualiserMenuItem implements PassControl {
@Override
public void setIcon(String icon_path) {
setIcon(Utils.getIcon(icon_path));
}
public PassMenuItem(Pass_2021 pass) {
setText(pass.getDescription());
setToolTipText(pass.getDescription());
if (pass.getIconPath() != null) setIcon(pass.getIconPath());
addActionListener(pass.getControlAction());
pass.controls.add(this);
}
}

View File

@@ -0,0 +1,7 @@
package Common.UI.Menus_2023.ProjectMenuBar;
import Common.UI.Menus_2023.VisualiserMenu;
public class FilesOperationsMenu extends VisualiserMenu {
public FilesOperationsMenu() {
super("Массовые операции над файлами","/icons/MassFiles.png" );
}
}

View File

@@ -0,0 +1,33 @@
package Common.UI.Menus_2023.ProjectMenuBar;
import Common.UI.Menus_2023.MenuBarButton;
import Common.UI.Menus_2023.VisualiserMenuBar;
import Common.UI.UI;
import javax.swing.*;
import java.awt.*;
public class ProjectMenuBar extends VisualiserMenuBar {
public ProjectViewMenu projectViewMenu;
public ProjectMenuBar() {
addMenus(projectViewMenu = new ProjectViewMenu());
add(new JSeparator());
addMenus(
new ProjectSettingsMenu()
);
add(new MenuBarButton() {
{
setToolTipText("Профили");
setIcon("/icons/Profiles.png");
addActionListener(e -> {
UI.ShowProfilesWindow();
});
}
});
}
public ProjectViewMenu getProjectViewMenu() {
return projectViewMenu;
}
@Override
public void setSizeLimits() {
setPreferredSize(new Dimension(0, 32));
}
}

View File

@@ -0,0 +1,73 @@
package Common.UI.Menus_2023.ProjectMenuBar;
import Common.Current;
import Common.Global;
import Common.UI.Menus_2023.LanguagesSubmenu;
import Common.UI.Menus_2023.SettingsSubmenu;
import Common.UI.Menus_2023.StylesSubmenu;
import Common.UI.Menus_2023.VisualiserMenu;
import GlobalData.Settings.SettingName;
import ProjectData.Files.LanguageStyle;
import ProjectData.LanguageName;
import javax.swing.*;
public class ProjectSettingsMenu extends VisualiserMenu {
JMenu mLanguage;
JMenu mStyle;
public ProjectSettingsMenu() {
super("Настройки проекта", "/icons/Settings.png");
add(mLanguage = new LanguagesSubmenu() {
@Override
public void action(LanguageName languageName) {
if (Current.getProject().UpdateLanguage(languageName)) {
Current.getSapfor().ResetAllAnalyses();
ShowLanguage();
}
}
});
ShowLanguage();
//--
add(mStyle = new StylesSubmenu() {
@Override
public void action(LanguageStyle languageStyle) {
if (Current.getProject().UpdateStyle(languageStyle))
ShowStyle();
}
});
ShowStyle();
addSeparator();
add(new SettingsSubmenu("Анализ", null,
SettingName.Precompilation,
SettingName.STATIC_SHADOW_ANALYSIS,
SettingName.KEEP_DVM_DIRECTIVES,
SettingName.IGNORE_IO_SAPFOR,
SettingName.MPI_PROGRAM,
SettingName.ANALYSIS_OPTIONS,
SettingName.PARALLELIZE_FREE_LOOPS
));
addSeparator();
add(new SettingsSubmenu("Построение системы интервалов", null,
SettingName.KEEP_LOOPS_CLOSE_NESTING,
SettingName.KEEP_GCOV
));
addSeparator();
add(new SettingsSubmenu("Построение версий", null,
SettingName.FREE_FORM,
SettingName.KEEP_SPF_DIRECTIVES,
SettingName.KEEP_SPF_DIRECTIVES_AMONG_TRANSFORMATIONS,
SettingName.OUTPUT_UPPER,
SettingName.MAX_SHADOW_WIDTH,
SettingName.DVMConvertationOptions,
SettingName.SaveModifications
));
addSeparator();
add(Global.db.settings.get(SettingName.TRANSLATE_MESSAGES).getMenuItem());
add(Global.db.settings.get(SettingName.DEBUG_PRINT_ON).getMenuItem());
add(Global.db.settings.get(SettingName.GCOVLimit).getMenuItem());
}
public void ShowLanguage() {
mLanguage.setText("Язык: " + Current.getProject().languageName.getDescription());
}
public void ShowStyle() {
mStyle.setText("Стиль: " + Current.getProject().style.getDescription());
}
}

View File

@@ -0,0 +1,34 @@
package Common.UI.Menus_2023.ProjectMenuBar;
import Common.Current;
import Common.UI.Menus_2023.VisualiserMenu;
import Common.UI.Themes.VisualiserFonts;
import Common.UI.UI;
import Common.Utils.Utils;
import ProjectData.ProjectView;
import javax.swing.*;
import java.util.LinkedHashMap;
public class ProjectViewMenu extends VisualiserMenu {
LinkedHashMap<ProjectView, JMenuItem> views;
public ProjectViewMenu() {
super("", "");
views = new LinkedHashMap<>();
for (ProjectView view : ProjectView.values()) {
JMenuItem m = new JMenuItem(view.getDescription()) {
{
setIcon(Utils.getIcon(view.getIcon()));
setFont(Current.getTheme().Fonts.get(VisualiserFonts.TreeItalic));
addActionListener(e -> {
Current.set(Current.ProjectView, view);
UI.getMainWindow().getProjectWindow().ShowProjectView();
});
}
};
add(m);
views.put(view, m);
}
}
public void SelectView(ProjectView view){
views.get(view).doClick();
}
}

View File

@@ -0,0 +1,11 @@
package Common.UI.Menus_2023.RemoteSapforsMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class RemoteSapforsMenuBar extends DataMenuBar {
public RemoteSapforsMenuBar() {
super("SAPFOR", PassCode_2021.InstallRemoteSapfor,
PassCode_2021.AddSapfor,
PassCode_2021.EditSapfor,
PassCode_2021.DeleteSapfor);
}
}

View File

@@ -0,0 +1,13 @@
package Common.UI.Menus_2023.RunConfigurationsMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
import javax.swing.*;
public class RunConfigurationsMenuBar extends DataMenuBar {
public RunConfigurationsMenuBar() {
super("конфигурации запуска", PassCode_2021.Run,
PassCode_2021.AddRunConfiguration, PassCode_2021.EditRunConfiguration, PassCode_2021.DeleteRunConfiguration);
add(new JSeparator());
addPasses(PassCode_2021.EditProjectRunMaxtime);
}
}

View File

@@ -0,0 +1,12 @@
package Common.UI.Menus_2023.SapforConfigurationCommandsMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class SapforConfigurationCommandsMenuBar extends DataMenuBar {
public SapforConfigurationCommandsMenuBar() {
super("команды",
PassCode_2021.PublishSapforConfigurationCommand,
PassCode_2021.EditSapforConfigurationCommand,
PassCode_2021.DeleteSapforConfigurationCommand
);
}
}

View File

@@ -0,0 +1,12 @@
package Common.UI.Menus_2023.SapforConfigurationsMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class SapforConfigurationsMenuBar extends DataMenuBar {
public SapforConfigurationsMenuBar() {
super("конфигурации", PassCode_2021.StartSapforTests,
PassCode_2021.PublishSapforConfiguration,
PassCode_2021.EditSapforConfiguration,
PassCode_2021.DeleteSapforConfiguration
);
}
}

View File

@@ -0,0 +1,8 @@
package Common.UI.Menus_2023.SapforTasksMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class SapforTasksMenuBar extends DataMenuBar {
public SapforTasksMenuBar() {
super("задачи", PassCode_2021.OpenSapforTest);
}
}

View File

@@ -0,0 +1,8 @@
package Common.UI.Menus_2023.SapforTasksPackagesBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class SapforTasksPackagesBar extends DataMenuBar {
public SapforTasksPackagesBar() {
super("пакеты задач", PassCode_2021.DeleteSapforTasksPackage);
}
}

View File

@@ -0,0 +1,19 @@
package Common.UI.Menus_2023;
import Common.Current;
import Common.Global;
import Common.UI.Themes.VisualiserFonts;
import Common.Utils.Utils;
import GlobalData.Settings.SettingName;
import javax.swing.*;
public class SettingsSubmenu extends JMenu {
public SettingsSubmenu(String title, String icon, SettingName... settings) {
super(title);
if (icon != null)
setIcon(Utils.getIcon(icon));
setFont(Current.getTheme().Fonts.get(VisualiserFonts.Menu));
for (SettingName c : settings) {
add(Global.db.settings.get(c).getMenuItem());
}
}
}

View File

@@ -0,0 +1,41 @@
package Common.UI.Menus_2023;
import Common.UI.Menus.VisualiserMenuItem;
import Common.UI.UI;
import Common.Utils.Utils;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicMenuItemUI;
//неичезающий меню итем. нужен для настроек
//https://translated.turbopages.org/proxy_u/en-ru.ru.64537f6c-6460c460-8e74a1ab-74722d776562/https/tips4java.wordpress.com/2010/09/12/keeping-menus-open/
class StableItemUI extends BasicMenuItemUI {
public static ComponentUI createUI(JComponent c) {
return new StableItemUI();
}
@Override
protected void doClick(MenuSelectionManager msm) {
menuItem.doClick(0);
if (UI.last_menu_path != null)
MenuSelectionManager.defaultManager().setSelectedPath(UI.last_menu_path);
}
}
public class StableMenuItem extends VisualiserMenuItem {
{
getModel().addChangeListener(e -> {
if (getModel().isArmed() && isShowing())
UI.last_menu_path = MenuSelectionManager.defaultManager().getSelectedPath();
});
}
public StableMenuItem(String text) {
super(text);
setUI(new StableItemUI());
}
public StableMenuItem(String text, String icon_path) {
super(text);
setIcon(Utils.getIcon(icon_path));
setUI(new StableItemUI());
}
public StableMenuItem() {
setUI(new StableItemUI());
}
}

View File

@@ -0,0 +1,16 @@
package Common.UI.Menus_2023;
import Common.Utils.Utils;
import Visual_DVM_2021.Passes.Pass_2021;
public class StablePassMenuItem extends StableMenuItem implements PassControl {
@Override
public void setIcon(String icon_path) {
setIcon(Utils.getIcon(icon_path));
}
public StablePassMenuItem(Pass_2021 pass) {
setText(pass.getDescription());
setToolTipText(pass.getDescription());
if (pass.getIconPath() != null) setIcon(pass.getIconPath());
addActionListener(pass.getControlAction());
pass.controls.add(this);
}
}

View File

@@ -0,0 +1,25 @@
package Common.UI.Menus_2023;
import ProjectData.Files.LanguageStyle;
import javax.swing.*;
import java.awt.event.ActionEvent;
public abstract class StylesSubmenu extends VisualiserMenu {
public StylesSubmenu() {
this("Стиль");
}
public StylesSubmenu(String text) {
super(text, "/icons/Style.png", true);
for (LanguageStyle languageStyle : LanguageStyle.values()) {
JMenuItem m = new StableMenuItem(languageStyle.getDescription());
m.addActionListener(
new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
action(languageStyle);
}
});
add(m);
}
}
public abstract void action(LanguageStyle languageStyle);
}

View File

@@ -0,0 +1,13 @@
package Common.UI.Menus_2023.SubscribersMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class SubscribersMenuBar extends DataMenuBar {
public SubscribersMenuBar() {
super("Адресаты",
PassCode_2021.SaveBugReportExecutor,
PassCode_2021.SaveBugReportRecipients,
PassCode_2021.AddSubscriber,
PassCode_2021.EditSubscriber,
PassCode_2021.DeleteSubscriber);
}
}

View File

@@ -0,0 +1,51 @@
package Common.UI.Menus_2023.TasksPackagesMenuBar;
import Common.Current;
import Common.UI.Menus_2023.DataMenuBar;
import Common.UI.Menus_2023.MenuBarButton;
import Common.UI.Themes.VisualiserFonts;
import Common.UI.UI;
import Common.Utils.Utils;
import TestingSystem.TestingServer;
import Visual_DVM_2021.Passes.PassCode_2021;
import javax.swing.*;
import java.awt.*;
public class TasksPackagesMenuBar extends DataMenuBar {
JButton autorefreshButton;
JSpinner sCheckTime;
public TasksPackagesMenuBar() {
super("пакеты задач", PassCode_2021.SynchronizeTestsTasks, PassCode_2021.AbortSelectedPackages);
add(autorefreshButton = new MenuBarButton() {
{
setText("проверка раз в");
setToolTipText("автоматическое обновление состояния пакета задач");
Mark();
addActionListener(e -> {
TestingServer.checkTasks = !TestingServer.checkTasks;
TestingServer.switchTimer(TestingServer.checkTasks);
Mark();
});
}
public void Mark() {
setIcon(Utils.getIcon(TestingServer.checkTasks ? "/icons/Pick.png" : "/icons/NotPick.png"));
}
});
add(sCheckTime = new JSpinner());
sCheckTime.setPreferredSize(new Dimension(60, 26));
sCheckTime.setMaximumSize(new Dimension(60, 26));
sCheckTime.setModel(new SpinnerNumberModel(TestingServer.checkIntervalSecond, 10, 3600, 1));
UI.MakeSpinnerRapid(sCheckTime, e -> {
TestingServer.checkIntervalSecond = (int) sCheckTime.getValue();
if (TestingServer.checkTasks) TestingServer.ResetTimer();
});
add(new JLabel(" сек") {
{
setFont(Current.getTheme().Fonts.get(VisualiserFonts.TreeItalic));
}
});
}
public void ShowAutorefresh() {
autorefreshButton.setIcon(Utils.getIcon(TestingServer.checkTasks ? "/icons/Pick.png" : "/icons/NotPick.png"));
}
}

View File

@@ -0,0 +1,22 @@
package Common.UI.Menus_2023.TestRunTasksMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
import javax.swing.*;
public class TestRunTasksMenuBar extends DataMenuBar {
JMenuBar filters= null;
public void DropFilters() {
if (filters != null) {
remove(filters);
filters = null;
}
revalidate();
repaint();
}
public void addFilters(JMenu cFilterMenu, JMenu rFilterMenu) {
filters= addMenus(cFilterMenu, rFilterMenu);
}
public TestRunTasksMenuBar() {
super("задачи", PassCode_2021.DownloadTaskTest);
}
}

View File

@@ -0,0 +1,12 @@
package Common.UI.Menus_2023.TestsMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class TestsMenuBar extends DataMenuBar {
public TestsMenuBar() {
super("тесты",
PassCode_2021.DownloadTest,
PassCode_2021.PublishTest,
PassCode_2021.EditTest,
PassCode_2021.DeleteSelectedTests);
}
}

View File

@@ -0,0 +1,26 @@
package Common.UI.Menus_2023;
import ProjectData.Files.FileType;
import javax.swing.*;
import java.awt.event.ActionEvent;
public abstract class TypesSubmenu extends VisualiserMenu {
public TypesSubmenu() {
this("Тип");
}
public TypesSubmenu(String text) {
super(text, "/icons/type.png", true);
for (FileType fileType : FileType.values()) {
if (fileType != FileType.forbidden) {
JMenuItem m = new StableMenuItem(fileType.getDescription());
m.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
action(fileType);
}
});
add(m);
}
}
}
public abstract void action(FileType fileType);
}

View File

@@ -0,0 +1,11 @@
package Common.UI.Menus_2023.UsersMenuBar;
import Common.UI.Menus_2023.DataMenuBar;
import Visual_DVM_2021.Passes.PassCode_2021;
public class UsersMenuBar extends DataMenuBar {
public UsersMenuBar() {
super("пользователи", PassCode_2021.AddUser,
PassCode_2021.EditUser,
PassCode_2021.InitialiseUser,
PassCode_2021.DeleteUser);
}
}

View File

@@ -0,0 +1,28 @@
package Common.UI.Menus_2023.VariantsMenuBar;
import Common.UI.Menus.VisualiserMenuItem;
import Common.UI.Menus_2023.DataMenuBar;
import Common.UI.Menus_2023.VisualiserMenu;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.Pass_2021;
public class VariantsMenuBar extends DataMenuBar {
public VariantsMenuBar() {
super("варианты");
addMenus(new VisualiserMenu("Отображение параллельных вариантов",
"/icons/ShowPassword.png") {
{
add(new VisualiserMenuItem("Все варианты") {
{
addActionListener(e -> Pass_2021.passes.get(PassCode_2021.GenerateParallelVariants).Do(true));
}
});
add(new VisualiserMenuItem("Минимальное покрытие вариантов") {
{
addActionListener(e -> Pass_2021.passes.get(PassCode_2021.GenerateParallelVariants).Do(false));
}
});
}
;
});
addPasses(PassCode_2021.PredictParallelVariants, PassCode_2021.CreateParallelVariants);
}
}

Some files were not shown because too many files have changed in this diff Show More