diff --git a/plugins/org.jkiss.dbeaver.data.console/META-INF/MANIFEST.MF b/plugins/org.jkiss.dbeaver.data.console/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..3fff669c00433b5a3bb360977296e7d5dd745cbf
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.data.console/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.jkiss.dbeaver.data.console;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Release-Date: 20200106
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui.console,
+ org.jkiss.dbeaver.ui,
+ org.jkiss.dbeaver.core
+Export-Package: org.jkiss.dbeaver.data.console
+Automatic-Module-Name: org.jkiss.dbeaver.data.console
diff --git a/plugins/org.jkiss.dbeaver.data.console/OSGI-INF/l10n/bundle.properties b/plugins/org.jkiss.dbeaver.data.console/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c1c58d8f47dd7ca01872f4d3b833017c45997b69
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.data.console/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,22 @@
+#Properties file for org.jkiss.dbeaver.debug.ui
+
+# DBeaver - Universal Database Manager
+# Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Bundle-Vendor = JKISS
+Bundle-Name = DBeaver SQL Script Output Console
+
+presentation.scriptconsole.label = Console
+presentation.scriptconsole.description = SQL Script Output Console
diff --git a/plugins/org.jkiss.dbeaver.data.console/build.properties b/plugins/org.jkiss.dbeaver.data.console/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..69167ad5f9df03fed42d4ecd5391a4a46fd8b63b
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.data.console/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/,\
+ plugin.xml
diff --git a/plugins/org.jkiss.dbeaver.data.console/plugin.xml b/plugins/org.jkiss.dbeaver.data.console/plugin.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5d2c38aa0001cd132055dea5c0a50a44da5c3e8b
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.data.console/plugin.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/org.jkiss.dbeaver.data.console/pom.xml b/plugins/org.jkiss.dbeaver.data.console/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7de00afd9258cd61366544bd7a2d18d927551eb1
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.data.console/pom.xml
@@ -0,0 +1,14 @@
+
+
+ 4.0.0
+
+ org.jkiss.dbeaver
+ plugins
+ 1.0.0-SNAPSHOT
+ ../
+
+ org.jkiss.dbeaver.data.console
+ 1.0.0-SNAPSHOT
+ eclipse-plugin
+
diff --git a/plugins/org.jkiss.dbeaver.data.console/src/org/jkiss/dbeaver/data/console/ConsoleTextPresentation.java b/plugins/org.jkiss.dbeaver.data.console/src/org/jkiss/dbeaver/data/console/ConsoleTextPresentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..58827abc332cde55dc7857db319e1191f5e250bb
--- /dev/null
+++ b/plugins/org.jkiss.dbeaver.data.console/src/org/jkiss/dbeaver/data/console/ConsoleTextPresentation.java
@@ -0,0 +1,758 @@
+/*
+ * DBeaver - Universal Database Manager
+ * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jkiss.dbeaver.data.console;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.IFindReplaceTarget;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.StyledTextPrintOptions;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.printing.PrintDialog;
+import org.eclipse.swt.printing.Printer;
+import org.eclipse.swt.printing.PrinterData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.themes.ITheme;
+import org.eclipse.ui.themes.IThemeManager;
+import org.jkiss.code.NotNull;
+import org.jkiss.code.Nullable;
+import org.jkiss.dbeaver.model.DBConstants;
+import org.jkiss.dbeaver.model.DBPDataKind;
+import org.jkiss.dbeaver.model.DBUtils;
+import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
+import org.jkiss.dbeaver.model.data.DBDDisplayFormat;
+import org.jkiss.dbeaver.model.impl.data.DBDValueError;
+import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
+import org.jkiss.dbeaver.ui.UIStyles;
+import org.jkiss.dbeaver.ui.UIUtils;
+import org.jkiss.dbeaver.ui.controls.StyledTextFindReplaceTarget;
+import org.jkiss.dbeaver.ui.controls.resultset.AbstractPresentation;
+import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
+import org.jkiss.dbeaver.ui.controls.resultset.IResultSetSelection;
+import org.jkiss.dbeaver.ui.controls.resultset.ResultSetCopySettings;
+import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
+import org.jkiss.dbeaver.ui.controls.resultset.ResultSetPreferences;
+import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
+import org.jkiss.dbeaver.ui.controls.resultset.ThemeConstants;
+import org.jkiss.dbeaver.ui.editors.TextEditorUtils;
+import org.jkiss.utils.CommonUtils;
+
+/**
+ * Empty presentation.
+ * Used when RSV has no results (initially).
+ */
+public class ConsoleTextPresentation extends AbstractPresentation implements IAdaptable {
+
+ public static final int FIRST_ROW_LINE = 2;
+
+ private StyledText text;
+ private DBDAttributeBinding curAttribute;
+ private StyledTextFindReplaceTarget findReplaceTarget;
+ public boolean activated;
+ private Color curLineColor;
+
+ private int[] colWidths;
+ private StyleRange curLineRange;
+ private int totalRows = 0;
+ private String curSelection;
+ private Font monoFont;
+ private boolean showNulls;
+ private boolean rightJustifyNumbers;
+ private boolean rightJustifyDateTime;
+
+ @Override
+ public void createPresentation(@NotNull final IResultSetController controller, @NotNull Composite parent) {
+ super.createPresentation(controller, parent);
+
+ UIUtils.createHorizontalLine(parent);
+ text = new StyledText(parent, SWT.READ_ONLY | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ text.setBlockSelection(true);
+ text.setCursor(parent.getDisplay().getSystemCursor(SWT.CURSOR_IBEAM));
+ text.setMargins(4, 4, 4, 4);
+ text.setForeground(UIStyles.getDefaultTextForeground());
+ text.setBackground(UIStyles.getDefaultTextBackground());
+ text.setTabs(controller.getPreferenceStore().getInt(ResultSetPreferences.RESULT_TEXT_TAB_SIZE));
+ text.setTabStops(null);
+ text.setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));
+ text.setLayoutData(new GridData(GridData.FILL_BOTH));
+ text.addCaretListener(event -> onCursorChange(event.caretOffset));
+ text.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ curSelection = text.getSelectionText();
+ fireSelectionChanged(new PlainTextSelectionImpl());
+ }
+ });
+
+ final ScrollBar verticalBar = text.getVerticalBar();
+ verticalBar.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (verticalBar.getSelection() + verticalBar.getPageIncrement() >= verticalBar.getMaximum()) {
+ if (controller.getPreferenceStore().getBoolean(ResultSetPreferences.RESULT_SET_AUTO_FETCH_NEXT_SEGMENT) &&
+ !controller.isRecordMode() &&
+ controller.isHasMoreData()) {
+ controller.readNextSegment();
+ }
+ }
+ }
+ });
+ findReplaceTarget = new StyledTextFindReplaceTarget(text);
+ TextEditorUtils.enableHostEditorKeyBindingsSupport(controller.getSite(), text);
+
+ applyThemeSettings();
+
+ registerContextMenu();
+ activateTextKeyBindings(controller, text);
+ trackPresentationControl();
+ }
+
+ @Override
+ public void dispose() {
+ if (monoFont != null) {
+ UIUtils.dispose(monoFont);
+ monoFont = null;
+ }
+ super.dispose();
+ }
+
+ @Override
+ protected void applyThemeSettings() {
+ IThemeManager themeManager = controller.getSite().getWorkbenchWindow().getWorkbench().getThemeManager();
+ curLineColor = themeManager.getCurrentTheme().getColorRegistry().get(ThemeConstants.COLOR_SQL_RESULT_CELL_ODD_BACK);
+
+ ITheme currentTheme = themeManager.getCurrentTheme();
+ Font rsFont = currentTheme.getFontRegistry().get(ThemeConstants.FONT_SQL_RESULT_SET);
+ if (rsFont != null) {
+ int fontHeight = rsFont.getFontData()[0].getHeight();
+ Font font = JFaceResources.getFont(JFaceResources.TEXT_FONT);
+
+ FontData[] fontData = font.getFontData();
+ fontData[0].setHeight(fontHeight);
+ Font newFont = new Font(font.getDevice(), fontData[0]);
+
+ this.text.setFont(newFont);
+
+ if (monoFont != null) {
+ UIUtils.dispose(monoFont);
+ }
+ monoFont = newFont;
+
+ }
+ }
+
+ private void onCursorChange(int offset) {
+ ResultSetModel model = controller.getModel();
+
+ int lineNum = text.getLineAtOffset(offset);
+ int lineOffset = text.getOffsetAtLine(lineNum);
+ int horizontalOffset = offset - lineOffset;
+
+ int lineCount = text.getLineCount();
+
+ boolean delimLeading = getController().getPreferenceStore().getBoolean(ResultSetPreferences.RESULT_TEXT_DELIMITER_LEADING);
+
+ int rowNum = lineNum - FIRST_ROW_LINE; //First 2 lines is header
+ if (controller.isRecordMode()) {
+ if (rowNum < 0) {
+ rowNum = 0;
+ }
+ if (rowNum >= 0 && rowNum < model.getVisibleAttributeCount()) {
+ curAttribute = model.getVisibleAttribute(rowNum);
+ }
+ } else {
+ int colNum = 0;
+ int horOffsetBegin = 0, horOffsetEnd = 0;
+ if (delimLeading) horOffsetEnd++;
+ for (int i = 0; i < colWidths.length; i++) {
+ horOffsetBegin = horOffsetEnd;
+ horOffsetEnd += colWidths[i] + 1;
+ if (horizontalOffset < horOffsetEnd) {
+ colNum = i;
+ break;
+ }
+ }
+ if (rowNum < 0 && model.getRowCount() > 0) {
+ rowNum = 0;
+ }
+ if (rowNum >= 0 && rowNum < model.getRowCount() && colNum >= 0 && colNum < model.getVisibleAttributeCount()) {
+ controller.setCurrentRow(model.getRow(rowNum));
+ curAttribute = model.getVisibleAttribute(colNum);
+ }
+ controller.updateEditControls();
+
+ {
+ // Highlight row
+ if (curLineRange == null || curLineRange.start != lineOffset + horOffsetBegin) {
+ curLineRange = new StyleRange(
+ lineOffset + horOffsetBegin,
+ horOffsetEnd - horOffsetBegin - 1,
+ null,
+ curLineColor);
+ UIUtils.asyncExec(() -> {
+ text.setStyleRanges(new StyleRange[]{curLineRange});
+ text.redraw();
+ });
+ }
+ }
+
+ if (lineNum == lineCount - 1 &&
+ controller.isHasMoreData() &&
+ controller.getPreferenceStore().getBoolean(ResultSetPreferences.RESULT_SET_AUTO_FETCH_NEXT_SEGMENT)) {
+ controller.readNextSegment();
+ }
+ }
+ fireSelectionChanged(new PlainTextSelectionImpl());
+ }
+
+ @Override
+ public Control getControl() {
+ return text;
+ }
+
+ @Override
+ public void refreshData(boolean refreshMetadata, boolean append, boolean keepState) {
+ colWidths = null;
+
+ DBPPreferenceStore prefs = getController().getPreferenceStore();
+ rightJustifyNumbers = prefs.getBoolean(ResultSetPreferences.RESULT_SET_RIGHT_JUSTIFY_NUMBERS);
+ rightJustifyDateTime = prefs.getBoolean(ResultSetPreferences.RESULT_SET_RIGHT_JUSTIFY_DATETIME);
+
+ if (controller.isRecordMode()) {
+ printRecord();
+ } else {
+ printGrid();
+ }
+ }
+
+ private void printGrid() {
+ DBPPreferenceStore prefs = getController().getPreferenceStore();
+ int maxColumnSize = prefs.getInt(ResultSetPreferences.RESULT_TEXT_MAX_COLUMN_SIZE);
+ boolean delimLeading = prefs.getBoolean(ResultSetPreferences.RESULT_TEXT_DELIMITER_LEADING);
+ boolean delimTrailing = prefs.getBoolean(ResultSetPreferences.RESULT_TEXT_DELIMITER_TRAILING);
+ boolean extraSpaces = prefs.getBoolean(ResultSetPreferences.RESULT_TEXT_EXTRA_SPACES);
+ this.showNulls = getController().getPreferenceStore().getBoolean(ResultSetPreferences.RESULT_TEXT_SHOW_NULLS);
+
+ DBDDisplayFormat displayFormat = DBDDisplayFormat.safeValueOf(prefs.getString(ResultSetPreferences.RESULT_TEXT_VALUE_FORMAT));
+
+ StringBuilder grid = new StringBuilder(512);
+ ResultSetModel model = controller.getModel();
+ List attrs = model.getVisibleAttributes();
+
+ grid.append("> "+controller.getDataContainer().getName()+"\n");
+
+ List allRows = model.getAllRows();
+ int extraSpacesNum = extraSpaces ? 2 : 0;
+ if (colWidths == null) {
+ // Calculate column widths
+ colWidths = new int[attrs.size()];
+
+ for (int i = 0; i < attrs.size(); i++) {
+ DBDAttributeBinding attr = attrs.get(i);
+ colWidths[i] = getAttributeName(attr).length() + extraSpacesNum;
+ if (showNulls && !attr.isRequired()) {
+ colWidths[i] = Math.max(colWidths[i], DBConstants.NULL_VALUE_LABEL.length());
+ }
+ for (ResultSetRow row : allRows) {
+ String displayString = getCellString(model, attr, row, displayFormat);
+ colWidths[i] = Math.max(colWidths[i], getStringWidth(displayString) + extraSpacesNum);
+ }
+ }
+ for (int i = 0; i < colWidths.length; i++) {
+ if (colWidths[i] > maxColumnSize) {
+ colWidths[i] = maxColumnSize;
+ }
+ }
+ }
+
+ // Print header
+ if (delimLeading) grid.append("|");
+ for (int i = 0; i < attrs.size(); i++) {
+ if (i > 0) grid.append("|");
+ if (extraSpaces) grid.append(" ");
+ DBDAttributeBinding attr = attrs.get(i);
+ String attrName = getAttributeName(attr);
+ grid.append(attrName);
+ for (int k = colWidths[i] - attrName.length() - extraSpacesNum; k > 0; k--) {
+ grid.append(" ");
+ }
+ if (extraSpaces) grid.append(" ");
+ }
+ if (delimTrailing) grid.append("|");
+ grid.append("\n");
+
+ // Print divider
+ // Print header
+ if (delimLeading) grid.append("|");
+ for (int i = 0; i < attrs.size(); i++) {
+ if (i > 0) grid.append("|");
+ for (int k = colWidths[i]; k > 0; k--) {
+ grid.append("-");
+ }
+ }
+ if (delimTrailing) grid.append("|");
+ grid.append("\n");
+
+ // Print rows
+ int firstRow = totalRows;
+
+ boolean newLines = false;
+ for (int i = firstRow; i < allRows.size(); i++) {
+ newLines = true;
+ ResultSetRow row = allRows.get(i);
+ if (delimLeading) grid.append("|");
+ for (int k = 0; k < attrs.size(); k++) {
+ if (k > 0) grid.append("|");
+ DBDAttributeBinding attr = attrs.get(k);
+ String displayString = getCellString(model, attr, row, displayFormat);
+ if (displayString.length() >= colWidths[k]) {
+ displayString = CommonUtils.truncateString(displayString, colWidths[k]);
+ }
+
+ int stringWidth = getStringWidth(displayString);
+
+ if (extraSpaces) grid.append(" ");
+ DBPDataKind dataKind = attr.getDataKind();
+ if ((dataKind == DBPDataKind.NUMERIC && rightJustifyNumbers) ||
+ (dataKind == DBPDataKind.DATETIME && rightJustifyDateTime))
+ {
+ // Right justify value
+ for (int j = colWidths[k] - stringWidth - extraSpacesNum; j > 0; j--) {
+ grid.append(" ");
+ }
+ grid.append(displayString);
+ } else {
+ grid.append(displayString);
+ for (int j = colWidths[k] - stringWidth - extraSpacesNum; j > 0; j--) {
+ grid.append(" ");
+ }
+ }
+ if (extraSpaces) grid.append(" ");
+ }
+ if (delimTrailing) grid.append("|");
+ grid.append("\n");
+ }
+ grid.setLength(grid.length() - 1); // cut last line feed
+
+ totalRows = allRows.size();
+
+ grid.append("\n");
+
+ // Print divider
+ // Print header
+ if (delimLeading) grid.append("|");
+ for (int i = 0; i < attrs.size(); i++) {
+ if (i > 0) grid.append("|");
+ for (int k = colWidths[i]; k > 0; k--) {
+ grid.append("-");
+ }
+ }
+ if (delimTrailing) grid.append("|");
+ grid.append("\n\n");
+
+ if (newLines) {
+ text.append(grid.toString());
+ text.append(totalRows +" row(s) fetched.\n\n");
+ }
+ }
+
+ private int getStringWidth(String str) {
+ int width = 0;
+ if (str != null && str.length() > 0) {
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c == '\t') {
+ width += controller.getPreferenceStore().getInt(ResultSetPreferences.RESULT_TEXT_TAB_SIZE);
+ } else {
+ width++;
+ }
+ }
+ }
+ return width;
+ }
+
+ private static String getAttributeName(DBDAttributeBinding attr) {
+ if (CommonUtils.isEmpty(attr.getLabel())) {
+ return attr.getName();
+ } else {
+ return attr.getLabel();
+ }
+ }
+
+ StringBuilder fixBuffer = new StringBuilder();
+
+ private String getCellString(ResultSetModel model, DBDAttributeBinding attr, ResultSetRow row, DBDDisplayFormat displayFormat) {
+ Object cellValue = model.getCellValue(attr, row);
+ if (cellValue instanceof DBDValueError) {
+ return ((DBDValueError) cellValue).getErrorTitle();
+ }
+ String displayString = attr.getValueHandler().getValueDisplayString(attr, cellValue, displayFormat);
+
+ if (displayString.isEmpty() &&
+ showNulls &&
+ DBUtils.isNullValue(cellValue))
+ {
+ displayString = DBConstants.NULL_VALUE_LABEL;
+ }
+
+ fixBuffer.setLength(0);
+ for (int i = 0; i < displayString.length(); i++) {
+ char c = displayString.charAt(i);
+ switch (c) {
+ case '\n':
+ c = CommonUtils.PARAGRAPH_CHAR;
+ break;
+ case '\r':
+ continue;
+ case 0:
+ case 255:
+ case '\t':
+ c = ' ';
+ break;
+ }
+ if (c < ' '/* || (c > 127 && c < 255)*/) {
+ c = ' ';
+ }
+ fixBuffer.append(c);
+ }
+
+ return fixBuffer.toString();
+ }
+
+ private void printRecord() {
+ text.append("print record ...\n");
+ DBPPreferenceStore prefs = getController().getPreferenceStore();
+ boolean delimLeading = prefs.getBoolean(ResultSetPreferences.RESULT_TEXT_DELIMITER_LEADING);
+ boolean delimTrailing = prefs.getBoolean(ResultSetPreferences.RESULT_TEXT_DELIMITER_TRAILING);
+ DBDDisplayFormat displayFormat = DBDDisplayFormat.safeValueOf(prefs.getString(ResultSetPreferences.RESULT_TEXT_VALUE_FORMAT));
+
+ StringBuilder grid = new StringBuilder(512);
+ ResultSetModel model = controller.getModel();
+ List attrs = model.getVisibleAttributes();
+ String[] values = new String[attrs.size()];
+ ResultSetRow currentRow = controller.getCurrentRow();
+
+ // Calculate column widths
+ int nameWidth = 4, valueWidth = 5;
+ for (int i = 0; i < attrs.size(); i++) {
+ DBDAttributeBinding attr = attrs.get(i);
+ nameWidth = Math.max(nameWidth, getAttributeName(attr).length());
+ if (currentRow != null) {
+ String displayString = getCellString(model, attr, currentRow, displayFormat);
+ values[i] = displayString;
+ valueWidth = Math.max(valueWidth, values[i].length());
+ }
+ }
+
+ // Header
+ if (delimLeading) grid.append("|");
+ grid.append("Name");
+ for (int j = nameWidth - 4; j > 0; j--) {
+ grid.append(" ");
+ }
+ grid.append("|Value");
+ for (int j = valueWidth - 5; j > 0; j--) {
+ grid.append(" ");
+ }
+ if (delimTrailing) grid.append("|");
+ grid.append("\n");
+
+ if (delimLeading) grid.append("|");
+ for (int j = 0; j < nameWidth; j++) grid.append("-");
+ grid.append("|");
+ for (int j = 0; j < valueWidth; j++) grid.append("-");
+ if (delimTrailing) grid.append("|");
+ grid.append("\n");
+
+ if (currentRow != null) {
+ // Values
+ for (int i = 0; i < attrs.size(); i++) {
+ DBDAttributeBinding attr = attrs.get(i);
+ String name = getAttributeName(attr);
+ if (delimLeading) grid.append("|");
+ grid.append(name);
+ for (int j = nameWidth - name.length(); j > 0; j--) {
+ grid.append(" ");
+ }
+ grid.append("|");
+ grid.append(values[i]);
+ for (int j = valueWidth - values[i].length(); j > 0; j--) {
+ grid.append(" ");
+ }
+
+ if (delimTrailing) grid.append("|");
+ grid.append("\n");
+ }
+ }
+ grid.setLength(grid.length() - 1); // cut last line feed
+ text.append(grid.toString());
+// text.setText(grid.toString());
+ }
+
+ @Override
+ public void formatData(boolean refreshData) {
+ //controller.refreshData(null);
+ }
+
+ @Override
+ public void clearMetaData() {
+ colWidths = null;
+ curLineRange = null;
+ totalRows = 0;
+ }
+
+ @Override
+ public void updateValueView() {
+
+ }
+
+ @Override
+ public void fillMenu(@NotNull IMenuManager menu) {
+
+ }
+
+ @Override
+ public void changeMode(boolean recordMode) {
+
+ }
+
+ @Override
+ public void scrollToRow(@NotNull RowPosition position) {
+ if (controller.isRecordMode()) {
+ super.scrollToRow(position);
+ } else {
+ int caretOffset = text.getCaretOffset();
+ if (caretOffset < 0) caretOffset = 0;
+ int lineNum = text.getLineAtOffset(caretOffset);
+ if (lineNum < FIRST_ROW_LINE) {
+ lineNum = FIRST_ROW_LINE;
+ }
+ int lineOffset = text.getOffsetAtLine(lineNum);
+ int xOffset = caretOffset - lineOffset;
+ int totalLines = text.getLineCount();
+ switch (position) {
+ case FIRST:
+ lineNum = FIRST_ROW_LINE;
+ break;
+ case PREVIOUS:
+ lineNum--;
+ break;
+ case NEXT:
+ lineNum++;
+ break;
+ case LAST:
+ lineNum = totalLines - 1;
+ break;
+ case CURRENT:
+ lineNum = controller.getCurrentRow().getVisualNumber() + FIRST_ROW_LINE;
+ break;
+ }
+ if (lineNum < FIRST_ROW_LINE || lineNum >= totalLines) {
+ return;
+ }
+ int newOffset = text.getOffsetAtLine(lineNum);
+ newOffset += xOffset;
+ text.setCaretOffset(newOffset);
+ //text.setSelection(newOffset, 0);
+ text.showSelection();
+ }
+ }
+
+ @Nullable
+ @Override
+ public DBDAttributeBinding getCurrentAttribute() {
+ return curAttribute;
+ }
+
+ @Nullable
+ @Override
+ public String copySelectionToString(ResultSetCopySettings settings) {
+ return text.getSelectionText();
+ }
+
+ private static PrinterData fgPrinterData= null;
+
+ @Override
+ public void printResultSet() {
+ final Shell shell = getControl().getShell();
+ StyledTextPrintOptions options = new StyledTextPrintOptions();
+ options.printTextFontStyle = true;
+ options.printTextForeground = true;
+
+ if (Printer.getPrinterList().length == 0) {
+ UIUtils.showMessageBox(shell, "No printers", "Printers not found", SWT.ICON_ERROR);
+ return;
+ }
+
+ final PrintDialog dialog = new PrintDialog(shell, SWT.PRIMARY_MODAL);
+ dialog.setPrinterData(fgPrinterData);
+ final PrinterData data = dialog.open();
+
+ if (data != null) {
+ final Printer printer = new Printer(data);
+ final Runnable styledTextPrinter = text.print(printer, options);
+ new Thread("Printing") { //$NON-NLS-1$
+ public void run() {
+ styledTextPrinter.run();
+ printer.dispose();
+ }
+ }.start();
+
+ /*
+ * FIXME:
+ * Should copy the printer data to avoid threading issues,
+ * but this is currently not possible, see http://bugs.eclipse.org/297957
+ */
+ fgPrinterData = data;
+ fgPrinterData.startPage = 1;
+ fgPrinterData.endPage = 1;
+ fgPrinterData.scope = PrinterData.ALL_PAGES;
+ fgPrinterData.copyCount = 1;
+ }
+ }
+
+ @Override
+ protected void performHorizontalScroll(int scrollCount) {
+ ScrollBar hsb = text.getHorizontalBar();
+ if (hsb != null && hsb.isVisible()) {
+ int curPosition = text.getHorizontalPixel();
+ int pageIncrement = UIUtils.getFontHeight(text.getFont()) * 10;
+ if (scrollCount > 0) {
+ if (curPosition > 0) {
+ curPosition -= pageIncrement;
+ }
+ } else {
+ curPosition += pageIncrement;
+ }
+ if (curPosition < 0) curPosition = 0;
+ text.setHorizontalPixel(curPosition);
+ //text.setHorizontalIndex();
+ }
+ }
+
+ @Override
+ public T getAdapter(Class adapter) {
+ if (adapter == IFindReplaceTarget.class) {
+ return adapter.cast(findReplaceTarget);
+ }
+ return null;
+ }
+
+ @Override
+ public ISelection getSelection() {
+ return new PlainTextSelectionImpl();
+ }
+
+ private class PlainTextSelectionImpl implements IResultSetSelection {
+
+ @Nullable
+ @Override
+ public Object getFirstElement()
+ {
+ return curSelection;
+ }
+
+ @Override
+ public Iterator iterator()
+ {
+ return toList().iterator();
+ }
+
+ @Override
+ public int size()
+ {
+ return curSelection == null ? 0 : 1;
+ }
+
+ @Override
+ public Object[] toArray()
+ {
+ return curSelection == null ?
+ new Object[0] :
+ new Object[] { curSelection };
+ }
+
+ @Override
+ public List toList()
+ {
+ return curSelection == null ?
+ Collections.emptyList() :
+ Collections.singletonList(curSelection);
+ }
+
+ @Override
+ public boolean isEmpty()
+ {
+ return false;
+ }
+
+ @NotNull
+ @Override
+ public IResultSetController getController()
+ {
+ return controller;
+ }
+
+ @NotNull
+ @Override
+ public List getSelectedAttributes() {
+ if (curAttribute == null) {
+ return Collections.emptyList();
+ }
+ return Collections.singletonList(curAttribute);
+ }
+
+ @NotNull
+ @Override
+ public List getSelectedRows()
+ {
+ ResultSetRow currentRow = controller.getCurrentRow();
+ if (currentRow == null) {
+ return Collections.emptyList();
+ }
+ return Collections.singletonList(currentRow);
+ }
+
+ @Override
+ public DBDAttributeBinding getElementAttribute(Object element) {
+ return curAttribute;
+ }
+
+ @Override
+ public ResultSetRow getElementRow(Object element) {
+ return getController().getCurrentRow();
+ }
+ }
+
+}
diff --git a/plugins/pom.xml b/plugins/pom.xml
index d146692abbc66235d592be733c7fb146528df1c9..6ee64d9149631a14f9679420c8dc5dae49ee1306 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -96,7 +96,7 @@
org.jkiss.dbeaver.ext.sample.database
org.jkiss.dbeaver.ext.ui.locks
org.jkiss.dbeaver.ext.ui.svg
- org.jkiss.dbeaver.ext.ui.colortheme
+ org.jkiss.dbeaver.ext.ui.colortheme
org.jkiss.dbeaver.ext.ui.tipoftheday
org.jkiss.dbeaver.tasks.native
@@ -112,8 +112,8 @@
org.jkiss.dbeaver.net.ssh.jsch
org.jkiss.dbeaver.net.ssh.sshj
org.jkiss.dbeaver.net.ssh.ui
-
org.jkiss.dbeaver.slf4j
+ org.jkiss.dbeaver.data.console