org.jkiss.dbeaver.ui.editors.sql.SQLEditorNested.java Source code

Java tutorial

Introduction

Here is the source code for org.jkiss.dbeaver.ui.editors.sql.SQLEditorNested.java

Source

/*
 * DBeaver - Universal Database Manager
 * Copyright (C) 2010-2016 Serge Rieder (serge@jkiss.org)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (version 2)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.jkiss.dbeaver.ui.editors.sql;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.text.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.core.CoreCommands;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.compile.DBCCompileLog;
import org.jkiss.dbeaver.model.exec.compile.DBCSourceHost;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.runtime.TasksJob;
import org.jkiss.dbeaver.ui.*;
import org.jkiss.dbeaver.ui.controls.ObjectCompilerLogViewer;
import org.jkiss.dbeaver.ui.controls.ProgressPageControl;
import org.jkiss.dbeaver.ui.controls.folders.ITabbedFolderEditorSite;
import org.jkiss.dbeaver.ui.editors.IDatabaseEditorInput;
import org.jkiss.dbeaver.ui.editors.entity.EntityEditor;
import org.jkiss.dbeaver.ui.editors.text.BaseTextDocumentProvider;
import org.jkiss.dbeaver.utils.RuntimeUtils;

import java.lang.reflect.InvocationTargetException;

/**
 * SQLEditorNested
 */
public abstract class SQLEditorNested<T extends DBSObject> extends SQLEditorBase
        implements IActiveWorkbenchPart, IRefreshablePart, DBCSourceHost {

    private EditorPageControl pageControl;
    private ObjectCompilerLogViewer compileLog;
    private Control editorControl;
    private SashForm editorSash;

    public SQLEditorNested() {
        super();

        setDocumentProvider(new ObjectDocumentProvider());
        //setHasVerticalRuler(false);
    }

    @Override
    public IDatabaseEditorInput getEditorInput() {
        return (IDatabaseEditorInput) super.getEditorInput();
    }

    @Override
    public T getSourceObject() {
        IDatabaseEditorInput editorInput = getEditorInput();
        if (editorInput == null) {
            return null;
        }
        return (T) editorInput.getDatabaseObject();
    }

    @Override
    public DBCExecutionContext getExecutionContext() {
        IDatabaseEditorInput editorInput = getEditorInput();
        if (editorInput == null) {
            return null;
        }
        return editorInput.getExecutionContext();
    }

    @Override
    public void createPartControl(Composite parent) {
        pageControl = new EditorPageControl(parent, SWT.SHEET);

        boolean hasCompiler = getCompileCommandId() != null;

        if (hasCompiler) {
            editorSash = new SashForm(pageControl.createContentContainer(), SWT.VERTICAL | SWT.SMOOTH);
            super.createPartControl(editorSash);

            editorControl = editorSash.getChildren()[0];
            compileLog = new ObjectCompilerLogViewer(editorSash, false);
        } else {
            super.createPartControl(pageControl.createContentContainer());
        }

        // Create new or substitute progress control
        ProgressPageControl progressControl = null;
        IWorkbenchPartSite site = getSite();
        if (site instanceof ITabbedFolderEditorSite
                && ((ITabbedFolderEditorSite) site).getFolderEditor() instanceof IProgressControlProvider) {
            progressControl = ((IProgressControlProvider) ((ITabbedFolderEditorSite) site).getFolderEditor())
                    .getProgressControl();
        } else if (site instanceof MultiPageEditorSite
                && ((MultiPageEditorSite) site).getMultiPageEditor() instanceof IProgressControlProvider) {
            progressControl = ((IProgressControlProvider) ((MultiPageEditorSite) site).getMultiPageEditor())
                    .getProgressControl();
        }
        if (progressControl != null) {
            pageControl.substituteProgressPanel(progressControl);
        } else {
            pageControl.createProgressPanel();
        }
        pageControl.setInfo("Source");

        if (hasCompiler) {
            editorSash.setWeights(new int[] { 70, 30 });
            editorSash.setMaximizedControl(editorControl);
        }

        // Use focus to activate page control
        final Control editorControl = getEditorControl();
        assert editorControl != null;
        editorControl.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                if (pageControl != null && !pageControl.isDisposed()) {
                    pageControl.activate(true);
                }
            }

            @Override
            public void focusLost(FocusEvent e) {
                if (pageControl != null && !pageControl.isDisposed()) {
                    pageControl.activate(false);
                }
            }
        });
    }

    @Override
    public void doSave(final IProgressMonitor progressMonitor) {
        UIUtils.runInUI(null, new Runnable() {
            @Override
            public void run() {
                SQLEditorNested.super.doSave(progressMonitor);
            }
        });
    }

    @Override
    public void activatePart() {
    }

    @Override
    public void deactivatePart() {
    }

    @Override
    public void refreshPart(Object source, boolean force) {
        // Check if we are in saving process
        // If so then no refresh needed (source text was updated during save)
        IEditorSite editorSite = getEditorSite();
        if (editorSite instanceof MultiPageEditorSite
                && ((MultiPageEditorSite) editorSite).getMultiPageEditor() instanceof EntityEditor
                && ((EntityEditor) ((MultiPageEditorSite) editorSite).getMultiPageEditor()).isSaveInProgress()) {
            return;
        }

        final IDocumentProvider documentProvider = getDocumentProvider();
        if (documentProvider instanceof SQLEditorNested.ObjectDocumentProvider) {
            ((SQLEditorNested.ObjectDocumentProvider) documentProvider).sourceText = null;
        }
        if (force) {
            try {
                super.init(editorSite, getEditorInput());
                //setFocus();
            } catch (PartInitException e) {
                log.error(e);
            }
        }
    }

    protected String getCompileCommandId() {
        return null;
    }

    private class ObjectDocumentProvider extends BaseTextDocumentProvider {

        private String sourceText;

        @Override
        public boolean isReadOnly(Object element) {
            return SQLEditorNested.this.isReadOnly();
        }

        @Override
        public boolean isModifiable(Object element) {
            return !SQLEditorNested.this.isReadOnly();
        }

        @Override
        protected IDocument createDocument(Object element) throws CoreException {
            final Document document = new Document();

            if (sourceText == null) {
                document.set(SQLUtils.generateCommentLine(getDataSource(),
                        "Loading '" + getEditorInput().getName() + "' source..."));
                TasksJob.runTask("Read source", new DBRRunnableWithProgress() {
                    @Override
                    public void run(final DBRProgressMonitor monitor)
                            throws InvocationTargetException, InterruptedException {
                        try {
                            sourceText = getSourceText(monitor);
                            if (sourceText == null) {
                                sourceText = SQLUtils.generateCommentLine(getDataSource(), "Empty source");
                            }
                        } catch (Throwable e) {
                            sourceText = "/* ERROR WHILE READING SOURCE:\n\n" + e.getMessage() + "\n*/";
                            throw new InvocationTargetException(e);
                        } finally {
                            if (!isDisposed()) {
                                UIUtils.runInUI(null, new Runnable() {
                                    @Override
                                    public void run() {
                                        resetDocumentContents(monitor);
                                    }
                                });
                            }
                        }
                    }
                });
            } else {
                // Set text
                document.set(sourceText);
            }

            return document;
        }

        private void resetDocumentContents(DBRProgressMonitor monitor) {
            try {
                doResetDocument(getEditorInput(), RuntimeUtils.getNestedMonitor(monitor));
                // Reset undo queue
                if (getSourceViewer() instanceof ITextViewerExtension6) {
                    ((ITextViewerExtension6) getSourceViewer()).getUndoManager().reset();
                }

                // Load syntax
                reloadSyntaxRules();
            } catch (CoreException e) {
                log.error(e);
            }
        }

        @Override
        protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document,
                boolean overwrite) throws CoreException {
            setSourceText(RuntimeUtils.makeMonitor(monitor), document.get());
        }
    }

    @Override
    public DBCCompileLog getCompileLog() {
        return compileLog;
    }

    @Override
    public void setCompileInfo(String message, boolean error) {
        pageControl.setInfo(message);
    }

    @Override
    public void positionSource(int line, int position) {
        try {
            final IRegion lineInfo = getTextViewer().getDocument().getLineInformation(line - 1);
            final int offset = lineInfo.getOffset() + position - 1;
            super.selectAndReveal(offset, 0);
            //textEditor.setFocus();
        } catch (BadLocationException e) {
            log.warn(e);
            // do nothing
        }
    }

    @Override
    public void showCompileLog() {
        editorSash.setMaximizedControl(null);
        compileLog.layoutLog();
    }

    protected abstract String getSourceText(DBRProgressMonitor monitor) throws DBException;

    protected abstract void setSourceText(DBRProgressMonitor monitor, String sourceText);

    protected void contributeEditorCommands(IContributionManager toolBarManager) {
        toolBarManager.add(
                ActionUtils.makeCommandContribution(getSite().getWorkbenchWindow(), CoreCommands.CMD_OPEN_FILE));
        toolBarManager.add(
                ActionUtils.makeCommandContribution(getSite().getWorkbenchWindow(), CoreCommands.CMD_SAVE_FILE));
        String compileCommandId = getCompileCommandId();
        if (compileCommandId != null) {
            toolBarManager.add(new Separator());
            toolBarManager
                    .add(ActionUtils.makeCommandContribution(getSite().getWorkbenchWindow(), compileCommandId));
            toolBarManager.add(new ViewLogAction());
        }
    }

    private class EditorPageControl extends ProgressPageControl {

        public EditorPageControl(Composite parent, int style) {
            super(parent, style);
        }

        @Override
        protected void fillCustomActions(IContributionManager contributionManager) {
            contributeEditorCommands(contributionManager);
        }
    }

    public class ViewLogAction extends Action {
        public ViewLogAction() {
            super("View compile log", DBeaverIcons.getImageDescriptor(UIIcon.COMPILE_LOG)); //$NON-NLS-2$
        }

        @Override
        public void run() {
            if (getTextViewer().getControl().isDisposed()) {
                return;
            }
            if (editorSash.getMaximizedControl() == null) {
                editorSash.setMaximizedControl(editorControl);
            } else {
                showCompileLog();
            }
        }

    }

}