提交 fa488d7e 编写于 作者: S serge-rider

#10 XML editor plugin, data managers model refactoring

上级 fc86ff49
......@@ -54,6 +54,7 @@
<plugin id="org.jkiss.dbeaver.ui.editors.hex" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.jkiss.dbeaver.ui.editors.image" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.jkiss.dbeaver.ui.editors.sql" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.jkiss.dbeaver.ui.editors.xml" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.jkiss.dbeaver.ui.navigator" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.jkiss.dbeaver.ext.erd" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
<plugin id="org.jkiss.dbeaver.ext.ui.colortheme" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
......
......@@ -36,15 +36,12 @@ Export-Package: org.jkiss.dbeaver,
org.jkiss.dbeaver.ui.data.dialogs,
org.jkiss.dbeaver.ui.data.editors,
org.jkiss.dbeaver.ui.data.managers,
org.jkiss.dbeaver.ui.data.managers.stream,
org.jkiss.dbeaver.ui.data.registry,
org.jkiss.dbeaver.ui.dialogs,
org.jkiss.dbeaver.ui.dialogs.connection,
org.jkiss.dbeaver.ui.dialogs.driver,
org.jkiss.dbeaver.ui.dialogs.net,
org.jkiss.dbeaver.ui.dialogs.tools,
org.jkiss.dbeaver.ui.e4,
org.jkiss.dbeaver.ui.editors.content,
org.jkiss.dbeaver.ui.editors.data,
org.jkiss.dbeaver.ui.editors.sql,
org.jkiss.dbeaver.ui.editors.sql.convert,
......@@ -61,7 +58,6 @@ Export-Package: org.jkiss.dbeaver,
org.jkiss.dbeaver.ui.editors.sql.syntax.tokens,
org.jkiss.dbeaver.ui.editors.sql.templates,
org.jkiss.dbeaver.ui.editors.sql.util,
org.jkiss.dbeaver.ui.editors.xml,
org.jkiss.dbeaver.ui.perspective,
org.jkiss.dbeaver.ui.preferences,
org.jkiss.dbeaver.ui.resources,
......
......@@ -388,9 +388,6 @@ meta.org.jkiss.dbeaver.registry.DriverDescriptor.name.name=Driver Name
meta.org.jkiss.dbeaver.registry.DriverDescriptor.description.name=Description
meta.org.jkiss.dbeaver.registry.DriverDescriptor.driverClassName.name=Driver Class
meta.org.jkiss.dbeaver.registry.DriverDescriptor.sampleURL.name=URL
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.type.name=Type
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.name.name=Name
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.columns.name=Columns
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.name.name=Name
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.foundRows.name=Rows Found (>=)
......
......@@ -468,9 +468,6 @@ meta.org.jkiss.dbeaver.registry.DriverDescriptor.description.name =
meta.org.jkiss.dbeaver.registry.DriverDescriptor.driverClassName.name = Treiberklasse
meta.org.jkiss.dbeaver.registry.DriverDescriptor.name.name = Treibername
meta.org.jkiss.dbeaver.registry.DriverDescriptor.sampleURL.name = URL
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.columns.name = Spalten
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.name.name = Name
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.type.name = Typ
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.foundRows.name = Gefundene Zeilen (>=)
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.name.name = Name
......
......@@ -353,9 +353,6 @@ meta.org.jkiss.dbeaver.registry.DriverDescriptor.description.name
meta.org.jkiss.dbeaver.registry.DriverDescriptor.driverClassName.name = Classe de pilote
meta.org.jkiss.dbeaver.registry.DriverDescriptor.name.name = Nom du pilote
meta.org.jkiss.dbeaver.registry.DriverDescriptor.sampleURL.name = URL
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.columns.name = Colonnes
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.name.name = Nom
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.type.name = Type
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.foundRows.name = Lignes trouv\u00E9es (>=)
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.name.name = Nom
......
......@@ -367,9 +367,6 @@ meta.org.jkiss.dbeaver.registry.DriverDescriptor.name.name=\u30C9\u30E9\u30A4\u3
meta.org.jkiss.dbeaver.registry.DriverDescriptor.description.name=\u8AAC\u660E
meta.org.jkiss.dbeaver.registry.DriverDescriptor.driverClassName.name=\u30C9\u30E9\u30A4\u30D0\u30FC\u30AF\u30E9\u30B9
meta.org.jkiss.dbeaver.registry.DriverDescriptor.sampleURL.name=URL
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.type.name=\u30BF\u30A4\u30D7
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.name.name=\u540D
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.columns.name=\u5217
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.name.name=\u540D
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.foundRows.name=\u898B\u3064\u304B\u3063\u305F\u884C\uFF08>\uFF09
......
......@@ -279,9 +279,6 @@ meta.org.jkiss.dbeaver.registry.DriverDescriptor.description.name =
meta.org.jkiss.dbeaver.registry.DriverDescriptor.driverClassName.name = \u041A\u043B\u0430\u0441\u0441 \u0414\u0440\u0430\u0439\u0432\u0435\u0440\u0430
meta.org.jkiss.dbeaver.registry.DriverDescriptor.name.name = \u0418\u043C\u044F \u0414\u0440\u0430\u0439\u0432\u0435\u0440\u0430
meta.org.jkiss.dbeaver.registry.DriverDescriptor.sampleURL.name = URL
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.columns.name = \u041A\u043E\u043B\u043E\u043D\u043A\u0438
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.name.name = \u0418\u043C\u044F
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.type.name = \u0422\u0438\u043F
search.page.label.db.fulltext = \u041F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0439 \u043F\u043E\u0438\u0441\u043A \u0411\u0414
search.page.label.db.metadata = \u041F\u043E\u0438\u0441\u043A \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 \u0411\u0414
......
......@@ -467,9 +467,6 @@ meta.org.jkiss.dbeaver.registry.DriverDescriptor.description.name =
meta.org.jkiss.dbeaver.registry.DriverDescriptor.driverClassName.name = \u9A71\u52A8\u7C7B
meta.org.jkiss.dbeaver.registry.DriverDescriptor.name.name = \u9A71\u52A8\u540D\u79F0
meta.org.jkiss.dbeaver.registry.DriverDescriptor.sampleURL.name = URL
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.columns.name = \u5B57\u6BB5
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.name.name = \u540D\u79F0
meta.org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel$CellKeyInfo.type.name = \u7C7B\u578B
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.foundRows.name = \u627E\u5230\u7684\u884C(>=)
meta.org.jkiss.dbeaver.ui.search.data.SearchDataObject.name.name = \u540D\u79F0
......
......@@ -3626,10 +3626,9 @@
<supports kind="ROWID"/>
</manager>
-->
<streamManager class="org.jkiss.dbeaver.ui.data.managers.stream.TextStreamValueManager" id="plaintext" label="Text" primaryMime="text/plain"
description="Plain text" icon="platform:/plugin/org.jkiss.dbeaver.model/icons/types/text.png"/>
<streamManager class="org.jkiss.dbeaver.ui.data.managers.stream.XMLStreamValueManager" id="xml" label="XML" primaryMime="text/xml"
description="XML" icon="platform:/plugin/org.jkiss.dbeaver.model/icons/types/xml.png"/>
<manager class="org.jkiss.dbeaver.ui.data.managers.DefaultValueManager" id="DefaultValueManager">
</manager>
</extension>
<extension point="org.jkiss.dbeaver.resourceHandler">
......
......@@ -149,7 +149,6 @@ public class CoreMessages extends NLS {
public static String controls_client_homes_panel_label_path;
public static String controls_client_homes_panel_label_product_name;
public static String controls_client_homes_panel_label_product_version;
public static String controls_column_info_panel_property_key;
public static String controls_driver_tree_column_connections;
public static String controls_driver_tree_column_name;
public static String controls_itemlist_action_copy;
......
......@@ -124,7 +124,6 @@ controls_client_homes_panel_label_name = Name
controls_client_homes_panel_label_path = Path
controls_client_homes_panel_label_product_name = Product Name
controls_client_homes_panel_label_product_version = Product Version
controls_column_info_panel_property_key = Key
controls_connection_properties_action_add_property = Add new property
controls_connection_properties_action_remove_property = Remove property
controls_connection_properties_category_user_properties = User Properties
......
......@@ -204,8 +204,6 @@ controls_client_homes_panel_label_product_name = Produktname
controls_client_homes_panel_label_product_version = Produktversion
controls_column_info_panel_property_key = Schl\u00FCssel
controls_connection_properties_action_add_property = Neue Eigenschaft hinzuf\u00FCgen
controls_connection_properties_action_remove_property = Eigenschaft entfernen
......
......@@ -153,8 +153,6 @@ controls_client_homes_panel_label_product_name = Nom du produit
controls_client_homes_panel_label_product_version = Version du produit
controls_column_info_panel_property_key = Clef
controls_connection_properties_action_add_property = Ajouter une nouvelle propri\u00E9t\u00E9
controls_connection_properties_action_remove_property = Supprimer la propri\u00E9t\u00E9
......
......@@ -116,7 +116,6 @@ controls_client_homes_panel_label_name =\u540D
controls_client_homes_panel_label_path =\u30D1\u30B9
controls_client_homes_panel_label_product_name =\u5546\u54C1\u540D
controls_client_homes_panel_label_product_version =\u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3
controls_column_info_panel_property_key =\u30AD\u30FC
controls_connection_properties_action_add_property =\u65B0\u3057\u3044\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8FFD\u52A0\u3059\u308B
controls_connection_properties_action_remove_property =\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u524A\u9664
controls_connection_properties_category_user_properties =\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30D1\u30C6\u30A3
......
......@@ -1015,7 +1015,6 @@ controls_client_homes_panel_button_remove_home=\u0423\u0434\u0430\u043B\u0438\u0
controls_client_homes_panel_confirm_remove_home_text=\u0412\u044B \u0443\u0432\u0435\u0440\u0435\u043D\u044B, \u0447\u0442\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043A\u043B\u0438\u0435\u043D\u0442\u0430 "{0}"?
controls_client_homes_panel_confirm_remove_home_title=\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043A\u043B\u0438\u0435\u043D\u0442\u0430
controls_client_homes_panel_dialog_title=\u041A\u043B\u0438\u0435\u043D\u0442\u044B \u0411\u0414
controls_column_info_panel_property_key=\u041A\u043B\u044E\u0447
controls_driver_tree_column_connections=\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F
controls_driver_tree_column_name=\u0418\u043C\u044F
controls_rs_pump_job_name=\u0427\u0442\u0435\u043D\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0445
......
......@@ -204,8 +204,6 @@ controls_client_homes_panel_label_product_name = \u4EA7\u54C1\u540D\u79F0
controls_client_homes_panel_label_product_version = \u4EA7\u54C1\u7248\u672C
controls_column_info_panel_property_key = \u952E
controls_connection_properties_action_add_property = \u6DFB\u52A0\u65B0\u5C5E\u6027
controls_connection_properties_action_remove_property = \u5220\u9664\u5C5E\u6027
......
......@@ -44,7 +44,7 @@ import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.data.*;
import org.jkiss.dbeaver.ui.data.managers.BaseValueManager;
import org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel;
import org.jkiss.dbeaver.ui.controls.ColumnInfoPanel;
import org.jkiss.utils.CommonUtils;
/**
......
......@@ -12,11 +12,21 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.core.expressions,
org.eclipse.ui,
org.eclipse.jface.text,
org.eclipse.ui.editors,
org.eclipse.ui.ide,
org.eclipse.ui.workbench.texteditor,
org.jkiss.dbeaver.model,
org.jkiss.dbeaver.ui,
org.jkiss.dbeaver.ui.editors.base,
org.jkiss.dbeaver.ui.navigator
Bundle-ClassPath: .
Export-Package: org.jkiss.dbeaver.ui.controls.lightgrid,
Export-Package: org.jkiss.dbeaver.ui.controls,
org.jkiss.dbeaver.ui.controls.lightgrid,
org.jkiss.dbeaver.ui.data,
org.jkiss.dbeaver.ui.data.managers,
org.jkiss.dbeaver.ui.data.managers.stream,
org.jkiss.dbeaver.ui.data.registry,
org.jkiss.dbeaver.ui.editors.content,
org.jkiss.dbeaver.ui.editors.data
Bundle-Vendor = DBeaver Corp
Bundle-Name = DBeaver UI Editors - Data
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.type.name=Type
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.name.name=Name
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.columns.name=Columns
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.columns.name = Spalten
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.name.name = Name
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.type.name = Typ
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.columns.name = Colonnes
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.name.name = Nom
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.type.name = Type
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.type.name=\u30BF\u30A4\u30D7
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.name.name=\u540D
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.columns.name=\u5217
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.columns.name = \u041A\u043E\u043B\u043E\u043D\u043A\u0438
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.name.name = \u0418\u043C\u044F
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.type.name = \u0422\u0438\u043F
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.columns.name = \u5B57\u6BB5
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.name.name = \u540D\u79F0
meta.org.jkiss.dbeaver.ui.controls.ColumnInfoPanel$CellKeyInfo.type.name = \u7C7B\u578B
......@@ -3,5 +3,10 @@
<plugin>
<extension point="org.jkiss.dbeaver.dataManager">
<streamManager class="org.jkiss.dbeaver.ui.data.managers.stream.TextStreamValueManager" id="plaintext" label="Text" primaryMime="text/plain"
description="Plain text" icon="platform:/plugin/org.jkiss.dbeaver.model/icons/types/text.png"/>
</extension>
</plugin>
......@@ -15,14 +15,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.dialogs;
package org.jkiss.dbeaver.ui.controls;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.core.CoreMessages;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.DBPNamedObject;
import org.jkiss.dbeaver.model.DBPObject;
......@@ -34,6 +33,7 @@ import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
import org.jkiss.dbeaver.ui.data.IAttributeController;
import org.jkiss.dbeaver.ui.data.IRowController;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.editors.data.internal.DataEditorsMessages;
import org.jkiss.dbeaver.ui.properties.PropertyTreeViewer;
import java.util.ArrayList;
......@@ -63,7 +63,7 @@ public class ColumnInfoPanel extends Composite {
infoItem.addProperty(
null,
"Key",
CoreMessages.controls_column_info_panel_property_key,
DataEditorsMessages.controls_column_info_panel_property_key,
new CellKeyInfo(valueController.getRowController(), rowIdentifier)
);
}
......
......@@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.data.managers.stream;
package org.jkiss.dbeaver.ui.data.managers;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.source.ISourceViewer;
......@@ -31,19 +32,18 @@ import org.eclipse.ui.PartInitException;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBPDataKind;
import org.jkiss.dbeaver.model.DBPMessageType;
import org.jkiss.dbeaver.model.data.DBDContent;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.impl.StringContentStorage;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.controls.resultset.panel.valueviewer.ValueViewerPanel;
import org.jkiss.dbeaver.ui.data.IStreamValueEditor;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.editors.StringEditorInput;
import org.jkiss.dbeaver.ui.editors.SubEditorSite;
import org.jkiss.dbeaver.ui.editors.content.ContentEditorInput;
import org.jkiss.dbeaver.ui.editors.data.internal.DataEditorsActivator;
import org.jkiss.dbeaver.ui.editors.text.BaseTextEditor;
import org.jkiss.dbeaver.utils.RuntimeUtils;
......@@ -97,7 +97,7 @@ public abstract class AbstractTextPanelEditor<EDITOR extends BaseTextEditor> imp
boolean newWW = !editorControl.getWordWrap();
setChecked(newWW);
editorControl.setWordWrap(newWW);
ValueViewerPanel.getPanelSettings().put(PREF_TEXT_EDITOR_WORD_WRAP, newWW);
getPanelSettings().put(PREF_TEXT_EDITOR_WORD_WRAP, newWW);
}
};
wwAction.setChecked(editorControl.getWordWrap());
......@@ -109,13 +109,13 @@ public abstract class AbstractTextPanelEditor<EDITOR extends BaseTextEditor> imp
final Action afAction = new Action("Auto Format", Action.AS_CHECK_BOX) {
@Override
public void run() {
boolean newAF = !ValueViewerPanel.getPanelSettings().getBoolean(PREF_TEXT_EDITOR_AUTO_FORMAT);
boolean newAF = !getPanelSettings().getBoolean(PREF_TEXT_EDITOR_AUTO_FORMAT);
setChecked(newAF);
ValueViewerPanel.getPanelSettings().put(PREF_TEXT_EDITOR_AUTO_FORMAT, newAF);
getPanelSettings().put(PREF_TEXT_EDITOR_AUTO_FORMAT, newAF);
applyEditorStyle();
}
};
afAction.setChecked(ValueViewerPanel.getPanelSettings().getBoolean(PREF_TEXT_EDITOR_AUTO_FORMAT));
afAction.setChecked(getPanelSettings().getBoolean(PREF_TEXT_EDITOR_AUTO_FORMAT));
manager.add(afAction);
}
}
......@@ -125,7 +125,7 @@ public abstract class AbstractTextPanelEditor<EDITOR extends BaseTextEditor> imp
}
private void initEditorSettings(StyledText control) {
boolean wwEnabled = ValueViewerPanel.getPanelSettings().getBoolean(PREF_TEXT_EDITOR_WORD_WRAP);
boolean wwEnabled = getPanelSettings().getBoolean(PREF_TEXT_EDITOR_WORD_WRAP);
if (wwEnabled != control.getWordWrap()) {
control.setWordWrap(wwEnabled);
}
......@@ -133,7 +133,7 @@ public abstract class AbstractTextPanelEditor<EDITOR extends BaseTextEditor> imp
private void applyEditorStyle() {
BaseTextEditor textEditor = getTextEditor();
if (textEditor != null && ValueViewerPanel.getPanelSettings().getBoolean(PREF_TEXT_EDITOR_AUTO_FORMAT)) {
if (textEditor != null && getPanelSettings().getBoolean(PREF_TEXT_EDITOR_AUTO_FORMAT)) {
try {
if (textEditor.getViewer().canDoOperation(ISourceViewer.FORMAT)) {
textEditor.getViewer().doOperation(ISourceViewer.FORMAT);
......@@ -205,4 +205,15 @@ public abstract class AbstractTextPanelEditor<EDITOR extends BaseTextEditor> imp
}
}
private static IDialogSettings viewerSettings;
public static IDialogSettings getPanelSettings() {
if (viewerSettings == null) {
viewerSettings = UIUtils.getSettingsSection(
DataEditorsActivator.getDefault().getDialogSettings(),
AbstractTextPanelEditor.class.getSimpleName());
}
return viewerSettings;
}
}
......@@ -27,7 +27,6 @@ import org.jkiss.dbeaver.model.DBIcon;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.editors.text.BaseTextEditor;
import org.jkiss.dbeaver.ui.editors.text.FileRefDocumentProvider;
import org.jkiss.dbeaver.ui.editors.xml.XMLSourceViewerConfiguration;
/**
* CONTENT text editor
......
......@@ -17,7 +17,7 @@
package org.jkiss.dbeaver.ui.data.managers.stream;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.editors.text.BaseTextEditor;
import org.jkiss.dbeaver.ui.data.managers.AbstractTextPanelEditor;
/**
* TextPanelEditor
......
......@@ -20,7 +20,6 @@ import org.eclipse.core.runtime.IConfigurationElement;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.DBPImage;
import org.jkiss.dbeaver.model.impl.AbstractDescriptor;
import org.jkiss.dbeaver.registry.RegistryConstants;
import org.jkiss.dbeaver.ui.data.IStreamValueManager;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
......@@ -48,11 +47,11 @@ public class StreamValueManagerDescriptor extends AbstractDescriptor
{
super(config);
this.id = config.getAttribute(RegistryConstants.ATTR_ID);
this.implType = new ObjectType(config.getAttribute(RegistryConstants.ATTR_CLASS));
this.label = config.getAttribute(RegistryConstants.ATTR_LABEL);
this.description = config.getAttribute(RegistryConstants.ATTR_DESCRIPTION);
this.icon = iconToImage(config.getAttribute(RegistryConstants.ATTR_ICON));
this.id = config.getAttribute("id");
this.implType = new ObjectType(config.getAttribute("class"));
this.label = config.getAttribute("label");
this.description = config.getAttribute("description");
this.icon = iconToImage(config.getAttribute("icon"));
this.primaryMime = config.getAttribute(ATTR_PRIMARY_MIME);
String supportedMimeString = config.getAttribute(ATTR_SUPPORTED_MIME);
......
......@@ -22,12 +22,11 @@ import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBPDataKind;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.impl.AbstractDescriptor;
import org.jkiss.dbeaver.model.struct.DBSDataType;
import org.jkiss.dbeaver.model.struct.DBSTypedObject;
import org.jkiss.dbeaver.model.struct.DBSTypedObjectEx;
import org.jkiss.dbeaver.registry.RegistryConstants;
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
import org.jkiss.dbeaver.ui.data.IValueManager;
import org.jkiss.utils.CommonUtils;
......@@ -68,8 +67,8 @@ public class ValueManagerDescriptor extends AbstractDescriptor
{
super(config);
this.id = config.getAttribute(RegistryConstants.ATTR_ID);
this.implType = new ObjectType(config.getAttribute(RegistryConstants.ATTR_CLASS));
this.id = config.getAttribute("id");
this.implType = new ObjectType(config.getAttribute("class"));
IConfigurationElement[] typeElements = config.getChildren(TAG_SUPPORTS);
for (IConfigurationElement typeElement : typeElements) {
......@@ -128,7 +127,7 @@ public class ValueManagerDescriptor extends AbstractDescriptor
final DBPDataKind dataKind = typedObject.getDataKind();
for (SupportInfo info : supportInfos) {
if (dataSource != null && info.dataSource != null) {
DriverDescriptor driver = (DriverDescriptor) dataSource.getContainer().getDriver();
DBPDriver driver = dataSource.getContainer().getDriver();
if (!info.dataSource.equals(driver.getProviderId()) && !info.dataSource.equals(dataSource.getClass().getName())) {
continue;
}
......
......@@ -28,7 +28,6 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSTypedObject;
import org.jkiss.dbeaver.ui.data.IStreamValueManager;
import org.jkiss.dbeaver.ui.data.IValueManager;
import org.jkiss.dbeaver.ui.data.managers.DefaultValueManager;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.MimeType;
......@@ -80,7 +79,7 @@ public class ValueManagerRegistry {
manager = findManager(dataSource, dataKind, valueType, false, false);
}
if (manager == null) {
manager = DefaultValueManager.INSTANCE;
throw new IllegalStateException("Can't find default data manager for " + dataKind);
}
return manager;
}
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.data.DBDContent;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
import org.jkiss.dbeaver.model.runtime.DefaultProgressMonitor;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.ui.IRefreshablePart;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetContainer;
import org.jkiss.dbeaver.ui.data.IStreamValueManager;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.data.IValueEditorStandalone;
import org.jkiss.dbeaver.ui.data.managers.stream.TextStreamValueManager;
import org.jkiss.dbeaver.ui.data.registry.StreamValueManagerDescriptor;
import org.jkiss.dbeaver.ui.data.registry.ValueManagerRegistry;
import org.jkiss.dbeaver.ui.dialogs.ColumnInfoPanel;
import org.jkiss.dbeaver.ui.dialogs.DialogUtils;
import org.jkiss.dbeaver.ui.editors.MultiPageAbstractEditor;
import org.jkiss.dbeaver.ui.editors.entity.EntityEditor;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* LOBEditor
*/
public class ContentEditor extends MultiPageAbstractEditor implements IValueEditorStandalone, IRefreshablePart
{
@Override
public ContentEditorInput getEditorInput()
{
return (ContentEditorInput)super.getEditorInput();
}
@Nullable
public static ContentEditor openEditor(IValueController valueController)
{
ContentEditorInput editorInput;
// Save data to file
try {
LOBInitializer initializer = new LOBInitializer(valueController);
//valueController.getValueSite().getWorkbenchWindow().run(true, true, initializer);
UIUtils.runInProgressService(initializer);
editorInput = initializer.editorInput;
} catch (Throwable e) {
if (e instanceof InvocationTargetException) {
e = ((InvocationTargetException)e).getTargetException();
}
DBWorkbench.getPlatformUI().showError("Cannot open content editor", null, e);
return null;
}
try {
return (ContentEditor) valueController.getValueSite().getWorkbenchWindow().getActivePage().openEditor(
editorInput,
ContentEditor.class.getName());
}
catch (PartInitException e) {
log.error("Can't open CONTENT editorPart", e);
return null;
}
}
//public static final long MAX_TEXT_LENGTH = 10 * 1024 * 1024;
//public static final long MAX_IMAGE_LENGTH = 10 * 1024 * 1024;
private static final Log log = Log.getLog(ContentEditor.class);
static class ContentPartInfo {
IEditorPart editorPart;
boolean isDefault;
boolean activated;
public int index = -1;
private ContentPartInfo(IEditorPart editorPart, boolean isDefault) {
this.editorPart = editorPart;
this.isDefault = isDefault;
}
}
private static class LOBInitializer implements DBRRunnableWithProgress {
IValueController valueController;
Object value;
IEditorPart[] editorParts;
IEditorPart defaultPart;
ContentEditorInput editorInput;
public LOBInitializer(IValueController valueController) {
this.valueController = valueController;
this.value = valueController.getValue();
}
private LOBInitializer(IValueController valueController, IEditorPart[] editorParts, IEditorPart defaultPart, @Nullable ContentEditorInput editorInput)
{
this.valueController = valueController;
this.editorParts = editorParts;
this.defaultPart = defaultPart;
this.editorInput = editorInput;
}
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException
{
try {
if (value != null && editorParts == null) {
List<IEditorPart> parts = new ArrayList<>();
if (value instanceof String) {
TextStreamValueManager valueManager = new TextStreamValueManager();
defaultPart = valueManager.createEditorPart(valueController);
parts.add(defaultPart);
} else if (value instanceof DBDContent) {
DBDContent content = (DBDContent) value;
Map<StreamValueManagerDescriptor, IStreamValueManager.MatchType> streamManagers =
ValueManagerRegistry.getInstance().getApplicableStreamManagers(monitor, valueController.getValueType(), content);
IStreamValueManager.MatchType defaultMatch = null;
for (Map.Entry<StreamValueManagerDescriptor, IStreamValueManager.MatchType> entry : streamManagers.entrySet()) {
IStreamValueManager streamValueManager = entry.getKey().getInstance();
try {
IEditorPart editorPart = streamValueManager.createEditorPart(valueController);
IStreamValueManager.MatchType matchType = entry.getValue();
if (defaultPart == null) {
defaultPart = editorPart;
defaultMatch = matchType;
} else {
boolean setDefault = false;
switch (matchType) {
case EXCLUSIVE:
case PRIMARY:
setDefault = true;
break;
case DEFAULT:
setDefault = (defaultMatch == IStreamValueManager.MatchType.APPLIES);
break;
default:
break;
}
if (setDefault) {
defaultPart = editorPart;
defaultMatch = matchType;
}
}
parts.add(editorPart);
} catch (DBException e) {
log.error(e);
}
}
}
editorParts = parts.toArray(new IEditorPart[parts.size()]);
}
if (editorInput == null) {
editorInput = new ContentEditorInput(
valueController,
editorParts,
defaultPart,
monitor);
} else {
editorInput.refreshContent(monitor, valueController);
}
} catch (DBException e) {
throw new InvocationTargetException(e);
}
}
}
private List<ContentPartInfo> contentParts = new ArrayList<>();
private ColumnInfoPanel infoPanel;
private boolean dirty;
private boolean partsLoaded;
private boolean saveInProgress;
public ContentEditor()
{
}
@Override
public void doSave(final IProgressMonitor monitor)
{
if (!isDirty()) {
// Nothing to save
return;
}
// Execute save in UI thread
UIUtils.syncExec(() -> {
try {
// Check for dirty parts
final List<IEditorPart> dirtyParts = new ArrayList<>();
for (ContentPartInfo partInfo : contentParts) {
if (partInfo.activated && partInfo.editorPart.isDirty()) {
dirtyParts.add(partInfo.editorPart);
}
}
IEditorPart dirtyPart = null;
if (dirtyParts.isEmpty()) {
// No modified parts - no additional save required
} else if (dirtyParts.size() == 1) {
// Single part modified - save it
dirtyPart = dirtyParts.get(0);
} else {
// Multiple parts modified - need to choose one
dirtyPart = SelectContentPartDialog.selectContentPart(getSite().getShell(), dirtyParts);
}
if (dirtyPart != null) {
saveInProgress = true;
try {
dirtyPart.doSave(monitor);
} finally {
saveInProgress = false;
}
}
// Set dirty flag - if error will occur during content save
// then document remains dirty
ContentEditor.this.dirty = true;
ContentEditorInput editorInput = getEditorInput();
editorInput.updateContentFromFile(new DefaultProgressMonitor(monitor), editorInput.getValue());
editorInput.getValueController().updateValue(editorInput.getValue(), true);
// Activate owner editor and focus on cell corresponding to this content editor
IWorkbenchPartSite parentEditorSite = editorInput.getValueController().getValueSite();
IWorkbenchPart parentEditor;
if (parentEditorSite instanceof MultiPageEditorSite) {
parentEditor = ((MultiPageEditorSite) parentEditorSite).getMultiPageEditor();
if (parentEditor instanceof EntityEditor) {
((EntityEditor) parentEditor).setActiveEditor(IResultSetContainer.class);
}
} else {
parentEditor = parentEditorSite.getPart();
}
parentEditorSite.getWorkbenchWindow().getActivePage().activate(parentEditor);
// Close editor
closeValueEditor();
} catch (Exception e) {
DBWorkbench.getPlatformUI().showError(
"Can't save content",
"Can't save content to database",
e);
}
});
}
@Override
public void doSaveAs()
{
Shell shell = getSite().getShell();
final File saveFile = DialogUtils.selectFileForSave(shell, getPartName());
if (saveFile == null) {
return;
}
try {
getSite().getWorkbenchWindow().run(true, true, monitor -> {
try {
getEditorInput().saveToExternalFile(saveFile, monitor);
}
catch (CoreException e) {
throw new InvocationTargetException(e);
}
});
}
catch (InvocationTargetException e) {
DBWorkbench.getPlatformUI().showError(
"Can't save content",
"Can't save content to file '" + saveFile.getAbsolutePath() + "'",
e.getTargetException());
}
catch (InterruptedException e) {
// do nothing
}
}
@Override
public void init(IEditorSite site, IEditorInput input)
throws PartInitException
{
super.init(site, input);
setPartName(input.getName());
// Fill nested editorParts info
IEditorPart[] editorParts = getEditorInput().getEditors();
for (IEditorPart editorPart : editorParts) {
contentParts.add(new ContentPartInfo(editorPart, editorPart == getEditorInput().getDefaultEditor()));
//editorPart.init(site, input);
}
//ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
@Override
public void dispose()
{
this.partsLoaded = true;
//ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
if (getEditorInput() != null) {
// Release CONTENT input resources
try {
getEditorInput().release();
} catch (Throwable e) {
log.warn("Error releasing CONTENT input", e);
}
}
super.dispose();
}
@Override
public boolean isDirty()
{
if (dirty) {
return true;
}
for (ContentPartInfo contentPart : contentParts) {
if (contentPart.activated && contentPart.editorPart.isDirty()) {
return true;
}
}
return false;
}
@Override
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
@Override
public boolean isSaveAsAllowed()
{
return true;
}
@Override
protected IEditorSite createSite(IEditorPart editor)
{
return new ContentEditorSite(this, editor);
}
@Override
protected void createPages() {
super.createPages();
ContentPartInfo defaultPage = null;
for (ContentPartInfo contentPart : contentParts) {
if (contentPart.isDefault) {
defaultPage = contentPart;
}
IEditorPart editorPart = contentPart.editorPart;
try {
int index = addPage(editorPart, getEditorInput());
setPageText(index, editorPart.getTitle());
setPageImage(index, editorPart.getTitleImage());
contentPart.activated = true;
contentPart.index = index;
} catch (PartInitException e) {
log.error(e);
}
}
if (defaultPage != null) {
setActiveEditor(defaultPage.editorPart);
}
this.partsLoaded = true;
}
@Override
public void removePage(int pageIndex) {
for (ContentPartInfo contentPart : contentParts) {
if (contentPart.index == pageIndex) {
contentPart.index = -1;
} else if (contentPart.index > pageIndex) {
contentPart.index--;
}
}
super.removePage(pageIndex);
}
@Override
protected Composite createPageContainer(Composite parent)
{
SashForm panel = UIUtils.createPartDivider(this, parent, SWT.VERTICAL);
/*
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
panel.setLayout(layout);
*/
if (parent.getLayout() instanceof GridLayout) {
panel.setLayoutData(new GridData(GridData.FILL_BOTH));
}
{
IValueController valueController = getValueController();
assert valueController != null;
infoPanel = new ColumnInfoPanel(panel, SWT.NONE, valueController);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.exclude = true;
infoPanel.setLayoutData(gd);
}
Composite editorPanel = new Composite(panel, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
editorPanel.setLayout(layout);
editorPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
panel.setMaximizedControl(editorPanel);
return editorPanel;
}
void toggleInfoBar()
{
SashForm sashForm = (SashForm) infoPanel.getParent();
boolean visible = sashForm.getMaximizedControl() == null;
if (visible) {
sashForm.setMaximizedControl(sashForm.getChildren()[1]);
} else {
sashForm.setMaximizedControl(null);
infoPanel.layoutProperties();
}
}
@Nullable
Object getValue()
{
IValueController valueController = getValueController();
return valueController == null? null : valueController.getValue();
}
@Nullable
public IValueController getValueController()
{
ContentEditorInput input = getEditorInput();
return input == null ? null : input.getValueController();
}
@Override
public void createControl() {
}
@Override
public Control getControl()
{
// Return container control
// Don't return active page because container may be already disposed (#2805)
return super.getContainer();
/*
int activePage = getActivePage();
return activePage < 0 ? null : getControl(activePage);
*/
}
@Override
public Object extractEditorValue() throws DBException
{
UIUtils.runInUI(monitor -> {
try {
getEditorInput().updateContentFromFile(monitor, getEditorInput().getValue());
} catch (DBException e) {
throw new InvocationTargetException(e);
}
});
return getEditorInput().getValue();
}
@Override
public void primeEditorValue(@Nullable Object value) throws DBException
{
ContentEditorInput input = getEditorInput();
IValueController valueController = input.getValueController();
LOBInitializer initializer = new LOBInitializer(valueController, input.getEditors(), input.getDefaultEditor(), input);
try {
//valueController.getValueSite().getWorkbenchWindow().run(true, true, initializer);
UIUtils.runInProgressService(initializer);
} catch (InvocationTargetException e) {
DBWorkbench.getPlatformUI().showError("Cannot refresh content editor", null, e);
} catch (InterruptedException e) {
// ignore
}
}
@Override
public void contributeActions(@NotNull IContributionManager manager, @NotNull IValueController controller) throws DBCException {
}
@Override
public void showValueEditor()
{
this.getEditorSite().getWorkbenchWindow().getActivePage().activate(this);
}
@Override
public void closeValueEditor()
{
IWorkbenchPage workbenchPage = this.getEditorSite().getWorkbenchWindow().getActivePage();
if (workbenchPage != null) {
workbenchPage.closeEditor(this, false);
}
}
@Override
public void refreshPart(Object source, boolean force) {
getEditorInput().refreshContentParts(source);
fireContentChanged();
}
public void fireContentChanged() {
firePropertyChange(ContentEditor.PROP_DIRTY);
}
/*
@Override
public void resourceChanged(IResourceChangeEvent event)
{
if (!partsLoaded || saveInProgress) {
// No content change before all parts are loaded
return;
}
IResourceDelta delta= event.getDelta();
if (delta == null) {
return;
}
delta = delta.findMember(ContentUtils.convertPathToWorkspacePath(getEditorInput().getPath()));
if (delta == null) {
return;
}
if (delta.getKind() == IResourceDelta.CHANGED &&
(delta.getFlags() & IResourceDelta.CONTENT) != 0)
{
// Content was changed somehow so mark editor as dirty
dirty = true;
DBeaverUI.asyncExec(new Runnable() {
@Override
public void run() {
firePropertyChange(PROP_DIRTY);
}
});
}
}
*/
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.data.DBDContent;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
import org.jkiss.dbeaver.model.runtime.DefaultProgressMonitor;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.ui.IRefreshablePart;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.controls.ColumnInfoPanel;
import org.jkiss.dbeaver.ui.data.IStreamValueManager;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.data.IValueEditorStandalone;
import org.jkiss.dbeaver.ui.data.managers.stream.TextStreamValueManager;
import org.jkiss.dbeaver.ui.data.registry.StreamValueManagerDescriptor;
import org.jkiss.dbeaver.ui.data.registry.ValueManagerRegistry;
import org.jkiss.dbeaver.ui.dialogs.DialogUtils;
import org.jkiss.dbeaver.ui.editors.MultiPageAbstractEditor;
import org.jkiss.dbeaver.ui.editors.entity.EntityEditor;
import org.jkiss.dbeaver.ui.editors.entity.IEntityDataContainer;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* LOBEditor
*/
public class ContentEditor extends MultiPageAbstractEditor implements IValueEditorStandalone, IRefreshablePart
{
@Override
public ContentEditorInput getEditorInput()
{
return (ContentEditorInput)super.getEditorInput();
}
@Nullable
public static ContentEditor openEditor(IValueController valueController)
{
ContentEditorInput editorInput;
// Save data to file
try {
LOBInitializer initializer = new LOBInitializer(valueController);
//valueController.getValueSite().getWorkbenchWindow().run(true, true, initializer);
UIUtils.runInProgressService(initializer);
editorInput = initializer.editorInput;
} catch (Throwable e) {
if (e instanceof InvocationTargetException) {
e = ((InvocationTargetException)e).getTargetException();
}
DBWorkbench.getPlatformUI().showError("Cannot open content editor", null, e);
return null;
}
try {
return (ContentEditor) valueController.getValueSite().getWorkbenchWindow().getActivePage().openEditor(
editorInput,
ContentEditor.class.getName());
}
catch (PartInitException e) {
log.error("Can't open CONTENT editorPart", e);
return null;
}
}
//public static final long MAX_TEXT_LENGTH = 10 * 1024 * 1024;
//public static final long MAX_IMAGE_LENGTH = 10 * 1024 * 1024;
private static final Log log = Log.getLog(ContentEditor.class);
static class ContentPartInfo {
IEditorPart editorPart;
boolean isDefault;
boolean activated;
public int index = -1;
private ContentPartInfo(IEditorPart editorPart, boolean isDefault) {
this.editorPart = editorPart;
this.isDefault = isDefault;
}
}
private static class LOBInitializer implements DBRRunnableWithProgress {
IValueController valueController;
Object value;
IEditorPart[] editorParts;
IEditorPart defaultPart;
ContentEditorInput editorInput;
public LOBInitializer(IValueController valueController) {
this.valueController = valueController;
this.value = valueController.getValue();
}
private LOBInitializer(IValueController valueController, IEditorPart[] editorParts, IEditorPart defaultPart, @Nullable ContentEditorInput editorInput)
{
this.valueController = valueController;
this.editorParts = editorParts;
this.defaultPart = defaultPart;
this.editorInput = editorInput;
}
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException
{
try {
if (value != null && editorParts == null) {
List<IEditorPart> parts = new ArrayList<>();
if (value instanceof String) {
TextStreamValueManager valueManager = new TextStreamValueManager();
defaultPart = valueManager.createEditorPart(valueController);
parts.add(defaultPart);
} else if (value instanceof DBDContent) {
DBDContent content = (DBDContent) value;
Map<StreamValueManagerDescriptor, IStreamValueManager.MatchType> streamManagers =
ValueManagerRegistry.getInstance().getApplicableStreamManagers(monitor, valueController.getValueType(), content);
IStreamValueManager.MatchType defaultMatch = null;
for (Map.Entry<StreamValueManagerDescriptor, IStreamValueManager.MatchType> entry : streamManagers.entrySet()) {
IStreamValueManager streamValueManager = entry.getKey().getInstance();
try {
IEditorPart editorPart = streamValueManager.createEditorPart(valueController);
IStreamValueManager.MatchType matchType = entry.getValue();
if (defaultPart == null) {
defaultPart = editorPart;
defaultMatch = matchType;
} else {
boolean setDefault = false;
switch (matchType) {
case EXCLUSIVE:
case PRIMARY:
setDefault = true;
break;
case DEFAULT:
setDefault = (defaultMatch == IStreamValueManager.MatchType.APPLIES);
break;
default:
break;
}
if (setDefault) {
defaultPart = editorPart;
defaultMatch = matchType;
}
}
parts.add(editorPart);
} catch (DBException e) {
log.error(e);
}
}
}
editorParts = parts.toArray(new IEditorPart[parts.size()]);
}
if (editorInput == null) {
editorInput = new ContentEditorInput(
valueController,
editorParts,
defaultPart,
monitor);
} else {
editorInput.refreshContent(monitor, valueController);
}
} catch (DBException e) {
throw new InvocationTargetException(e);
}
}
}
private List<ContentPartInfo> contentParts = new ArrayList<>();
private ColumnInfoPanel infoPanel;
private boolean dirty;
private boolean partsLoaded;
private boolean saveInProgress;
public ContentEditor()
{
}
@Override
public void doSave(final IProgressMonitor monitor)
{
if (!isDirty()) {
// Nothing to save
return;
}
// Execute save in UI thread
UIUtils.syncExec(() -> {
try {
// Check for dirty parts
final List<IEditorPart> dirtyParts = new ArrayList<>();
for (ContentPartInfo partInfo : contentParts) {
if (partInfo.activated && partInfo.editorPart.isDirty()) {
dirtyParts.add(partInfo.editorPart);
}
}
IEditorPart dirtyPart = null;
if (dirtyParts.isEmpty()) {
// No modified parts - no additional save required
} else if (dirtyParts.size() == 1) {
// Single part modified - save it
dirtyPart = dirtyParts.get(0);
} else {
// Multiple parts modified - need to choose one
dirtyPart = SelectContentPartDialog.selectContentPart(getSite().getShell(), dirtyParts);
}
if (dirtyPart != null) {
saveInProgress = true;
try {
dirtyPart.doSave(monitor);
} finally {
saveInProgress = false;
}
}
// Set dirty flag - if error will occur during content save
// then document remains dirty
ContentEditor.this.dirty = true;
ContentEditorInput editorInput = getEditorInput();
editorInput.updateContentFromFile(new DefaultProgressMonitor(monitor), editorInput.getValue());
editorInput.getValueController().updateValue(editorInput.getValue(), true);
// Activate owner editor and focus on cell corresponding to this content editor
IWorkbenchPartSite parentEditorSite = editorInput.getValueController().getValueSite();
IWorkbenchPart parentEditor;
if (parentEditorSite instanceof MultiPageEditorSite) {
parentEditor = ((MultiPageEditorSite) parentEditorSite).getMultiPageEditor();
if (parentEditor instanceof EntityEditor) {
((EntityEditor) parentEditor).setActiveEditor(IEntityDataContainer.class);
}
} else {
parentEditor = parentEditorSite.getPart();
}
parentEditorSite.getWorkbenchWindow().getActivePage().activate(parentEditor);
// Close editor
closeValueEditor();
} catch (Exception e) {
DBWorkbench.getPlatformUI().showError(
"Can't save content",
"Can't save content to database",
e);
}
});
}
@Override
public void doSaveAs()
{
Shell shell = getSite().getShell();
final File saveFile = DialogUtils.selectFileForSave(shell, getPartName());
if (saveFile == null) {
return;
}
try {
getSite().getWorkbenchWindow().run(true, true, monitor -> {
try {
getEditorInput().saveToExternalFile(saveFile, monitor);
}
catch (CoreException e) {
throw new InvocationTargetException(e);
}
});
}
catch (InvocationTargetException e) {
DBWorkbench.getPlatformUI().showError(
"Can't save content",
"Can't save content to file '" + saveFile.getAbsolutePath() + "'",
e.getTargetException());
}
catch (InterruptedException e) {
// do nothing
}
}
@Override
public void init(IEditorSite site, IEditorInput input)
throws PartInitException
{
super.init(site, input);
setPartName(input.getName());
// Fill nested editorParts info
IEditorPart[] editorParts = getEditorInput().getEditors();
for (IEditorPart editorPart : editorParts) {
contentParts.add(new ContentPartInfo(editorPart, editorPart == getEditorInput().getDefaultEditor()));
//editorPart.init(site, input);
}
//ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
@Override
public void dispose()
{
this.partsLoaded = true;
//ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
if (getEditorInput() != null) {
// Release CONTENT input resources
try {
getEditorInput().release();
} catch (Throwable e) {
log.warn("Error releasing CONTENT input", e);
}
}
super.dispose();
}
@Override
public boolean isDirty()
{
if (dirty) {
return true;
}
for (ContentPartInfo contentPart : contentParts) {
if (contentPart.activated && contentPart.editorPart.isDirty()) {
return true;
}
}
return false;
}
@Override
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
@Override
public boolean isSaveAsAllowed()
{
return true;
}
@Override
protected IEditorSite createSite(IEditorPart editor)
{
return new ContentEditorSite(this, editor);
}
@Override
protected void createPages() {
super.createPages();
ContentPartInfo defaultPage = null;
for (ContentPartInfo contentPart : contentParts) {
if (contentPart.isDefault) {
defaultPage = contentPart;
}
IEditorPart editorPart = contentPart.editorPart;
try {
int index = addPage(editorPart, getEditorInput());
setPageText(index, editorPart.getTitle());
setPageImage(index, editorPart.getTitleImage());
contentPart.activated = true;
contentPart.index = index;
} catch (PartInitException e) {
log.error(e);
}
}
if (defaultPage != null) {
setActiveEditor(defaultPage.editorPart);
}
this.partsLoaded = true;
}
@Override
public void removePage(int pageIndex) {
for (ContentPartInfo contentPart : contentParts) {
if (contentPart.index == pageIndex) {
contentPart.index = -1;
} else if (contentPart.index > pageIndex) {
contentPart.index--;
}
}
super.removePage(pageIndex);
}
@Override
protected Composite createPageContainer(Composite parent)
{
SashForm panel = UIUtils.createPartDivider(this, parent, SWT.VERTICAL);
/*
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
panel.setLayout(layout);
*/
if (parent.getLayout() instanceof GridLayout) {
panel.setLayoutData(new GridData(GridData.FILL_BOTH));
}
{
IValueController valueController = getValueController();
assert valueController != null;
infoPanel = new ColumnInfoPanel(panel, SWT.NONE, valueController);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.exclude = true;
infoPanel.setLayoutData(gd);
}
Composite editorPanel = new Composite(panel, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.horizontalSpacing = 0;
editorPanel.setLayout(layout);
editorPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
panel.setMaximizedControl(editorPanel);
return editorPanel;
}
void toggleInfoBar()
{
SashForm sashForm = (SashForm) infoPanel.getParent();
boolean visible = sashForm.getMaximizedControl() == null;
if (visible) {
sashForm.setMaximizedControl(sashForm.getChildren()[1]);
} else {
sashForm.setMaximizedControl(null);
infoPanel.layoutProperties();
}
}
@Nullable
Object getValue()
{
IValueController valueController = getValueController();
return valueController == null? null : valueController.getValue();
}
@Nullable
public IValueController getValueController()
{
ContentEditorInput input = getEditorInput();
return input == null ? null : input.getValueController();
}
@Override
public void createControl() {
}
@Override
public Control getControl()
{
// Return container control
// Don't return active page because container may be already disposed (#2805)
return super.getContainer();
/*
int activePage = getActivePage();
return activePage < 0 ? null : getControl(activePage);
*/
}
@Override
public Object extractEditorValue() throws DBException
{
UIUtils.runInUI(monitor -> {
try {
getEditorInput().updateContentFromFile(monitor, getEditorInput().getValue());
} catch (DBException e) {
throw new InvocationTargetException(e);
}
});
return getEditorInput().getValue();
}
@Override
public void primeEditorValue(@Nullable Object value) throws DBException
{
ContentEditorInput input = getEditorInput();
IValueController valueController = input.getValueController();
LOBInitializer initializer = new LOBInitializer(valueController, input.getEditors(), input.getDefaultEditor(), input);
try {
//valueController.getValueSite().getWorkbenchWindow().run(true, true, initializer);
UIUtils.runInProgressService(initializer);
} catch (InvocationTargetException e) {
DBWorkbench.getPlatformUI().showError("Cannot refresh content editor", null, e);
} catch (InterruptedException e) {
// ignore
}
}
@Override
public void contributeActions(@NotNull IContributionManager manager, @NotNull IValueController controller) throws DBCException {
}
@Override
public void showValueEditor()
{
this.getEditorSite().getWorkbenchWindow().getActivePage().activate(this);
}
@Override
public void closeValueEditor()
{
IWorkbenchPage workbenchPage = this.getEditorSite().getWorkbenchWindow().getActivePage();
if (workbenchPage != null) {
workbenchPage.closeEditor(this, false);
}
}
@Override
public void refreshPart(Object source, boolean force) {
getEditorInput().refreshContentParts(source);
fireContentChanged();
}
public void fireContentChanged() {
firePropertyChange(ContentEditor.PROP_DIRTY);
}
/*
@Override
public void resourceChanged(IResourceChangeEvent event)
{
if (!partsLoaded || saveInProgress) {
// No content change before all parts are loaded
return;
}
IResourceDelta delta= event.getDelta();
if (delta == null) {
return;
}
delta = delta.findMember(ContentUtils.convertPathToWorkspacePath(getEditorInput().getPath()));
if (delta == null) {
return;
}
if (delta.getKind() == IResourceDelta.CHANGED &&
(delta.getFlags() & IResourceDelta.CONTENT) != 0)
{
// Content was changed somehow so mark editor as dirty
dirty = true;
DBeaverUI.asyncExec(new Runnable() {
@Override
public void run() {
firePropertyChange(PROP_DIRTY);
}
});
}
}
*/
}
\ No newline at end of file
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.*;
import org.eclipse.ui.editors.text.IEncodingSupport;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.core.DBeaverCore;
import org.jkiss.dbeaver.model.DBIcon;
import org.jkiss.dbeaver.model.DBPContextProvider;
import org.jkiss.dbeaver.model.DBValueFormatting;
import org.jkiss.dbeaver.model.data.DBDContent;
import org.jkiss.dbeaver.model.data.DBDContentCached;
import org.jkiss.dbeaver.model.data.DBDContentStorage;
import org.jkiss.dbeaver.model.data.DBDContentStorageLocal;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.impl.BytesContentStorage;
import org.jkiss.dbeaver.model.impl.ExternalContentStorage;
import org.jkiss.dbeaver.model.impl.StringContentStorage;
import org.jkiss.dbeaver.model.impl.TemporaryContentStorage;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DefaultProgressMonitor;
import org.jkiss.dbeaver.runtime.LocalFileStorage;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.IRefreshablePart;
import org.jkiss.dbeaver.ui.data.IAttributeController;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.editors.IStatefulEditorInput;
import org.jkiss.dbeaver.ui.editors.StringEditorInput;
import org.jkiss.dbeaver.utils.ContentUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.IOUtils;
import java.io.*;
/**
* ContentEditorInput
*/
public class ContentEditorInput implements IPathEditorInput, IStatefulEditorInput, DBPContextProvider, IEncodingSupport
{
private static final Log log = Log.getLog(ContentEditorInput.class);
private IValueController valueController;
private IEditorPart[] editorParts;
private IEditorPart defaultPart;
private boolean contentDetached = false;
private File contentFile;
private String fileCharset;
private StringEditorInput.StringStorage stringStorage;
public ContentEditorInput(
IValueController valueController,
IEditorPart[] editorParts,
IEditorPart defaultPart,
DBRProgressMonitor monitor)
throws DBException
{
this.valueController = valueController;
this.editorParts = editorParts;
this.defaultPart = defaultPart;
this.fileCharset = getDefaultEncoding();
this.prepareContent(monitor);
}
public IValueController getValueController()
{
return valueController;
}
public void refreshContent(DBRProgressMonitor monitor, IValueController valueController) throws DBException
{
this.valueController = valueController;
this.prepareContent(monitor);
}
IEditorPart[] getEditors()
{
return editorParts;
}
public IEditorPart getDefaultEditor() {
return defaultPart;
}
@Override
public boolean exists()
{
return false;
}
@Override
public ImageDescriptor getImageDescriptor()
{
return DBeaverIcons.getImageDescriptor(DBIcon.TYPE_LOB);
}
@Override
public String getName()
{
String inputName;
if (valueController instanceof IAttributeController) {
inputName = ((IAttributeController) valueController).getColumnId();
} else {
inputName = valueController.getValueName();
}
if (isReadOnly()) {
inputName += " [Read Only]";
}
return inputName;
}
@Nullable
@Override
public IPersistableElement getPersistable()
{
return null;
}
@Override
public String getToolTipText()
{
return getName();
}
@Nullable
@Override
public <T> T getAdapter(Class<T> adapter)
{
if (adapter == IStorage.class) {
if (stringStorage != null) {
return adapter.cast(stringStorage);
} else {
return adapter.cast(new LocalFileStorage(contentFile, fileCharset));
}
}
return null;
}
public Object getValue() {
return valueController.getValue();
}
private void prepareContent(DBRProgressMonitor monitor)
throws DBException
{
Object value = getValue();
DBDContent content;
if (value instanceof DBDContent) {
content = (DBDContent) value;
} else {
// No need to do init
stringStorage = new StringEditorInput(getName(), CommonUtils.toString(value), isReadOnly(), fileCharset).getStorage();
return;
}
DBDContentStorage storage = content.getContents(monitor);
if (contentDetached) {
release();
contentDetached = false;
}
if (storage instanceof DBDContentStorageLocal) {
// User content's storage directly
contentFile = ((DBDContentStorageLocal)storage).getDataFile();
contentDetached = true;
} else {
// Copy content to local file
try {
// Create file
if (contentFile == null) {
String valueId;
if (valueController instanceof IAttributeController) {
valueId = ((IAttributeController) valueController).getColumnId();
} else {
valueId = valueController.getValueName();
}
contentFile = ContentUtils.createTempContentFile(monitor, DBeaverCore.getInstance(), valueId);
}
// Write value to file
copyContentToFile(content, monitor);
}
catch (IOException e) {
// Delete temp file
if (contentFile != null && contentFile.exists()) {
if (!contentFile.delete()) {
log.warn("Can't delete temporary content file '" + contentFile.getAbsolutePath() + "'");
}
}
throw new DBException("Can't delete content file", e);
}
}
// Mark file as readonly
if (valueController.isReadOnly()) {
markReadOnly(true);
}
}
private void markReadOnly(boolean readOnly) throws DBException
{
if (!contentFile.setWritable(!readOnly)) {
throw new DBException("Can't set content read-only");
}
}
public void release()
{
if (contentFile != null && !contentDetached) {
if (!contentFile.delete()) {
log.warn("Can't delete temp file '" + contentFile.getAbsolutePath() + "'");
}
contentDetached = true;
}
stringStorage = null;
}
@Nullable
@Override
public IPath getPath()
{
return contentFile == null ? null : new Path(contentFile.getAbsolutePath());
}
public boolean isReadOnly() {
return valueController.isReadOnly();
}
void saveToExternalFile(File file, IProgressMonitor monitor)
throws CoreException
{
try (InputStream is = openContents()) {
ContentUtils.saveContentToFile(
is,
file,
RuntimeUtils.makeMonitor(monitor));
}
catch (Exception e) {
throw new CoreException(GeneralUtils.makeExceptionStatus(e));
}
}
private InputStream openContents() throws Exception {
return stringStorage == null ? new FileInputStream(contentFile) : stringStorage.getContents();
}
void loadFromExternalFile(File extFile, IProgressMonitor monitor)
throws CoreException
{
try {
release();
contentFile = extFile;
contentDetached = true;
Object value = getValue();
if (value instanceof DBDContent) {
((DBDContent)value).updateContents(
new DefaultProgressMonitor(monitor),
new ExternalContentStorage(DBeaverCore.getInstance(), extFile));
} else {
updateStringValueFromFile(extFile);
}
refreshContentParts(extFile);
}
catch (Throwable e) {
throw new CoreException(GeneralUtils.makeExceptionStatus(e));
}
}
private void updateStringValueFromFile(File extFile) throws DBException {
try (FileReader is = new FileReader(extFile)) {
String str = IOUtils.readToString(is);
stringStorage.setString(str);
valueController.updateValue(str, false);
} catch (IOException e) {
throw new DBException("Error reading content from file", e);
}
}
void refreshContentParts(Object source) {
// Refresh editor parts
for (IEditorPart cePart : editorParts) {
if (cePart instanceof IRefreshablePart) {
((IRefreshablePart) cePart).refreshPart(source, false);
}
}
}
private void copyContentToFile(DBDContent contents, DBRProgressMonitor monitor)
throws DBException, IOException
{
DBDContentStorage storage = contents.getContents(monitor);
markReadOnly(false);
try (OutputStream os = new FileOutputStream(contentFile)) {
if (contents.isNull()) {
ContentUtils.copyStreams(new ByteArrayInputStream(new byte[0]), 0, os, monitor);
} else {
if (storage == null) {
log.warn("Can't get data from null storage");
return;
}
try (InputStream is = storage.getContentStream()) {
ContentUtils.copyStreams(is, storage.getContentLength(), os, monitor);
}
}
}
markReadOnly(valueController.isReadOnly());
}
public void updateContentFromFile(DBRProgressMonitor monitor, Object value)
throws DBException
{
if (valueController.isReadOnly()) {
throw new DBCException("Can't update read-only value");
}
if (value instanceof DBDContent) {
DBDContent content = (DBDContent) value;
DBDContentStorage storage = content.getContents(monitor);
if (storage instanceof DBDContentStorageLocal) {
// Nothing to update - we use content's storage
content.updateContents(monitor, storage);
contentDetached = true;
} else if (storage instanceof DBDContentCached) {
// Create new storage and pass it to content
try (FileInputStream is = new FileInputStream(contentFile)) {
if (ContentUtils.isTextContent(content)) {
try (Reader reader = new InputStreamReader(is, fileCharset)) {
storage = StringContentStorage.createFromReader(reader);
}
} else {
storage = BytesContentStorage.createFromStream(is, contentFile.length(), fileCharset);
}
//StringContentStorage.
contentDetached = content.updateContents(monitor, storage);
} catch (IOException e) {
throw new DBException("Error reading content from file", e);
}
} else {
// Create new storage and pass it to content
storage = new TemporaryContentStorage(DBeaverCore.getInstance(), contentFile, fileCharset);
contentDetached = content.updateContents(monitor, storage);
}
} else if (stringStorage != null) {
// Just read as string
valueController.updateValue(stringStorage.getString(), false);
contentDetached = true;
}
}
@Nullable
@Override
public DBCExecutionContext getExecutionContext() {
return valueController.getExecutionContext();
}
public String getEncoding() {
return fileCharset;
}
@Override
public String getDefaultEncoding() {
if (valueController.getExecutionContext() == null) {
return GeneralUtils.getDefaultFileEncoding();
}
return DBValueFormatting.getDefaultBinaryFileEncoding(valueController.getExecutionContext().getDataSource());
}
public void setEncoding(String fileCharset) {
this.fileCharset = fileCharset;
for (IEditorPart part : editorParts) {
try {
if (part instanceof IReusableEditor) {
((IReusableEditor) part).setInput(this);
} else {
part.init(part.getEditorSite(), this);
}
} catch (PartInitException e) {
log.error("Error refreshing content editor part " + part, e);
}
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.*;
import org.eclipse.ui.editors.text.IEncodingSupport;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBIcon;
import org.jkiss.dbeaver.model.DBPContextProvider;
import org.jkiss.dbeaver.model.DBValueFormatting;
import org.jkiss.dbeaver.model.data.DBDContent;
import org.jkiss.dbeaver.model.data.DBDContentCached;
import org.jkiss.dbeaver.model.data.DBDContentStorage;
import org.jkiss.dbeaver.model.data.DBDContentStorageLocal;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.impl.BytesContentStorage;
import org.jkiss.dbeaver.model.impl.ExternalContentStorage;
import org.jkiss.dbeaver.model.impl.StringContentStorage;
import org.jkiss.dbeaver.model.impl.TemporaryContentStorage;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DefaultProgressMonitor;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.runtime.LocalFileStorage;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.IRefreshablePart;
import org.jkiss.dbeaver.ui.data.IAttributeController;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.editors.IStatefulEditorInput;
import org.jkiss.dbeaver.ui.editors.StringEditorInput;
import org.jkiss.dbeaver.utils.ContentUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.IOUtils;
import java.io.*;
/**
* ContentEditorInput
*/
public class ContentEditorInput implements IPathEditorInput, IStatefulEditorInput, DBPContextProvider, IEncodingSupport
{
private static final Log log = Log.getLog(ContentEditorInput.class);
private IValueController valueController;
private IEditorPart[] editorParts;
private IEditorPart defaultPart;
private boolean contentDetached = false;
private File contentFile;
private String fileCharset;
private StringEditorInput.StringStorage stringStorage;
public ContentEditorInput(
IValueController valueController,
IEditorPart[] editorParts,
IEditorPart defaultPart,
DBRProgressMonitor monitor)
throws DBException
{
this.valueController = valueController;
this.editorParts = editorParts;
this.defaultPart = defaultPart;
this.fileCharset = getDefaultEncoding();
this.prepareContent(monitor);
}
public IValueController getValueController()
{
return valueController;
}
public void refreshContent(DBRProgressMonitor monitor, IValueController valueController) throws DBException
{
this.valueController = valueController;
this.prepareContent(monitor);
}
IEditorPart[] getEditors()
{
return editorParts;
}
public IEditorPart getDefaultEditor() {
return defaultPart;
}
@Override
public boolean exists()
{
return false;
}
@Override
public ImageDescriptor getImageDescriptor()
{
return DBeaverIcons.getImageDescriptor(DBIcon.TYPE_LOB);
}
@Override
public String getName()
{
String inputName;
if (valueController instanceof IAttributeController) {
inputName = ((IAttributeController) valueController).getColumnId();
} else {
inputName = valueController.getValueName();
}
if (isReadOnly()) {
inputName += " [Read Only]";
}
return inputName;
}
@Nullable
@Override
public IPersistableElement getPersistable()
{
return null;
}
@Override
public String getToolTipText()
{
return getName();
}
@Nullable
@Override
public <T> T getAdapter(Class<T> adapter)
{
if (adapter == IStorage.class) {
if (stringStorage != null) {
return adapter.cast(stringStorage);
} else {
return adapter.cast(new LocalFileStorage(contentFile, fileCharset));
}
}
return null;
}
public Object getValue() {
return valueController.getValue();
}
private void prepareContent(DBRProgressMonitor monitor)
throws DBException
{
Object value = getValue();
DBDContent content;
if (value instanceof DBDContent) {
content = (DBDContent) value;
} else {
// No need to do init
stringStorage = new StringEditorInput(getName(), CommonUtils.toString(value), isReadOnly(), fileCharset).getStorage();
return;
}
DBDContentStorage storage = content.getContents(monitor);
if (contentDetached) {
release();
contentDetached = false;
}
if (storage instanceof DBDContentStorageLocal) {
// User content's storage directly
contentFile = ((DBDContentStorageLocal)storage).getDataFile();
contentDetached = true;
} else {
// Copy content to local file
try {
// Create file
if (contentFile == null) {
String valueId;
if (valueController instanceof IAttributeController) {
valueId = ((IAttributeController) valueController).getColumnId();
} else {
valueId = valueController.getValueName();
}
contentFile = ContentUtils.createTempContentFile(monitor, DBWorkbench.getPlatform(), valueId);
}
// Write value to file
copyContentToFile(content, monitor);
}
catch (IOException e) {
// Delete temp file
if (contentFile != null && contentFile.exists()) {
if (!contentFile.delete()) {
log.warn("Can't delete temporary content file '" + contentFile.getAbsolutePath() + "'");
}
}
throw new DBException("Can't delete content file", e);
}
}
// Mark file as readonly
if (valueController.isReadOnly()) {
markReadOnly(true);
}
}
private void markReadOnly(boolean readOnly) throws DBException
{
if (!contentFile.setWritable(!readOnly)) {
throw new DBException("Can't set content read-only");
}
}
public void release()
{
if (contentFile != null && !contentDetached) {
if (!contentFile.delete()) {
log.warn("Can't delete temp file '" + contentFile.getAbsolutePath() + "'");
}
contentDetached = true;
}
stringStorage = null;
}
@Nullable
@Override
public IPath getPath()
{
return contentFile == null ? null : new Path(contentFile.getAbsolutePath());
}
public boolean isReadOnly() {
return valueController.isReadOnly();
}
void saveToExternalFile(File file, IProgressMonitor monitor)
throws CoreException
{
try (InputStream is = openContents()) {
ContentUtils.saveContentToFile(
is,
file,
RuntimeUtils.makeMonitor(monitor));
}
catch (Exception e) {
throw new CoreException(GeneralUtils.makeExceptionStatus(e));
}
}
private InputStream openContents() throws Exception {
return stringStorage == null ? new FileInputStream(contentFile) : stringStorage.getContents();
}
void loadFromExternalFile(File extFile, IProgressMonitor monitor)
throws CoreException
{
try {
release();
contentFile = extFile;
contentDetached = true;
Object value = getValue();
if (value instanceof DBDContent) {
((DBDContent)value).updateContents(
new DefaultProgressMonitor(monitor),
new ExternalContentStorage(DBWorkbench.getPlatform(), extFile));
} else {
updateStringValueFromFile(extFile);
}
refreshContentParts(extFile);
}
catch (Throwable e) {
throw new CoreException(GeneralUtils.makeExceptionStatus(e));
}
}
private void updateStringValueFromFile(File extFile) throws DBException {
try (FileReader is = new FileReader(extFile)) {
String str = IOUtils.readToString(is);
stringStorage.setString(str);
valueController.updateValue(str, false);
} catch (IOException e) {
throw new DBException("Error reading content from file", e);
}
}
void refreshContentParts(Object source) {
// Refresh editor parts
for (IEditorPart cePart : editorParts) {
if (cePart instanceof IRefreshablePart) {
((IRefreshablePart) cePart).refreshPart(source, false);
}
}
}
private void copyContentToFile(DBDContent contents, DBRProgressMonitor monitor)
throws DBException, IOException
{
DBDContentStorage storage = contents.getContents(monitor);
markReadOnly(false);
try (OutputStream os = new FileOutputStream(contentFile)) {
if (contents.isNull()) {
ContentUtils.copyStreams(new ByteArrayInputStream(new byte[0]), 0, os, monitor);
} else {
if (storage == null) {
log.warn("Can't get data from null storage");
return;
}
try (InputStream is = storage.getContentStream()) {
ContentUtils.copyStreams(is, storage.getContentLength(), os, monitor);
}
}
}
markReadOnly(valueController.isReadOnly());
}
public void updateContentFromFile(DBRProgressMonitor monitor, Object value)
throws DBException
{
if (valueController.isReadOnly()) {
throw new DBCException("Can't update read-only value");
}
if (value instanceof DBDContent) {
DBDContent content = (DBDContent) value;
DBDContentStorage storage = content.getContents(monitor);
if (storage instanceof DBDContentStorageLocal) {
// Nothing to update - we use content's storage
content.updateContents(monitor, storage);
contentDetached = true;
} else if (storage instanceof DBDContentCached) {
// Create new storage and pass it to content
try (FileInputStream is = new FileInputStream(contentFile)) {
if (ContentUtils.isTextContent(content)) {
try (Reader reader = new InputStreamReader(is, fileCharset)) {
storage = StringContentStorage.createFromReader(reader);
}
} else {
storage = BytesContentStorage.createFromStream(is, contentFile.length(), fileCharset);
}
//StringContentStorage.
contentDetached = content.updateContents(monitor, storage);
} catch (IOException e) {
throw new DBException("Error reading content from file", e);
}
} else {
// Create new storage and pass it to content
storage = new TemporaryContentStorage(DBWorkbench.getPlatform(), contentFile, fileCharset);
contentDetached = content.updateContents(monitor, storage);
}
} else if (stringStorage != null) {
// Just read as string
valueController.updateValue(stringStorage.getString(), false);
contentDetached = true;
}
}
@Nullable
@Override
public DBCExecutionContext getExecutionContext() {
return valueController.getExecutionContext();
}
public String getEncoding() {
return fileCharset;
}
@Override
public String getDefaultEncoding() {
if (valueController.getExecutionContext() == null) {
return GeneralUtils.getDefaultFileEncoding();
}
return DBValueFormatting.getDefaultBinaryFileEncoding(valueController.getExecutionContext().getDataSource());
}
public void setEncoding(String fileCharset) {
this.fileCharset = fileCharset;
for (IEditorPart part : editorParts) {
try {
if (part instanceof IReusableEditor) {
((IReusableEditor) part).setInput(this);
} else {
part.init(part.getEditorSite(), this);
}
} catch (PartInitException e) {
log.error("Error refreshing content editor part " + part, e);
}
}
}
}
\ No newline at end of file
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.MultiPageEditorSite;
/**
* Content Editor Site
*/
class ContentEditorSite extends MultiPageEditorSite {
public ContentEditorSite(ContentEditor contentEditor, IEditorPart editor)
{
super(contentEditor, editor);
}
@Override
public IWorkbenchPart getPart() {
return getMultiPageEditor();
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.MultiPageEditorSite;
/**
* Content Editor Site
*/
class ContentEditorSite extends MultiPageEditorSite {
public ContentEditorSite(ContentEditor contentEditor, IEditorPart editor)
{
super(contentEditor, editor);
}
@Override
public IWorkbenchPart getPart() {
return getMultiPageEditor();
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IEditorPart;
import java.util.List;
/**
* SelectContentPartDialog
*
* @author Serge Rider
*/
class SelectContentPartDialog extends Dialog {
private List<IEditorPart> dirtyParts;
private IEditorPart selectedPart;
private SelectContentPartDialog(Shell parentShell, List<IEditorPart> dirtyParts)
{
super(parentShell);
this.dirtyParts = dirtyParts;
}
@Override
protected boolean isResizable()
{
return true;
}
@Override
protected Control createDialogArea(Composite parent)
{
getShell().setText("Choose content editor");
Composite group = (Composite) super.createDialogArea(parent);
GridData gd = new GridData(GridData.FILL_BOTH);
group.setLayoutData(gd);
Label infoLabel = new Label(group, SWT.NONE);
infoLabel.setText("Content was modified in mutliple editors. Choose correct one:");
gd = new GridData(GridData.FILL_HORIZONTAL);
infoLabel.setLayoutData(gd);
final Combo combo = new Combo(group, SWT.READ_ONLY | SWT.DROP_DOWN);
gd = new GridData(GridData.FILL_HORIZONTAL);
combo.setLayoutData(gd);
combo.add("");
for (IEditorPart part : dirtyParts) {
combo.add(part.getTitle());
}
combo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e)
{
if (combo.getSelectionIndex() >= 1) {
selectedPart = dirtyParts.get(combo.getSelectionIndex() - 1);
} else {
selectedPart = null;
}
getButton(IDialogConstants.OK_ID).setEnabled(selectedPart != null);
}
});
return group;
}
@Override
protected Control createContents(Composite parent)
{
Control ctl = super.createContents(parent);
getButton(IDialogConstants.OK_ID).setEnabled(false);
return ctl;
}
public IEditorPart getSelectedPart()
{
return selectedPart;
}
public static IEditorPart selectContentPart(Shell parentShell, List<IEditorPart> dirtyParts)
{
SelectContentPartDialog scDialog = new SelectContentPartDialog(parentShell, dirtyParts);
if (scDialog.open() == IDialogConstants.OK_ID) {
return scDialog.getSelectedPart();
} else {
return null;
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.content;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IEditorPart;
import java.util.List;
/**
* SelectContentPartDialog
*
* @author Serge Rider
*/
class SelectContentPartDialog extends Dialog {
private List<IEditorPart> dirtyParts;
private IEditorPart selectedPart;
private SelectContentPartDialog(Shell parentShell, List<IEditorPart> dirtyParts)
{
super(parentShell);
this.dirtyParts = dirtyParts;
}
@Override
protected boolean isResizable()
{
return true;
}
@Override
protected Control createDialogArea(Composite parent)
{
getShell().setText("Choose content editor");
Composite group = (Composite) super.createDialogArea(parent);
GridData gd = new GridData(GridData.FILL_BOTH);
group.setLayoutData(gd);
Label infoLabel = new Label(group, SWT.NONE);
infoLabel.setText("Content was modified in mutliple editors. Choose correct one:");
gd = new GridData(GridData.FILL_HORIZONTAL);
infoLabel.setLayoutData(gd);
final Combo combo = new Combo(group, SWT.READ_ONLY | SWT.DROP_DOWN);
gd = new GridData(GridData.FILL_HORIZONTAL);
combo.setLayoutData(gd);
combo.add("");
for (IEditorPart part : dirtyParts) {
combo.add(part.getTitle());
}
combo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e)
{
if (combo.getSelectionIndex() >= 1) {
selectedPart = dirtyParts.get(combo.getSelectionIndex() - 1);
} else {
selectedPart = null;
}
getButton(IDialogConstants.OK_ID).setEnabled(selectedPart != null);
}
});
return group;
}
@Override
protected Control createContents(Composite parent)
{
Control ctl = super.createContents(parent);
getButton(IDialogConstants.OK_ID).setEnabled(false);
return ctl;
}
public IEditorPart getSelectedPart()
{
return selectedPart;
}
public static IEditorPart selectContentPart(Shell parentShell, List<IEditorPart> dirtyParts)
{
SelectContentPartDialog scDialog = new SelectContentPartDialog(parentShell, dirtyParts);
if (scDialog.open() == IDialogConstants.OK_ID) {
return scDialog.getSelectedPart();
} else {
return null;
}
}
}
\ No newline at end of file
......@@ -24,8 +24,9 @@ public class DataEditorsMessages extends NLS {
public static String grid_tooltip_sort_by_column;
public static String grid_tooltip_filter_by_column;
public static String controls_column_info_panel_property_key;
static {
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, DataEditorsMessages.class);
}
......
grid_tooltip_sort_by_column = Sort by column
grid_tooltip_filter_by_column = Filter by column value
controls_column_info_panel_property_key = Key
grid_tooltip_filter_by_column = Filtern mit Spaltenwert
grid_tooltip_sort_by_column = Sortieren mit Spalte
controls_column_info_panel_property_key = Schl\u00FCssel
grid_tooltip_sort_by_column = Trier par colonne
grid_tooltip_filter_by_column = Filtrer par la valeur de colonne
controls_column_info_panel_property_key = Clef
grid_tooltip_sort_by_column = \u0421\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u043F\u043E \u043A\u043E\u043B\u043E\u043D\u043A\u0435
grid_tooltip_filter_by_column = \u0424\u0438\u043B\u044C\u0442\u0440 \u043F\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044E \u043A\u043E\u043B\u043E\u043D\u043A\u0438
controls_column_info_panel_property_key=\u041A\u043B\u044E\u0447
grid_tooltip_filter_by_column = \u6309\u5217\u503C\u8FC7\u6EE4
grid_tooltip_sort_by_column = \u6309\u5217\u8FC7\u6EE4
controls_column_info_panel_property_key = \u952E
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.jkiss.dbeaver.ui.editors.xml</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Vendor: %Bundle-Vendor
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.jkiss.dbeaver.ui.editors.xml;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Release-Date: 20181224
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.core.expressions,
org.eclipse.jface.text,
org.eclipse.ui,
org.eclipse.ui.editors,
org.eclipse.ui.ide,
org.eclipse.ui.workbench.texteditor,
org.jkiss.dbeaver.model,
org.jkiss.dbeaver.ui,
org.jkiss.dbeaver.ui.editors.base,
org.jkiss.dbeaver.ui.editors.data
Bundle-ClassPath: .
Export-Package: org.jkiss.dbeaver.ui.editors.xml,
org.jkiss.dbeaver.ui.data.managers.stream
Bundle-Vendor = DBeaver Corp
Bundle-Name = DBeaver UI Editors - XML
source.. = src/
output.. = target/classes/
bin.includes = .,\
META-INF/,\
OSGI-INF/,\
plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension point="org.jkiss.dbeaver.dataManager">
<streamManager class="org.jkiss.dbeaver.ui.data.managers.stream.XMLStreamValueManager" id="xml" label="XML" primaryMime="text/xml"
description="XML" icon="platform:/plugin/org.jkiss.dbeaver.model/icons/types/xml.png"/>
</extension>
</plugin>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jkiss.dbeaver</groupId>
<artifactId>plugins</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>org.jkiss.dbeaver.ui.editors.xml</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
......@@ -17,7 +17,7 @@
package org.jkiss.dbeaver.ui.data.managers.stream;
import org.jkiss.dbeaver.ui.data.IValueController;
import org.jkiss.dbeaver.ui.editors.text.BaseTextEditor;
import org.jkiss.dbeaver.ui.data.managers.AbstractTextPanelEditor;
import org.jkiss.dbeaver.ui.editors.xml.XMLEditor;
/**
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.presentation.IPresentationDamager;
import org.eclipse.jface.text.presentation.IPresentationRepairer;
import org.eclipse.swt.custom.StyleRange;
import org.jkiss.dbeaver.Log;
public class NonRuleBasedDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
private static final Log log = Log.getLog(NonRuleBasedDamagerRepairer.class);
/** The document this object works on */
protected IDocument fDocument;
/** The default text attribute if non is returned as data by the current token */
protected TextAttribute fDefaultTextAttribute;
public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) {
fDefaultTextAttribute = defaultTextAttribute;
}
/**
* @see IPresentationRepairer#setDocument(IDocument)
*/
@Override
public void setDocument(IDocument document) {
fDocument = document;
}
/**
* Returns the end offset of the line that contains the specified offset or
* if the offset is inside a line delimiter, the end offset of the next line.
*
* @param offset the offset whose line end offset must be computed
* @return the line end offset for the given offset
* @exception BadLocationException if offset is invalid in the current document
*/
protected int endOfLineOf(int offset) throws BadLocationException {
IRegion info = fDocument.getLineInformationOfOffset(offset);
if (offset <= info.getOffset() + info.getLength())
return info.getOffset() + info.getLength();
int line = fDocument.getLineOfOffset(offset);
try {
info = fDocument.getLineInformation(line + 1);
return info.getOffset() + info.getLength();
} catch (BadLocationException x) {
return fDocument.getLength();
}
}
/**
* @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
*/
@Override
public IRegion getDamageRegion(
ITypedRegion partition,
DocumentEvent event,
boolean documentPartitioningChanged) {
if (!documentPartitioningChanged) {
try {
IRegion info =
fDocument.getLineInformationOfOffset(event.getOffset());
int start = Math.max(partition.getOffset(), info.getOffset());
int end =
event.getOffset()
+ (event.getText() == null
? event.getLength()
: event.getText().length());
if (info.getOffset() <= end
&& end <= info.getOffset() + info.getLength()) {
// optimize the case of the same line
end = info.getOffset() + info.getLength();
} else
end = endOfLineOf(end);
end =
Math.min(
partition.getOffset() + partition.getLength(),
end);
return new Region(start, end - start);
} catch (BadLocationException e) {
log.debug(e);
}
}
return partition;
}
/**
* @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
*/
@Override
public void createPresentation(
TextPresentation presentation,
ITypedRegion region) {
addRange(
presentation,
region.getOffset(),
region.getLength(),
fDefaultTextAttribute);
}
/**
* Adds style information to the given text presentation.
*
* @param presentation the text presentation to be extended
* @param offset the offset of the range to be styled
* @param length the length of the range to be styled
* @param attr the attribute describing the style of the range to be styled
*/
protected void addRange(
TextPresentation presentation,
int offset,
int length,
TextAttribute attr) {
if (attr != null)
presentation.addStyleRange(
new StyleRange(
offset,
length,
attr.getForeground(),
attr.getBackground(),
attr.getStyle()));
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.presentation.IPresentationDamager;
import org.eclipse.jface.text.presentation.IPresentationRepairer;
import org.eclipse.swt.custom.StyleRange;
import org.jkiss.dbeaver.Log;
public class NonRuleBasedDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
private static final Log log = Log.getLog(NonRuleBasedDamagerRepairer.class);
/** The document this object works on */
protected IDocument fDocument;
/** The default text attribute if non is returned as data by the current token */
protected TextAttribute fDefaultTextAttribute;
public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) {
fDefaultTextAttribute = defaultTextAttribute;
}
/**
* @see IPresentationRepairer#setDocument(IDocument)
*/
@Override
public void setDocument(IDocument document) {
fDocument = document;
}
/**
* Returns the end offset of the line that contains the specified offset or
* if the offset is inside a line delimiter, the end offset of the next line.
*
* @param offset the offset whose line end offset must be computed
* @return the line end offset for the given offset
* @exception BadLocationException if offset is invalid in the current document
*/
protected int endOfLineOf(int offset) throws BadLocationException {
IRegion info = fDocument.getLineInformationOfOffset(offset);
if (offset <= info.getOffset() + info.getLength())
return info.getOffset() + info.getLength();
int line = fDocument.getLineOfOffset(offset);
try {
info = fDocument.getLineInformation(line + 1);
return info.getOffset() + info.getLength();
} catch (BadLocationException x) {
return fDocument.getLength();
}
}
/**
* @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
*/
@Override
public IRegion getDamageRegion(
ITypedRegion partition,
DocumentEvent event,
boolean documentPartitioningChanged) {
if (!documentPartitioningChanged) {
try {
IRegion info =
fDocument.getLineInformationOfOffset(event.getOffset());
int start = Math.max(partition.getOffset(), info.getOffset());
int end =
event.getOffset()
+ (event.getText() == null
? event.getLength()
: event.getText().length());
if (info.getOffset() <= end
&& end <= info.getOffset() + info.getLength()) {
// optimize the case of the same line
end = info.getOffset() + info.getLength();
} else
end = endOfLineOf(end);
end =
Math.min(
partition.getOffset() + partition.getLength(),
end);
return new Region(start, end - start);
} catch (BadLocationException e) {
log.debug(e);
}
}
return partition;
}
/**
* @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
*/
@Override
public void createPresentation(
TextPresentation presentation,
ITypedRegion region) {
addRange(
presentation,
region.getOffset(),
region.getLength(),
fDefaultTextAttribute);
}
/**
* Adds style information to the given text presentation.
*
* @param presentation the text presentation to be extended
* @param offset the offset of the range to be styled
* @param length the length of the range to be styled
* @param attr the attribute describing the style of the range to be styled
*/
protected void addRange(
TextPresentation presentation,
int offset,
int length,
TextAttribute attr) {
if (attr != null)
presentation.addStyleRange(
new StyleRange(
offset,
length,
attr.getForeground(),
attr.getBackground(),
attr.getStyle()));
}
}
\ No newline at end of file
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextViewer;
import org.jkiss.dbeaver.Log;
public class XMLDoubleClickStrategy implements ITextDoubleClickStrategy {
private static final Log log = Log.getLog(XMLDoubleClickStrategy.class);
protected ITextViewer fText;
@Override
public void doubleClicked(ITextViewer part) {
int pos = part.getSelectedRange().x;
if (pos < 0)
return;
fText = part;
if (!selectComment(pos)) {
selectWord(pos);
}
}
protected boolean selectComment(int caretPos) {
IDocument doc = fText.getDocument();
int startPos, endPos;
try {
int pos = caretPos;
char c = ' ';
while (pos >= 0) {
c = doc.getChar(pos);
if (c == '\\') {
pos -= 2;
continue;
}
if (c == Character.LINE_SEPARATOR || c == '\"')
break;
--pos;
}
if (c != '\"')
return false;
startPos = pos;
pos = caretPos;
int length = doc.getLength();
c = ' ';
while (pos < length) {
c = doc.getChar(pos);
if (c == Character.LINE_SEPARATOR || c == '\"')
break;
++pos;
}
if (c != '\"')
return false;
endPos = pos;
int offset = startPos + 1;
int len = endPos - offset;
fText.setSelectedRange(offset, len);
return true;
} catch (BadLocationException e) {
log.debug(e);
}
return false;
}
protected boolean selectWord(int caretPos) {
IDocument doc = fText.getDocument();
int startPos, endPos;
try {
int pos = caretPos;
char c;
while (pos >= 0) {
c = doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
--pos;
}
startPos = pos;
pos = caretPos;
int length = doc.getLength();
while (pos < length) {
c = doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
++pos;
}
endPos = pos;
selectRange(startPos, endPos);
return true;
} catch (BadLocationException e) {
log.debug(e);
}
return false;
}
private void selectRange(int startPos, int stopPos) {
int offset = startPos + 1;
int length = stopPos - offset;
fText.setSelectedRange(offset, length);
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextDoubleClickStrategy;
import org.eclipse.jface.text.ITextViewer;
import org.jkiss.dbeaver.Log;
public class XMLDoubleClickStrategy implements ITextDoubleClickStrategy {
private static final Log log = Log.getLog(XMLDoubleClickStrategy.class);
protected ITextViewer fText;
@Override
public void doubleClicked(ITextViewer part) {
int pos = part.getSelectedRange().x;
if (pos < 0)
return;
fText = part;
if (!selectComment(pos)) {
selectWord(pos);
}
}
protected boolean selectComment(int caretPos) {
IDocument doc = fText.getDocument();
int startPos, endPos;
try {
int pos = caretPos;
char c = ' ';
while (pos >= 0) {
c = doc.getChar(pos);
if (c == '\\') {
pos -= 2;
continue;
}
if (c == Character.LINE_SEPARATOR || c == '\"')
break;
--pos;
}
if (c != '\"')
return false;
startPos = pos;
pos = caretPos;
int length = doc.getLength();
c = ' ';
while (pos < length) {
c = doc.getChar(pos);
if (c == Character.LINE_SEPARATOR || c == '\"')
break;
++pos;
}
if (c != '\"')
return false;
endPos = pos;
int offset = startPos + 1;
int len = endPos - offset;
fText.setSelectedRange(offset, len);
return true;
} catch (BadLocationException e) {
log.debug(e);
}
return false;
}
protected boolean selectWord(int caretPos) {
IDocument doc = fText.getDocument();
int startPos, endPos;
try {
int pos = caretPos;
char c;
while (pos >= 0) {
c = doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
--pos;
}
startPos = pos;
pos = caretPos;
int length = doc.getLength();
while (pos < length) {
c = doc.getChar(pos);
if (!Character.isJavaIdentifierPart(c))
break;
++pos;
}
endPos = pos;
selectRange(startPos, endPos);
return true;
} catch (BadLocationException e) {
log.debug(e);
}
return false;
}
private void selectRange(int startPos, int stopPos) {
int offset = startPos + 1;
int length = stopPos - offset;
fText.setSelectedRange(offset, length);
}
}
\ No newline at end of file
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.texteditor.ITextEditorExtension3;
import org.jkiss.dbeaver.ui.editors.text.BaseTextEditor;
import org.jkiss.dbeaver.ui.editors.text.FileRefDocumentProvider;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class XMLEditor extends BaseTextEditor {
private ProjectionSupport projectionSupport;
private Annotation[] oldAnnotations;
private ProjectionAnnotationModel annotationModel;
public XMLEditor() {
configureInsertMode(ITextEditorExtension3.SMART_INSERT, false);
setSourceViewerConfiguration(new XMLSourceViewerConfiguration(this));
setDocumentProvider(new FileRefDocumentProvider());
}
@Override
public void dispose() {
super.dispose();
}
@Override
protected void doSetInput(IEditorInput input) throws CoreException {
super.doSetInput(input);
setupDocument();
}
@Override
public void createPartControl(Composite parent) {
super.createPartControl(parent);
ProjectionViewer viewer = (ProjectionViewer) getSourceViewer();
projectionSupport = new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors());
projectionSupport.install();
//turn projection mode on
viewer.doOperation(ProjectionViewer.TOGGLE);
annotationModel = viewer.getProjectionAnnotationModel();
}
private void setupDocument() {
IDocument document = getDocument();
if (document != null) {
IDocumentPartitioner partitioner =
new FastPartitioner(
new XMLPartitionScanner(),
new String[]{
XMLPartitionScanner.XML_TAG,
XMLPartitionScanner.XML_COMMENT});
partitioner.connect(document);
((IDocumentExtension3) document).setDocumentPartitioner(XMLPartitionScanner.XML_PARTITIONING, partitioner);
}
}
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles)
{
ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
// ensure decoration support has been created and configured.
getSourceViewerDecorationSupport(viewer);
return viewer;
}
void updateFoldingStructure(List<Position> positions) {
Annotation[] annotations = new Annotation[positions.size()];
//this will hold the new annotations along
//with their corresponding positions
Map<Annotation, Position> newAnnotations = new HashMap<>();
for (int i = 0; i < positions.size(); i++) {
ProjectionAnnotation annotation = new ProjectionAnnotation();
newAnnotations.put(annotation, positions.get(i));
annotations[i] = annotation;
}
annotationModel.modifyAnnotations(oldAnnotations, newAnnotations, null);
oldAnnotations = annotations;
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.texteditor.ITextEditorExtension3;
import org.jkiss.dbeaver.ui.editors.text.BaseTextEditor;
import org.jkiss.dbeaver.ui.editors.text.FileRefDocumentProvider;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class XMLEditor extends BaseTextEditor {
private ProjectionSupport projectionSupport;
private Annotation[] oldAnnotations;
private ProjectionAnnotationModel annotationModel;
public XMLEditor() {
configureInsertMode(ITextEditorExtension3.SMART_INSERT, false);
setSourceViewerConfiguration(new XMLSourceViewerConfiguration(this));
setDocumentProvider(new FileRefDocumentProvider());
}
@Override
public void dispose() {
super.dispose();
}
@Override
protected void doSetInput(IEditorInput input) throws CoreException {
super.doSetInput(input);
setupDocument();
}
@Override
public void createPartControl(Composite parent) {
super.createPartControl(parent);
ProjectionViewer viewer = (ProjectionViewer) getSourceViewer();
projectionSupport = new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors());
projectionSupport.install();
//turn projection mode on
viewer.doOperation(ProjectionViewer.TOGGLE);
annotationModel = viewer.getProjectionAnnotationModel();
}
private void setupDocument() {
IDocument document = getDocument();
if (document != null) {
IDocumentPartitioner partitioner =
new FastPartitioner(
new XMLPartitionScanner(),
new String[]{
XMLPartitionScanner.XML_TAG,
XMLPartitionScanner.XML_COMMENT});
partitioner.connect(document);
((IDocumentExtension3) document).setDocumentPartitioner(XMLPartitionScanner.XML_PARTITIONING, partitioner);
}
}
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles)
{
ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
// ensure decoration support has been created and configured.
getSourceViewerDecorationSupport(viewer);
return viewer;
}
void updateFoldingStructure(List<Position> positions) {
Annotation[] annotations = new Annotation[positions.size()];
//this will hold the new annotations along
//with their corresponding positions
Map<Annotation, Position> newAnnotations = new HashMap<>();
for (int i = 0; i < positions.size(); i++) {
ProjectionAnnotation annotation = new ProjectionAnnotation();
newAnnotations.put(annotation, positions.get(i));
annotations[i] = annotation;
}
annotationModel.modifyAnnotations(oldAnnotations, newAnnotations, null);
oldAnnotations = annotations;
}
}
......@@ -64,7 +64,7 @@ public class XMLFormattingStrategy extends ContextBasedFormattingStrategy
transformer.transform(source, result);
return result.getWriter().toString();
} catch (Throwable e) {
log.debug("Error formatting XML", e);
log.debug("Error formatting XML: " + e.getMessage());
return content;
}
}
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.rules.*;
public class XMLPartitionScanner extends RuleBasedPartitionScanner {
public static final String XML_PARTITIONING= "__xml_partitioning"; //$NON-NLS-1$
public final static String XML_DEFAULT = "__xml_default"; //$NON-NLS-1$
public final static String XML_COMMENT = "__xml_comment"; //$NON-NLS-1$
public final static String XML_TAG = "__xml_tag"; //$NON-NLS-1$
public XMLPartitionScanner() {
IToken xmlComment = new Token(XMLPartitionScanner.XML_COMMENT);
IToken tag = new Token(XMLPartitionScanner.XML_TAG);
IPredicateRule[] rules = new IPredicateRule[2];
rules[0] = new MultiLineRule("<!--", "-->", xmlComment); //$NON-NLS-1$//$NON-NLS-2$
rules[1] = new XMLTagRule(tag);
setPredicateRules(rules);
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.rules.*;
public class XMLPartitionScanner extends RuleBasedPartitionScanner {
public static final String XML_PARTITIONING= "__xml_partitioning"; //$NON-NLS-1$
public final static String XML_DEFAULT = "__xml_default"; //$NON-NLS-1$
public final static String XML_COMMENT = "__xml_comment"; //$NON-NLS-1$
public final static String XML_TAG = "__xml_tag"; //$NON-NLS-1$
public XMLPartitionScanner() {
IToken xmlComment = new Token(XMLPartitionScanner.XML_COMMENT);
IToken tag = new Token(XMLPartitionScanner.XML_TAG);
IPredicateRule[] rules = new IPredicateRule[2];
rules[0] = new MultiLineRule("<!--", "-->", xmlComment); //$NON-NLS-1$//$NON-NLS-2$
rules[1] = new XMLTagRule(tag);
setPredicateRules(rules);
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.*;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.jkiss.dbeaver.ui.editors.text.TextWhiteSpaceDetector;
public class XMLScanner extends RuleBasedScanner {
public XMLScanner(ISharedTextColors manager) {
IToken procInstr =
new Token(
new TextAttribute(
manager.getColor(XMLSourceViewerConfiguration.COLOR_PROC_INSTR)));
IRule[] rules = new IRule[2];
//Add rule for processing instructions
rules[0] = new SingleLineRule("<?", "?>", procInstr); //$NON-NLS-1$ //$NON-NLS-2$
// Add generic whitespace rule.
rules[1] = new WhitespaceRule(new TextWhiteSpaceDetector());
setRules(rules);
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.*;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.jkiss.dbeaver.ui.editors.text.TextWhiteSpaceDetector;
public class XMLScanner extends RuleBasedScanner {
public XMLScanner(ISharedTextColors manager) {
IToken procInstr =
new Token(
new TextAttribute(
manager.getColor(XMLSourceViewerConfiguration.COLOR_PROC_INSTR)));
IRule[] rules = new IRule[2];
//Add rule for processing instructions
rules[0] = new SingleLineRule("<?", "?>", procInstr); //$NON-NLS-1$ //$NON-NLS-2$
// Add generic whitespace rule.
rules[1] = new WhitespaceRule(new TextWhiteSpaceDetector());
setRules(rules);
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.MultiLineRule;
public class XMLTagRule extends MultiLineRule {
public XMLTagRule(IToken token) {
super("<", ">", token); //$NON-NLS-1$//$NON-NLS-2$
}
@Override
protected boolean sequenceDetected(
ICharacterScanner scanner,
char[] sequence,
boolean eofAllowed) {
int c = scanner.read();
if (sequence[0] == '<') {
if (c == '?') {
// processing instruction - abort
scanner.unread();
return false;
}
if (c == '!') {
scanner.unread();
// comment - abort
return false;
}
} else if (sequence[0] == '>') {
scanner.unread();
}
return super.sequenceDetected(scanner, sequence, eofAllowed);
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.MultiLineRule;
public class XMLTagRule extends MultiLineRule {
public XMLTagRule(IToken token) {
super("<", ">", token); //$NON-NLS-1$//$NON-NLS-2$
}
@Override
protected boolean sequenceDetected(
ICharacterScanner scanner,
char[] sequence,
boolean eofAllowed) {
int c = scanner.read();
if (sequence[0] == '<') {
if (c == '?') {
// processing instruction - abort
scanner.unread();
return false;
}
if (c == '!') {
scanner.unread();
// comment - abort
return false;
}
} else if (sequence[0] == '>') {
scanner.unread();
}
return super.sequenceDetected(scanner, sequence, eofAllowed);
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.*;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.jkiss.dbeaver.ui.editors.text.TextWhiteSpaceDetector;
public class XMLTagScanner extends RuleBasedScanner {
public XMLTagScanner(ISharedTextColors manager) {
IToken string =
new Token(
new TextAttribute(manager.getColor(XMLSourceViewerConfiguration.COLOR_STRING)));
IRule[] rules = new IRule[3];
// Add rule for double quotes
rules[0] = new SingleLineRule("\"", "\"", string, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
// Add a rule for single quotes
rules[1] = new SingleLineRule("'", "'", string, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
// Add generic whitespace rule.
rules[2] = new WhitespaceRule(new TextWhiteSpaceDetector());
setRules(rules);
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 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.ui.editors.xml;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.*;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.jkiss.dbeaver.ui.editors.text.TextWhiteSpaceDetector;
public class XMLTagScanner extends RuleBasedScanner {
public XMLTagScanner(ISharedTextColors manager) {
IToken string =
new Token(
new TextAttribute(manager.getColor(XMLSourceViewerConfiguration.COLOR_STRING)));
IRule[] rules = new IRule[3];
// Add rule for double quotes
rules[0] = new SingleLineRule("\"", "\"", string, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
// Add a rule for single quotes
rules[1] = new SingleLineRule("'", "'", string, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
// Add generic whitespace rule.
rules[2] = new WhitespaceRule(new TextWhiteSpaceDetector());
setRules(rules);
}
}
......@@ -25,9 +25,6 @@ actions_navigator_copy_fqn_title=\u041A\u043E\u043F\u0438\u0440\u043E\u0432\u043
actions_navigator_copy_fqn_titles=\u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043F\u043E\u043B\u043D\u044B\u0435 \u0438\u043C\u0435\u043D\u0430
actions_navigator_copy_object_copy_node=\u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C {0}
actions_navigator_copy_object_copy_objects=\u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043E\u0431\u044A\u0435\u043A\u0442\u044B
actions_navigator_bookmark_error_message=\u041E\u0448\u0438\u0431\u043A\u0430 \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u044F \u0437\u0430\u043A\u043B\u0430\u0434\u043A\u0438
actions_navigator_bookmark_error_title=\u041D\u043E\u0432\u0430\u044F \u0437\u0430\u043A\u043B\u0430\u0434\u043A\u0430
actions_navigator_bookmark_title=\u0418\u043C\u044F \u0437\u0430\u043A\u043B\u0430\u0434\u043A\u0438
actions_navigator_create_folder_error_message=\u041E\u0448\u0438\u0431\u043A\u0430 \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u044F \u043F\u0430\u043F\u043A\u0438 "{0}"
actions_navigator_create_folder_error_title=\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0443
actions_navigator_create_folder_folder_name=\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0443
......
......@@ -23,6 +23,7 @@
<module>org.jkiss.dbeaver.ui.editors.hex</module>
<module>org.jkiss.dbeaver.ui.editors.image</module>
<module>org.jkiss.dbeaver.ui.editors.sql</module>
<module>org.jkiss.dbeaver.ui.editors.xml</module>
<module>org.jkiss.dbeaver.ui.navigator</module>
<module>org.jkiss.dbeaver.debug.core</module>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册