// Path: src/main/java/ru/taximaxim/pgsqlblocks/ui/UIAppender.java
// @Plugin(name = UIAppender.PLUGIN_NAME, category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
// public final class UIAppender extends AbstractAppender {
// 
//     public static final String PLUGIN_NAME = "TextComposite";
// 
//     private static final List<Listener> LISTENERS = new ArrayList<>();
// 
//     public static void addListener(Listener e) {
//         LISTENERS.add(e);
//     }
// 
//     public static void removeListener(Listener e) {
//         LISTENERS.remove(e);
//     }
// 
//     private UIAppender(String name, Layout<?> layout, Filter filter, boolean ignoreExceptions) {
//         super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
//     }
// 
//     @Override
//     public void append(LogEvent event) {
//         String text = new String(getLayout().toByteArray(event), StandardCharsets.UTF_8);
//         Event ev = new Event();
//         ev.data = text;
//         for (Listener listener : LISTENERS) {
//             listener.handleEvent(ev);
//         }
//     }
// 
//     @PluginFactory
//     public static UIAppender createAppender(
//             @PluginAttribute("name") String name,
//             @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
//             @PluginElement("Layout") Layout<?> layout,
//             @PluginElement("Filters") Filter filter) {
//         if (name == null) {
//             LOGGER.error("No name provided for UIAppender");
//             return null;
//         }
// 
//         if (layout == null) {
//             layout = PatternLayout.createDefaultLayout();
//         }
// 
//         return new UIAppender(name, layout, filter, ignoreExceptions);
//     }
// }


import ru.taximaxim.pgsqlblocks.ui.UIAppender;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextContent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Listener;

    private final ModifyListener modifyListener = (ModifyEvent e) -> {
        if (text.getText().length() > TEXT_LIMIT) {
            styledTextContent.replaceTextRange(0, text.getText().length() - TEXT_LIMIT - 1, "");
            styledTextContent.replaceTextRange(0, styledTextContent.getLine(0).length(), "");
        }
        if (autoScrollEnabled) {
            text.setTopIndex(text.getLineCount() - 1);
        }
    };

    private final Listener logListener = e -> {
        Display display = getDisplay();
        if (display != null && !display.isDisposed()) {
            display.asyncExec(() -> {
                if (text != null && !text.isDisposed()) {
                    text.append(e.data.toString());
                }
            });
        }
    };

    public LogsView(Composite parent, int style) {
        super(parent, style);
        GridLayout layout = new GridLayout();
        layout.marginTop = 0;
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
        setLayout(layout);
        setLayoutData(layoutData);
        createContent();
// Path: src/main/java/ru/taximaxim/pgsqlblocks/ui/UIAppender.java
// @Plugin(name = UIAppender.PLUGIN_NAME, category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
// public final class UIAppender extends AbstractAppender {
// 
//     public static final String PLUGIN_NAME = "TextComposite";
// 
//     private static final List<Listener> LISTENERS = new ArrayList<>();
// 
//     public static void addListener(Listener e) {
//         LISTENERS.add(e);
//     }
// 
//     public static void removeListener(Listener e) {
//         LISTENERS.remove(e);
//     }
// 
//     private UIAppender(String name, Layout<?> layout, Filter filter, boolean ignoreExceptions) {
//         super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
//     }
// 
//     @Override
//     public void append(LogEvent event) {
//         String text = new String(getLayout().toByteArray(event), StandardCharsets.UTF_8);
//         Event ev = new Event();
//         ev.data = text;
//         for (Listener listener : LISTENERS) {
//             listener.handleEvent(ev);
//         }
//     }
// 
//     @PluginFactory
//     public static UIAppender createAppender(
//             @PluginAttribute("name") String name,
//             @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
//             @PluginElement("Layout") Layout<?> layout,
//             @PluginElement("Filters") Filter filter) {
//         if (name == null) {
//             LOGGER.error("No name provided for UIAppender");
//             return null;
//         }
// 
//         if (layout == null) {
//             layout = PatternLayout.createDefaultLayout();
//         }
// 
//         return new UIAppender(name, layout, filter, ignoreExceptions);
//     }
// }


// Path: src/main/java/ru/taximaxim/pgsqlblocks/modules/logs/view/LogsView.java
import ru.taximaxim.pgsqlblocks.ui.UIAppender;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextContent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Listener;


    private final ModifyListener modifyListener = (ModifyEvent e) -> {
        if (text.getText().length() > TEXT_LIMIT) {
            styledTextContent.replaceTextRange(0, text.getText().length() - TEXT_LIMIT - 1, "");
            styledTextContent.replaceTextRange(0, styledTextContent.getLine(0).length(), "");
        }
        if (autoScrollEnabled) {
            text.setTopIndex(text.getLineCount() - 1);
        }
    };

    private final Listener logListener = e -> {
        Display display = getDisplay();
        if (display != null && !display.isDisposed()) {
            display.asyncExec(() -> {
                if (text != null && !text.isDisposed()) {
                    text.append(e.data.toString());
                }
            });
        }
    };

    public LogsView(Composite parent, int style) {
        super(parent, style);
        GridLayout layout = new GridLayout();
        layout.marginTop = 0;
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
        setLayout(layout);
        setLayoutData(layoutData);
        createContent();
        UIAppender.addListener(logListener);