// Path: src/main/java/ru/taximaxim/pgsqlblocks/common/models/DBProcess.java
// public class DBProcess implements IObject {
// 
//     private List<DBProcess> parents = new ArrayList<>();
//     private List<DBProcess> children = new ArrayList<>();
// 
//     private final Set<DBBlock> blocks = new HashSet<>();
// 
//     private final int pid;
//     private final String state;
//     private final String backendType;
//     private final Date stateChange; //изменено
//     private final DBProcessQuery query;
//     private final DBProcessQueryCaller queryCaller;
// 
//     private DBProcessStatus status = DBProcessStatus.WORKING;
// 
//     public DBProcess(int pid, String backendType, DBProcessQueryCaller queryCaller, String state, Date stateChange, DBProcessQuery query) {
//         this.pid = pid;
//         this.backendType = backendType;
//         this.queryCaller = queryCaller;
//         this.state = state;
//         this.stateChange = stateChange;
//         this.query = query;
//     }
// 
//     public void addBlock(DBBlock block) {
//         blocks.add(block);
//     }
// 
//     public List<DBProcess> getParents() {
//         return parents;
//     }
// 
//     public void addChild(DBProcess process) {
//         children.add(process);
//     }
// 
//     public void addParent(DBProcess parentProcess) {
//         this.parents.add(parentProcess);
//     }
// 
//     public boolean hasParent() {
//         return !parents.isEmpty();
//     }
// 
//     public DBProcessStatus getStatus() {
//         return status;
//     }
// 
//     public void setStatus(DBProcessStatus status) {
//         this.status = status;
//     }
// 
//     public Set<DBBlock> getBlocks() {
//         return blocks;
//     }
// 
//     public String getBlocksPidsString() {
//         return blocks.stream()
//                 .map(b -> String.valueOf(b.getBlockingPid()))
//                 .collect(Collectors.joining(","));
//     }
// 
//     public String getBlocksLocktypesString() {
//         return blocks.stream()
//                 .map(DBBlock::getLocktype)
//                 .distinct()
//                 .collect(Collectors.joining(","));
//     }
// 
//     public String getBlocksRelationsString() {
//         return blocks.stream()
//                 .map(DBBlock::getRelation)
//                 .filter(r -> r != null && !r.isEmpty())
//                 .distinct()
//                 .collect(Collectors.joining(","));
//     }
// 
//     public int getPid() {
//         return pid;
//     }
// 
//     public String getBackendType() {
//         return backendType;
//     }
// 
//     public String getState() {
//         return state;
//     }
// 
//     public Date getStateChange() {
//         return stateChange;
//     }
// 
//     public DBProcessQuery getQuery() {
//         return query;
//     }
// 
//     public DBProcessQueryCaller getQueryCaller() {
//         return queryCaller;
//     }
// 
//     @Override
//     public List<DBProcess> getChildren() {
//         return children;
//     }
// 
//     @Override
//     public boolean hasChildren() {
//         return !children.isEmpty();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof DBProcess)) return false;
// 
//         DBProcess process = (DBProcess) o;
// 
//         return pid == process.pid;
//     }
// 
//     @Override
//     public int hashCode() {
//         return pid;
//     }
// 
//     @Override
//     public String toString() {
//         return "DBProcess{" +
//                 "parents=" + parents +
//                 ", children=" + children.size() +
//                 ", blocks=" + blocks +
//                 ", pid=" + pid +
//                 ", state='" + state + '\'' +
//                 ", stateChange=" + stateChange +
//                 ", query=" + query +
//                 ", queryCaller=" + queryCaller +
//                 ", status=" + status +
//                 '}';
//     }
// }


import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import ru.taximaxim.pgsqlblocks.common.models.DBProcess;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
        buttonBar.setLayout(layout);
        buttonBar.setLayoutData(btnData);

        Button cancelProcessButton = new Button(buttonBar, SWT.PUSH);
        cancelProcessButton.setText(resourceBundle.getString("cancel_process"));
        cancelProcessButton.setToolTipText("pg_cancel_backend");
        cancelProcessButton.addListener(SWT.Selection, event -> {
            listeners.forEach(DBProcessInfoViewListener::dbProcessInfoViewCancelProcessButtonClicked);
        });

        Button terminateProcessButton = new Button(buttonBar, SWT.PUSH);
        terminateProcessButton.setText(resourceBundle.getString("kill_process"));
        terminateProcessButton.setToolTipText("pg_terminate_backend");
        terminateProcessButton.addListener(SWT.Selection, event -> {
            listeners.forEach(DBProcessInfoViewListener::dbProcessInfoViewTerminateProcessButtonClicked);
        });

        processInfoText = new Text(this, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL);
        GridData textLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
        textLayoutData.heightHint = 200;
        processInfoText.setLayoutData(textLayoutData);
    }

    public void hideToolBar() {
        this.buttonBar.setVisible(false);
        GridData layoutData = (GridData) this.buttonBar.getLayoutData();
        layoutData.exclude = true;
        this.layout();
    }

// Path: src/main/java/ru/taximaxim/pgsqlblocks/common/models/DBProcess.java
// public class DBProcess implements IObject {
// 
//     private List<DBProcess> parents = new ArrayList<>();
//     private List<DBProcess> children = new ArrayList<>();
// 
//     private final Set<DBBlock> blocks = new HashSet<>();
// 
//     private final int pid;
//     private final String state;
//     private final String backendType;
//     private final Date stateChange; //изменено
//     private final DBProcessQuery query;
//     private final DBProcessQueryCaller queryCaller;
// 
//     private DBProcessStatus status = DBProcessStatus.WORKING;
// 
//     public DBProcess(int pid, String backendType, DBProcessQueryCaller queryCaller, String state, Date stateChange, DBProcessQuery query) {
//         this.pid = pid;
//         this.backendType = backendType;
//         this.queryCaller = queryCaller;
//         this.state = state;
//         this.stateChange = stateChange;
//         this.query = query;
//     }
// 
//     public void addBlock(DBBlock block) {
//         blocks.add(block);
//     }
// 
//     public List<DBProcess> getParents() {
//         return parents;
//     }
// 
//     public void addChild(DBProcess process) {
//         children.add(process);
//     }
// 
//     public void addParent(DBProcess parentProcess) {
//         this.parents.add(parentProcess);
//     }
// 
//     public boolean hasParent() {
//         return !parents.isEmpty();
//     }
// 
//     public DBProcessStatus getStatus() {
//         return status;
//     }
// 
//     public void setStatus(DBProcessStatus status) {
//         this.status = status;
//     }
// 
//     public Set<DBBlock> getBlocks() {
//         return blocks;
//     }
// 
//     public String getBlocksPidsString() {
//         return blocks.stream()
//                 .map(b -> String.valueOf(b.getBlockingPid()))
//                 .collect(Collectors.joining(","));
//     }
// 
//     public String getBlocksLocktypesString() {
//         return blocks.stream()
//                 .map(DBBlock::getLocktype)
//                 .distinct()
//                 .collect(Collectors.joining(","));
//     }
// 
//     public String getBlocksRelationsString() {
//         return blocks.stream()
//                 .map(DBBlock::getRelation)
//                 .filter(r -> r != null && !r.isEmpty())
//                 .distinct()
//                 .collect(Collectors.joining(","));
//     }
// 
//     public int getPid() {
//         return pid;
//     }
// 
//     public String getBackendType() {
//         return backendType;
//     }
// 
//     public String getState() {
//         return state;
//     }
// 
//     public Date getStateChange() {
//         return stateChange;
//     }
// 
//     public DBProcessQuery getQuery() {
//         return query;
//     }
// 
//     public DBProcessQueryCaller getQueryCaller() {
//         return queryCaller;
//     }
// 
//     @Override
//     public List<DBProcess> getChildren() {
//         return children;
//     }
// 
//     @Override
//     public boolean hasChildren() {
//         return !children.isEmpty();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof DBProcess)) return false;
// 
//         DBProcess process = (DBProcess) o;
// 
//         return pid == process.pid;
//     }
// 
//     @Override
//     public int hashCode() {
//         return pid;
//     }
// 
//     @Override
//     public String toString() {
//         return "DBProcess{" +
//                 "parents=" + parents +
//                 ", children=" + children.size() +
//                 ", blocks=" + blocks +
//                 ", pid=" + pid +
//                 ", state='" + state + '\'' +
//                 ", stateChange=" + stateChange +
//                 ", query=" + query +
//                 ", queryCaller=" + queryCaller +
//                 ", status=" + status +
//                 '}';
//     }
// }


// Path: src/main/java/ru/taximaxim/pgsqlblocks/common/ui/DBProcessInfoView.java
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import ru.taximaxim.pgsqlblocks.common.models.DBProcess;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

        buttonBar.setLayout(layout);
        buttonBar.setLayoutData(btnData);

        Button cancelProcessButton = new Button(buttonBar, SWT.PUSH);
        cancelProcessButton.setText(resourceBundle.getString("cancel_process"));
        cancelProcessButton.setToolTipText("pg_cancel_backend");
        cancelProcessButton.addListener(SWT.Selection, event -> {
            listeners.forEach(DBProcessInfoViewListener::dbProcessInfoViewCancelProcessButtonClicked);
        });

        Button terminateProcessButton = new Button(buttonBar, SWT.PUSH);
        terminateProcessButton.setText(resourceBundle.getString("kill_process"));
        terminateProcessButton.setToolTipText("pg_terminate_backend");
        terminateProcessButton.addListener(SWT.Selection, event -> {
            listeners.forEach(DBProcessInfoViewListener::dbProcessInfoViewTerminateProcessButtonClicked);
        });

        processInfoText = new Text(this, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL);
        GridData textLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
        textLayoutData.heightHint = 200;
        processInfoText.setLayoutData(textLayoutData);
    }

    public void hideToolBar() {
        this.buttonBar.setVisible(false);
        GridData layoutData = (GridData) this.buttonBar.getLayoutData();
        layoutData.exclude = true;
        this.layout();
    }

    public void show(DBProcess process) {