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