Index: ../src-rep/src/lib/aqua-base/com/aquafold/library/common/utils/AQFileUtils.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../src-rep/src/lib/aqua-base/com/aquafold/library/common/utils/AQFileUtils.java (revision 57629) +++ ../src-rep/src/lib/aqua-base/com/aquafold/library/common/utils/AQFileUtils.java (revision ) @@ -1646,4 +1646,20 @@ } return path; } + + public static void editFile(File f) throws Exception { + if (f == null) { + return; + } + String path = f.getAbsolutePath(); + try { + Process proc = Runtime.getRuntime().exec(new String[]{"open", path}); + proc.waitFor(); + return; + } + catch (Exception e) { + e.printStackTrace(); + } + throw new Exception("Cannot open file: " + f); + } } Index: ../src-rep/src/lib/aqua-common/com/common/options/OptionSettings.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../src-rep/src/lib/aqua-common/com/common/options/OptionSettings.java (revision 57629) +++ ../src-rep/src/lib/aqua-common/com/common/options/OptionSettings.java (revision ) @@ -1805,6 +1805,9 @@ public static final String KEY_EXCEL_FONT_SIZE = "excel.fontsize"; public static final String KEY_EXCEL_FONT_STYLE = "excel.fontstyle"; + // Image View + public static final String KEY_IMAGE_FORMAT = "image.format"; + // AFScriptContext public static final String EXECUTE_TRIMMED_KEY = "execute.trimmed"; @@ -1941,5 +1944,4 @@ //Scheduler Execute Query public static final String SCHEDULER_EXECUTE_QUERY = "scheduler.execute.query"; - } Index: ../src-rep/src/lib/aqua-common/com/common/BaseMsg.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../src-rep/src/lib/aqua-common/com/common/BaseMsg.java (revision 57629) +++ ../src-rep/src/lib/aqua-common/com/common/BaseMsg.java (revision ) @@ -440,6 +440,7 @@ public static final String TOOLBAR_INSERTBINARY = TXT.get("DataStudioMsg.TOOLBAR_INSERTBINARY", "Insert Binary"); public static final String TOOLBAR_EDIT_IN_WINDOW = TXT.get("DataStudioMsg.TOOLBAR_EDIT_IN_WINDOW", "Edit in Window"); public static final String TOOLBAR_EDIT_JSON = TXT.get("DataStudioMsg.TOOLBAR_EDIT_JSON", "Edit JSON"); + public static final String TOOLBAR_EDIT_IMAGE = TXT.get("DataStudioMsg.TOOLBAR_EDIT_IMAGE", "Edit Image"); public static final String TOOLBAR_LOAD_CONTENT_FROM_FILE = TXT.get("DataStudioMsg.TOOLBAR_LOAD_CONTENT_FROM_FILE", "Load Content From File"); public static final String TOOLBAR_SAVE_CONTENT_TO_FILE = TXT.get("DataStudioMsg.TOOLBAR_SAVE_CONTENT_TO_FILE", "Save Content To File"); public static final String TOOLBAR_CLOSEWINDOW = TXT.get("DataStudioMsg.TOOLBAR_CLOSEWINDOW", "Close Window"); Index: ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/ImageView.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/ImageView.java (revision ) +++ ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/ImageView.java (revision ) @@ -0,0 +1,129 @@ +/* + * AQUAFOLD CONFIDENTIAL + * Unpublished Copyright (c) 2002-2020 AquaFold Incorporated, All Rights Reserved. + * + * NOTICE: All information contained herein is, and remains the property of AquaFold Incorporated. The intellectual + * and technical concepts contained herein are proprietary to AquaFold Incorporated and may be covered by U.S. + * and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this + * information or reproduction of this material is strictly forbidden unless prior written permission is obtained from + * AquaFold Incorporated. + * + * The copyright notice above does not evidence any actual or intended publication or disclosure of this source code, + * which includes information that is confidential and/or proprietary, and is a trade secret, of AquaFold Incorporated. + * ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, PUBLIC PERFORMANCE, OR PUBLIC DISPLAY OF OR + * THROUGH USE OF THIS SOURCE CODE WITHOUT THE EXPRESS WRITTEN CONSENT OF COMPANY IS + * STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL TREATIES. THE + * RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED INFORMATION DOES NOT CONVEY OR + * IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, + * OR SELL ANYTHING THAT IT MAY DESCRIBE, IN WHOLE OR IN PART. + */ + +package com.aquafold.datastudio.queryanalyzer.tableeditor; + +import java.io.File; + +import com.aquafold.library.common.utils.AQAWTUtils; +import com.aquafold.library.common.utils.AQFileUtils; +import com.common.i18n.TXT; +import com.common.log.CLog; +import com.common.options.COptionSettings; +import com.common.options.EnumOption; +import com.common.options.OptionSettings; + +/** + * Created by synerzip on 28/02/20. + */ +public class ImageView { + public static final String IMAGE_EDIT_DIRECTORY = OptionSettings.CONFIG_DIRECTORY + File.separator + "images"; + + public static void launchImageEditor(final File f) { + if (f != null) { + Runnable t = () -> { + try { + AQFileUtils.editFile(f); + } + catch (Exception e) { + CLog.log.err(e); + } + }; + AQAWTUtils.waitForEDT(t); + } + } + + public static ImageFormat getDefaultFormat() { + return ImageFormat.parse(COptionSettings.getProperty(OptionSettings.KEY_IMAGE_FORMAT)); + } + + public static File createTempImageFile(String fileName, File tempImageDirectory) throws Exception { + return new File(tempImageDirectory, fileName + getImageExtension(getDefaultFormat())); + } + + public static String getImageExtension(ImageFormat format) { + return format != null ? format.getExt() : ImageFormat.DEFAULT.getExt(); + } + + public static File getImagesDirectory() { + File directory = new File(IMAGE_EDIT_DIRECTORY); + + if (!directory.exists()) { + directory.mkdir(); + } + + return directory; + } + + /** + * Created by harishk on 30/01/20. + */ + enum ImageFormat implements EnumOption { + + GIF { + public String getProperty() { return "gif"; } + + public String toString() { return TXT.get("ImageFormat.gif", "gif"); } + + public String getExt() { return ".gif"; } + }, + PNG { + public String getProperty() { return "png"; } + + public String toString() { return TXT.get("ImageFormat.png", "png"); } + + public String getExt() { return ".png"; } + }, + JPEG { + public String getProperty() { return "jpeg"; } + + public String toString() { return TXT.get("ImageFormat.jpeg", "jpeg"); } + + public String getExt() { return ".jpeg"; } + }, + TIFF { + public String getProperty() { return "tiff"; } + + public String toString() { return TXT.get("ImageFormat.tiff", "tiff"); } + + public String getExt() { return ".tiff"; } + }; + + // intellij needs this to compile + public abstract String toString(); + + public abstract String getProperty(); + + public abstract String getExt(); + + public static final ImageFormat DEFAULT = PNG; + + public static ImageFormat parse(String s) { + for (ImageFormat f : values()) { + if (f.getProperty().equals(s)) { + return f; + } + } + return DEFAULT; + } + + } + +} Index: ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/TEMenuBar.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/TEMenuBar.java (revision 57629) +++ ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/TEMenuBar.java (revision ) @@ -72,6 +72,7 @@ public static String TE_INSERT_BINARY = "TE_INSERT_BINARY"; public static String TE_EDIT_IN_EDITOR = "TE_EDIT_IN_EDITOR"; public static String TE_EDIT_JSON_IN_EDITOR = "TE_EDIT_JSON_IN_EDITOR"; + public static String TE_EDIT_IMAGE = "TE_EDIT_IMAGE"; public static String TE_LOAD_CONTENT_FROM_FILE = "TE_LOAD_CONTENT_FROM_FILE"; public static String TE_SAVE_CONTENT_TO_FILE = "TE_SAVE_CONTENT_TO_FILE"; public static String TE_CLOSE_WINDOW = "TE_CLOSE_WINDOW"; Index: ../src-rep/src/apps/datastudio/com/aquafold/datastudio/mainframe/DataStudioFrame.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../src-rep/src/apps/datastudio/com/aquafold/datastudio/mainframe/DataStudioFrame.java (revision 57620) +++ ../src-rep/src/apps/datastudio/com/aquafold/datastudio/mainframe/DataStudioFrame.java (revision ) @@ -1993,10 +1993,10 @@ m.add(new CMenuItem(DataStudioMsg.MENU_TOOLS_EXEC_MONITOR, h, ActionHandler.TOOLS_EXEC_MONITOR)); m.add(new CMenuItem(DataStudioMsg.MENU_TOOLS_CONN_MONITOR, h, ActionHandler.TOOLS_CONN_MONITOR)); - if(AQSystemUtils.isWindows()){ + //if(AQSystemUtils.isWindows()){ m.add(new CMenuItem(DataStudioMsg.MENU_TOOLS_SCHEDULED_TASK, h, ActionHandler.TOOLS_SCHEDULED_TASK)); m.add(new CMenuItem(DataStudioMsg.MENU_TOOLS_CREATE_SCHEDULED_TASK, Elegant.get(Elegant.BI_FIELD_DATE_TIME_CONTINUOUS), h, ActionHandler.TOOLS_CREATE_SCHEDULED_TASK)); - } +// } // DBA Tools - menu items should be presented in alphabetical order CMenu dbaMenu = new CMenu(DataStudioMsg.MENU_DBA_TOOLS); Index: ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/EditorPane.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/EditorPane.java (revision 57629) +++ ../src-rep/src/apps/datastudio/com/aquafold/datastudio/queryanalyzer/tableeditor/EditorPane.java (revision ) @@ -61,6 +61,12 @@ import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.Timestamp; @@ -96,6 +102,9 @@ import com.aquafold.aquacore.open.rdbms.core.scripts.engine.AFScriptContext; import com.aquafold.aquacore.open.rdbms.core.scripts.engine.AFStmtResultColumn; import com.aquafold.aquacore.util.ConnectionThreadQueue; +import com.aquafold.components.keybindings.AppKeyBindings; +import com.aquafold.components.menu.CMenu; +import com.aquafold.components.menu.CMenuItem; import com.aquafold.datastudio.boot.AFSystem; import com.aquafold.datastudio.boot.DataStudioConfiguration; import com.aquafold.datastudio.boot.DataStudioMsg; @@ -124,7 +133,6 @@ import com.aquafold.library.common.utils.AQFileUtils; import com.aquafold.library.common.utils.AQHexUtils; import com.aquafold.library.common.utils.AQStringUtils; -import com.aquafold.library.desktop.dialog.alert.AlertUI; import com.common.StringUtils; import com.common.export.excel.ResultSettings; import com.common.export.excel.aspose.ExcelView; @@ -135,9 +143,8 @@ import com.common.options.FontSettings; import com.common.options.OptionSettings; import com.common.options.OptionSettingsDefaults; +import com.common.ui.FrameTracker; import com.common.ui.components.CFileChooser; -import com.aquafold.components.menu.CMenu; -import com.aquafold.components.menu.CMenuItem; import com.common.ui.components.CPopupMenu; import com.common.ui.components.CSplitPane; import com.common.ui.frame.CFileFilter; @@ -147,7 +154,6 @@ import com.common.ui.frame.CTabbedPane; import com.common.ui.frame.CTableScrollPane; import com.common.ui.frame.SQLFileFilter; -import com.aquafold.components.keybindings.AppKeyBindings; import com.common.ui.resource.Elegant; import com.common.ui.table.CPopupMenuController; import com.common.ui.table.ResultSetTableCustomizer; @@ -155,7 +161,10 @@ import com.common.ui.table.WrapMultiTableModel; import com.common.ui.table.renderer.CTableCellAggregator; import com.common.ui.tools.GUIDGenerator; +import com.common.ui.util.BackgroundThread; import com.common.util.JsonFormat; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorEx; import com.jidesoft.grid.JideCellEditorAdapter; @@ -239,7 +248,102 @@ protected static CLog log = CLog.get(); + private ImageEditWatcher imageEditWatcher; + class ImageEditWatcher extends BackgroundThread { + + // Temp directory for editing images + private final File tempImageDirectory; + private final WatchService watchService; + private final Table watchedFiles = HashBasedTable.create(); + + public ImageEditWatcher() throws IOException { + super("ImageEditWatcher"); + tempImageDirectory = ImageView.getImagesDirectory(); + + // setup watch for modifications + watchService = FileSystems.getDefault().newWatchService(); + Path dirPath = tempImageDirectory.toPath(); + dirPath.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY); + } + + public void launchEditor(Integer row, Integer col, byte[] binaryData) throws Exception { + Path path = watchedFiles.get(row, col); + File imageFile = null; + if (path == null) { + String id = FrameTracker.getInstance().getId(getEditorFrame()); + imageFile = ImageView.createTempImageFile(String.format("%s-row%d-col%d", id, row, col), tempImageDirectory); + imageFile.deleteOnExit(); + AQFileUtils.write(binaryData, imageFile); + watchedFiles.put(row, col, imageFile.toPath()); + } + else { + imageFile = path.toFile(); + } + ImageView.launchImageEditor(imageFile); + } + + @Override + public void process() throws Throwable { + // Write updated image data to cell + while (!isCancelled()) { + WatchKey key; + + try { + key = watchService.take(); + } + catch (InterruptedException ex) { + return; + } + + for (WatchEvent event : key.pollEvents()) { + if(isCancelled()) { + return; + } + WatchEvent.Kind kind = event.kind(); + + if (kind == StandardWatchEventKinds.OVERFLOW) { + continue; + } + + WatchEvent ev = (WatchEvent) event; + Path imageFile = ev.context(); + + for (Table.Cell cell : watchedFiles.cellSet()) { + if(isCancelled()) { + return; + } + Path watchedFile = (Path) cell.getValue(); + if (watchedFile.getFileName().equals(imageFile.getFileName())) { + AQAWTUtils.waitForEDT(new Runnable() { + @Override + public void run() { + updateTableCell(watchedFile.toFile(), (Integer) cell.getRowKey(), (Integer) cell.getColumnKey()); + } + }); + break; + } + } + } + + if (!key.reset()) { + break; + } + } + } + + @Override + public void success() { + + } + + @Override + public void error(Throwable e) { + + } + + } + public EditorPane(EditorFrame fr, ConnectionProperties connSettings, Connection conn, String[] tableNames, ResultSetTableModel resultSetTableModel, AFTable[] theTables, int maxResults, SimpleDateFormat dateFormat, DecimalFormat decFormat, DecimalFormat fracedFormat, String nullFormat, boolean bTransSupported, boolean bAllowPKDef) { this.frame = fr; this._connSettings = connSettings; @@ -2518,7 +2622,118 @@ _dataModel.showResultMessage(); } + private void editImage() { + if (_dataTable.getRowCount() == 0) { + return; + } + + String titleSaveCellValueFile = TXT.get("EditorPane.titleCellValueImageEdit", "Image Editor"); + String msg = TXT.get("EditorPane.msgSelectSingleCellForImageEdit", "You may edit image from only one cell at a time. Please repeat the operation with only one cell selected."); + + if (checkSingleCell(titleSaveCellValueFile, msg)) { + return; + } + + _showResultMessage = false; + int row = _dataTable.getSelectedRow(); + int col = _dataTable.getSelectedColumn(); + + if (row < 0 || col < 0 || col >= _dataModel.getColumnCount()) { + return; + } + + if (_dataTable.getCellEditor() != null) { + _dataTable.getCellEditor().cancelCellEditing(); + } + + if (!isBlobTypeColumn(col)) { + COptionPane.showMessageDialog(frame, TXT.get("EditorPane.msgSelectBlobTypeForImageEdit", "Image Edit only works on a cell with BLOB content type. Please repeat the operation with the appropriate cell selected."), titleSaveCellValueFile, JOptionPane.WARNING_MESSAGE); + return; + } + + Object theValue = _dataTable.getValueAt(row, col); + + if (theValue == null || (theValue instanceof AFNoValue)) { + COptionPane.showMessageDialog + ( + frame, + SELECTION_EMPTY, + titleSaveCellValueFile, + JOptionPane.WARNING_MESSAGE + ); + return; + } + + try { + // init temp image directory + if (imageEditWatcher == null) { + imageEditWatcher = new ImageEditWatcher(); + imageEditWatcher.start(); + } + boolean binaryToHex = COptionSettings.getPropertyBool(CoreOptionSettings.RESULTS_RETRIEVE_BINARY_TO_HEX, CoreOptionSettingsDefaults.RESULTS_RETRIEVE_BINARY_TO_HEX); + byte[] binaryData; + if (theValue instanceof byte[]) { + binaryData = (byte[]) theValue; + } + else if (theValue instanceof String) { + binaryData = ((String) theValue).getBytes(); + } + else { + binaryData = theValue.toString().getBytes(); + } + if (binaryToHex) { + binaryData = AQHexUtils.hexToByte(new String(binaryData)); + } + + imageEditWatcher.launchEditor(row, col, binaryData); + } + catch (Exception e) { + COptionPane.showWarning + ( + frame, + TXT.get("EditorPane.err.imageEditor.title", "Image Editor"), + TXT.get("EditorPane.err.imageEditor.text", "Selected cell is not an image document.") + ); + } + } + + private void updateTableCell(File imageFile, Integer rowIndex, Integer colIndex) { + boolean binaryToHex = COptionSettings.getPropertyBool(CoreOptionSettings.RESULTS_RETRIEVE_BINARY_TO_HEX, CoreOptionSettingsDefaults.RESULTS_RETRIEVE_BINARY_TO_HEX); + boolean hexConvertToLower = COptionSettings.getPropertyBool(CoreOptionSettings.RESULTS_RETRIEVE_HEX_CONVERT_TO_LOWER, CoreOptionSettingsDefaults.RESULTS_RETRIEVE_HEX_CONVERT_TO_LOWER); + String value = null; + try { + FileInputStream fStream = new FileInputStream(imageFile); + try { + long fLength = imageFile.length(); + byte[] readBytes = new byte[(int) fLength]; + fStream.read(readBytes); + if (!isClobTypeColumn(colIndex) && binaryToHex) { + if (hexConvertToLower) { + value = AQHexUtils.toHexStringLower(readBytes); + } + else { + value = AQHexUtils.toHexStringUpper(readBytes); + } + } + else { + value = new String(readBytes); + } + } + finally { + AQCommonUtils.close(fStream); + } + } + catch (Exception e) { + String title = TXT.get("EditorPane.titleEditImage", "Edit Image"); + String message = TXT.get("EditorPane.msgEditImage", "Failed to load image file"); + COptionPane.showMessageDialog(frame, message, title, JOptionPane.INFORMATION_MESSAGE); + return; + } + _dataModel.setValueAt(value, rowIndex, colIndex); + _dataModel.fireTableRowsUpdated(rowIndex, colIndex); + } + - private boolean isBlobTypeColumn(int viewIndex){ + private boolean isBlobTypeColumn(int viewIndex) { AFTableColumnInfo column = getColumnInfo(viewIndex); if(column._columnType == AFTableColumnInfo.BLOB || column._columnType == AFTableColumnInfo.BINARY){ return true; @@ -2705,18 +2920,18 @@ boolean binaryToHex = COptionSettings.getPropertyBool(CoreOptionSettings.RESULTS_RETRIEVE_BINARY_TO_HEX, CoreOptionSettingsDefaults.RESULTS_RETRIEVE_BINARY_TO_HEX); byte[] binaryData = null; - if (theValue instanceof byte[]) { - binaryData = (byte[]) theValue; - } - else if (theValue instanceof String) { - binaryData = ((String) theValue).getBytes(); - } - else { - binaryData = theValue.toString().getBytes(); - } - if(!isClobTypeColumn(col) && binaryToHex){ - binaryData = AQHexUtils.hexToByte(new String(binaryData)); - } + if (theValue instanceof byte[]) { + binaryData = (byte[]) theValue; + } + else if (theValue instanceof String) { + binaryData = ((String) theValue).getBytes(); + } + else { + binaryData = theValue.toString().getBytes(); + } + if(!isClobTypeColumn(col) && binaryToHex){ + binaryData = AQHexUtils.hexToByte(new String(binaryData)); + } BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file)); out.write(binaryData); @@ -2724,18 +2939,7 @@ Properties props = AFSystem.getInstance().getUIProperties(); props.setProperty(OptionSettings.EXPORTRESULTS_RESULTSLASTDIRECTORY, file.getParent()); AFSystem.getInstance().setUIProperties(); - - final String doNotShowPropKey = "EditorPane.save.contentToFile.showFilePath"; //NOI18N - - String title = TXT.get("EditorPane.save.contentToFile.title", "Save Content to File"); - String message = TXT.get("EditorPane.save.contentToFile.message", "The content saved to the file successfully."); - - boolean show = AlertUI.showFilePathWithDoNotShow(frame, title, message, doNotShowPropKey); - if (show) { - File parentDirectory = file.getParentFile(); - AQFileUtils.showFilePath(parentDirectory, file); - } + } - } catch (Exception e) { log.err(e); COptionPane.showMessageDialog @@ -2745,8 +2949,10 @@ titleSaveCellValueFile, JOptionPane.WARNING_MESSAGE ); + return; } } + return; } private String getFileReadOnlyMsg(String path) { @@ -2763,6 +2969,13 @@ } private void cleanup() { + if(imageEditWatcher != null) { + try { + imageEditWatcher.cancel(); + } catch (Exception e) { + // ignore + } + } if (_theSQLPreviewGrid != null) { _theSQLPreviewGrid.cannibalizeMemory(); } @@ -3298,6 +3511,9 @@ else if (command.equals(TEMenuBar.TE_EDIT_JSON_IN_EDITOR)) { editJsonInEditor(); } + else if (command.equals(TEMenuBar.TE_EDIT_IMAGE)) { + editImage(); + } else if (command.equals(TEMenuBar.TE_LOAD_CONTENT_FROM_FILE)) { loadContentFromFile(); } @@ -3505,6 +3721,7 @@ _popupGridMenu.add(new CMenuItem(DataStudioMsg.TOOLBAR_EDIT_JSON, Elegant.get(Elegant.DATAEDITOR_EDIT_IN_WINDOW), this, TEMenuBar.TE_EDIT_JSON_IN_EDITOR)); if(_connSettings.isOracle() || _connSettings.isMssql() || _connSettings.isDB2()){ + _popupGridMenu.add(new CMenuItem(DataStudioMsg.TOOLBAR_EDIT_IMAGE, Elegant.get(Elegant.DATAEDITOR_EDIT_IN_WINDOW), this, TEMenuBar.TE_EDIT_IMAGE)); _popupGridMenu.addSeparator(); _popupGridMenu.add(new CMenuItem(DataStudioMsg.TOOLBAR_LOAD_CONTENT_FROM_FILE, Elegant.get(Elegant.DATAEDITOR_EDIT_IN_WINDOW), this, TEMenuBar.TE_LOAD_CONTENT_FROM_FILE)); _popupGridMenu.add(new CMenuItem(DataStudioMsg.TOOLBAR_SAVE_CONTENT_TO_FILE, Elegant.get(Elegant.DATAEDITOR_EDIT_IN_WINDOW), this, TEMenuBar.TE_SAVE_CONTENT_TO_FILE));