diff --git a/README.md b/README.md index 26d27e3..ac3ca1d 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Java Development Kit (JDK) version 11 or later is required to build this project IntelliJ Idea platform is necessary to build this plugin. See. http://jetbrains.org -Assign SDK using 2022.2.1 IntelliJ platform / add and use "Plugin" run configuration to execute. +Assign SDK using 2022.2.1 IntelliJ platform / add and use "Other/Plugin" run configuration to execute. License ------- diff --git a/build.gradle.kts b/build.gradle.kts index 5c8574a..d544b9e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "org.exbin.deltahex.intellij" -version = "0.2.8-SNAPSHOT" +version = "0.2.8" val ideLocalPath = providers.gradleProperty("ideLocalPath").getOrElse("") repositories { diff --git a/changes.txt b/changes.txt index 893af66..ea34bb4 100644 --- a/changes.txt +++ b/changes.txt @@ -1,4 +1,4 @@ -0.2.8 +0.2.8 (2023-05-19) - Added edit as binary action for columns in database view - Added byte-to-byte compare diff option - Added integration options page diff --git a/lib/bined-core-0.2.1-SNAPSHOT.jar b/lib/bined-core-0.2.1-SNAPSHOT.jar index 587aec2..1e9ad05 100644 Binary files a/lib/bined-core-0.2.1-SNAPSHOT.jar and b/lib/bined-core-0.2.1-SNAPSHOT.jar differ diff --git a/lib/bined-extended-0.2.1-SNAPSHOT.jar b/lib/bined-extended-0.2.1-SNAPSHOT.jar index 49bca8c..349c08f 100644 Binary files a/lib/bined-extended-0.2.1-SNAPSHOT.jar and b/lib/bined-extended-0.2.1-SNAPSHOT.jar differ diff --git a/lib/bined-highlight-swing-0.2.1-SNAPSHOT.jar b/lib/bined-highlight-swing-0.2.1-SNAPSHOT.jar index d3a6bcc..1fc3135 100644 Binary files a/lib/bined-highlight-swing-0.2.1-SNAPSHOT.jar and b/lib/bined-highlight-swing-0.2.1-SNAPSHOT.jar differ diff --git a/lib/bined-operation-0.2.1-SNAPSHOT.jar b/lib/bined-operation-0.2.1-SNAPSHOT.jar index 0b7c8e9..b8b3f96 100644 Binary files a/lib/bined-operation-0.2.1-SNAPSHOT.jar and b/lib/bined-operation-0.2.1-SNAPSHOT.jar differ diff --git a/lib/bined-operation-swing-0.2.1-SNAPSHOT.jar b/lib/bined-operation-swing-0.2.1-SNAPSHOT.jar index 01070d5..7050523 100644 Binary files a/lib/bined-operation-swing-0.2.1-SNAPSHOT.jar and b/lib/bined-operation-swing-0.2.1-SNAPSHOT.jar differ diff --git a/lib/bined-swing-0.2.1-SNAPSHOT.jar b/lib/bined-swing-0.2.1-SNAPSHOT.jar index ca87410..e6dff40 100644 Binary files a/lib/bined-swing-0.2.1-SNAPSHOT.jar and b/lib/bined-swing-0.2.1-SNAPSHOT.jar differ diff --git a/lib/bined-swing-extended-0.2.1-SNAPSHOT.jar b/lib/bined-swing-extended-0.2.1-SNAPSHOT.jar index d0af0cf..2f88c28 100644 Binary files a/lib/bined-swing-extended-0.2.1-SNAPSHOT.jar and b/lib/bined-swing-extended-0.2.1-SNAPSHOT.jar differ diff --git a/lib/jetbrains/database-plugin-2022.2.1.jar b/lib/jetbrains/database-plugin-2022.2.1.jar index 3844d5c..424fcfb 100644 Binary files a/lib/jetbrains/database-plugin-2022.2.1.jar and b/lib/jetbrains/database-plugin-2022.2.1.jar differ diff --git a/lib/paged_data-0.2.1-SNAPSHOT.jar b/lib/paged_data-0.2.1-SNAPSHOT.jar index 2da81d2..e7363ed 100644 Binary files a/lib/paged_data-0.2.1-SNAPSHOT.jar and b/lib/paged_data-0.2.1-SNAPSHOT.jar differ diff --git a/lib/paged_data-delta-0.2.1-SNAPSHOT.jar b/lib/paged_data-delta-0.2.1-SNAPSHOT.jar index 681b19c..6a75e38 100644 Binary files a/lib/paged_data-delta-0.2.1-SNAPSHOT.jar and b/lib/paged_data-delta-0.2.1-SNAPSHOT.jar differ diff --git a/src/main/java/org/exbin/bined/intellij/BinEdDiffTool.java b/src/main/java/org/exbin/bined/intellij/BinEdDiffTool.java deleted file mode 100644 index 341497b..0000000 --- a/src/main/java/org/exbin/bined/intellij/BinEdDiffTool.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) ExBin Project - * - * 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 - * - * https://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.exbin.bined.intellij; - -import com.intellij.diff.DiffContext; -import com.intellij.diff.FrameDiffTool; -import com.intellij.diff.requests.ContentDiffRequest; -import com.intellij.diff.requests.DiffRequest; -import com.intellij.diff.tools.util.base.DiffViewerBase; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.vfs.VirtualFile; -import org.exbin.bined.intellij.action.SearchAction; -import org.exbin.bined.swing.extended.ExtCodeArea; -import org.exbin.bined.swing.extended.diff.ExtCodeAreaDiffPanel; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.Nullable; - -import javax.annotation.Nonnull; -import javax.annotation.ParametersAreNonnullByDefault; -import javax.swing.JComponent; -import java.util.List; - -/** - * BinEd diff support provider to compare binary files. - * - * @author ExBin Project (https://exbin.org) - */ -@ParametersAreNonnullByDefault -public class BinEdDiffTool implements FrameDiffTool, DumbAware { - - private boolean actionVisible = true; - - public BinEdDiffTool() { - BinEdPluginStartupActivity.addIntegrationOptionsListener(integrationOptions -> actionVisible = integrationOptions.isRegisterByteToByteDiffTool()); - } - - @Nonnull - @Nls(capitalization = Nls.Capitalization.Sentence) - @Override - public String getName() { - return "Byte-to-byte compare (BinEd plugin)"; - } - - @Override - public boolean canShow(DiffContext context, DiffRequest request) { - return actionVisible; - } - - @Nonnull - @Override - public DiffViewer createComponent(DiffContext context, DiffRequest request) { - return new DiffViewerBase(context, (ContentDiffRequest) request) { - @Nonnull - @Override - protected Runnable performRediff(ProgressIndicator indicator) { - return () -> { - // no activity - }; - } - - @Nonnull - @Override - public JComponent getComponent() { - final ExtCodeAreaDiffPanel diffPanel = new ExtCodeAreaDiffPanel(); - List filesToRefresh = request.getFilesToRefresh(); - VirtualFile virtualFile = filesToRefresh.get(0); - diffPanel.setLeftContentData(new BinEdFileDataWrapper(virtualFile)); - ExtCodeArea leftCodeArea = diffPanel.getLeftCodeArea(); - leftCodeArea.setComponentPopupMenu(SearchAction.createCodeAreaPopupMenu(leftCodeArea, "left")); - if (filesToRefresh.size() > 1) { - VirtualFile secondFile = filesToRefresh.get(1); - diffPanel.setRightContentData(new BinEdFileDataWrapper(secondFile)); - } - ExtCodeArea rightCodeArea = diffPanel.getRightCodeArea(); - rightCodeArea.setComponentPopupMenu(SearchAction.createCodeAreaPopupMenu(rightCodeArea, "right")); - - return diffPanel; - } - - @Nullable - @Override - public JComponent getPreferredFocusedComponent() { - return null; - } - }; - } -} diff --git a/src/main/java/org/exbin/bined/intellij/BinEdFileListener.java b/src/main/java/org/exbin/bined/intellij/BinEdFileListener.java deleted file mode 100644 index 57ef5d9..0000000 --- a/src/main/java/org/exbin/bined/intellij/BinEdFileListener.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) ExBin Project - * - * 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 - * - * https://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.exbin.bined.intellij; - -import com.intellij.openapi.vfs.VirtualFileEvent; -import com.intellij.openapi.vfs.VirtualFileListener; - -import javax.annotation.ParametersAreNonnullByDefault; -import javax.swing.*; - -/** - * File listener for hexadecimal editor. - * - * @author ExBin Project (https://exbin.org) - */ -@ParametersAreNonnullByDefault -public class BinEdFileListener implements VirtualFileListener { - - private JPanel editor; - - public BinEdFileListener(JPanel viewer) { - this.editor = viewer; - } - - public void contentsChanged(VirtualFileEvent event) { - // if (event.getFile().equals(this.editor.getCanvas().getFile())) { - // this.editor.getCanvas().showSelectedFile(); - // } - } -} diff --git a/src/main/java/org/exbin/bined/intellij/BinEdPluginStartupActivity.java b/src/main/java/org/exbin/bined/intellij/BinEdPluginStartupActivity.java index 233edc4..0aa6442 100644 --- a/src/main/java/org/exbin/bined/intellij/BinEdPluginStartupActivity.java +++ b/src/main/java/org/exbin/bined/intellij/BinEdPluginStartupActivity.java @@ -18,11 +18,17 @@ import com.intellij.openapi.extensions.ExtensionPointAdapter; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.PluginDescriptor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.startup.StartupActivity; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.components.BorderLayoutPanel; import org.exbin.auxiliary.paged_data.BinaryData; @@ -34,6 +40,7 @@ import org.exbin.bined.intellij.gui.BinEdComponentPanel; import org.exbin.bined.intellij.options.IntegrationOptions; import org.exbin.bined.intellij.preferences.IntegrationPreferences; +import org.exbin.framework.bined.BinEdFileHandler; import org.exbin.framework.bined.FileHandlingMode; import javax.annotation.Nonnull; @@ -66,16 +73,20 @@ public final class BinEdPluginStartupActivity implements StartupActivity, DumbAw @Override public void runActivity(Project project) { - ProjectManager.getInstance().addProjectManagerListener(new BinEdVetoableProjectListener()); + if (initialIntegrationOptions == null) { + ProjectManager.getInstance().addProjectManagerListener(new BinEdVetoableProjectListener()); - BINED_VIEW_DATA.addExtensionPointListener(new ExtensionPointAdapter<>() { - @Override - public void extensionListChanged() { - initExtensions(); - } - }, null); - initExtensions(); - initIntegration(); + BINED_VIEW_DATA.addExtensionPointListener(new ExtensionPointAdapter<>() { + @Override + public void extensionListChanged() { + initExtensions(); + } + }, null); + initExtensions(); + initIntegration(); + } + + projectOpened(project); } private void initExtensions() { @@ -88,13 +99,33 @@ private void initExtensions() { }); } - private void initIntegration() { + private static void initIntegration() { initialIntegrationOptions = new IntegrationPreferences( new IntelliJPreferencesWrapper(BinEdComponentPanel.getPreferences(), BinEdIntelliJPlugin.PLUGIN_PREFIX) ); applyIntegrationOptions(initialIntegrationOptions); } + private static void projectOpened(Project project) { + MessageBus messageBus = project.getMessageBus(); + MessageBusConnection connect = messageBus.connect(); + connect.subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, new FileEditorManagerListener.Before() { + @Override + public void beforeFileClosed(@Nonnull FileEditorManager source, @Nonnull VirtualFile file) { + if (file instanceof BinEdVirtualFile && !((BinEdVirtualFile) file).isMoved() + && !((BinEdVirtualFile) file).isClosing()) { + ((BinEdVirtualFile) file).setClosing(true); + BinEdFileHandler editorPanel = ((BinEdVirtualFile) file).getEditorFile(); + if (!editorPanel.releaseFile()) { + ((BinEdVirtualFile) file).setClosing(false); + throw new ProcessCanceledException(); + } + ((BinEdVirtualFile) file).setClosing(false); + } + } + }); + } + public static void addIntegrationOptionsListener(IntegrationOptionsListener integrationOptionsListener) { INTEGRATION_OPTIONS_LISTENERS.add(integrationOptionsListener); if (initialIntegrationOptions != null) { diff --git a/src/main/java/org/exbin/bined/intellij/BinEdProjectListener.java b/src/main/java/org/exbin/bined/intellij/BinEdProjectListener.java deleted file mode 100644 index 8a0253a..0000000 --- a/src/main/java/org/exbin/bined/intellij/BinEdProjectListener.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) ExBin Project - * - * 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 - * - * https://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.exbin.bined.intellij; - -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.FileEditorManagerListener; -import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.messages.MessageBus; -import com.intellij.util.messages.MessageBusConnection; -import org.exbin.framework.bined.BinEdFileHandler; - -import javax.annotation.Nonnull; -import javax.annotation.ParametersAreNonnullByDefault; - -/** - * Project listener for BinEd plugin. - * - * @author ExBin Project (https://exbin.org) - */ -@ParametersAreNonnullByDefault -public class BinEdProjectListener implements ProjectManagerListener { - - @Override - public void projectOpened(Project project) { - MessageBus messageBus = project.getMessageBus(); - MessageBusConnection connect = messageBus.connect(); - connect.subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, new FileEditorManagerListener.Before() { - @Override - public void beforeFileClosed(@Nonnull FileEditorManager source, @Nonnull VirtualFile file) { - if (file instanceof BinEdVirtualFile && !((BinEdVirtualFile) file).isMoved() - && !((BinEdVirtualFile) file).isClosing()) { - ((BinEdVirtualFile) file).setClosing(true); - BinEdFileHandler editorPanel = ((BinEdVirtualFile) file).getEditorFile(); - if (!editorPanel.releaseFile()) { - ((BinEdVirtualFile) file).setClosing(false); - throw new ProcessCanceledException(); - } - ((BinEdVirtualFile) file).setClosing(false); - } - } - }); - } -} diff --git a/src/main/java/org/exbin/bined/intellij/action/SearchAction.java b/src/main/java/org/exbin/bined/intellij/action/SearchAction.java index 21cd9cc..46ff531 100644 --- a/src/main/java/org/exbin/bined/intellij/action/SearchAction.java +++ b/src/main/java/org/exbin/bined/intellij/action/SearchAction.java @@ -341,7 +341,7 @@ public void actionPerformed(ActionEvent e) { @Override public boolean isEnabled() { - return codeArea.hasSelection(); + return codeArea.isEditable() && codeArea.hasSelection(); } }); cutMenuItem.setText("Cut"); @@ -369,7 +369,7 @@ public void actionPerformed(ActionEvent e) { @Override public boolean isEnabled() { - return codeArea.canPaste(); + return codeArea.isEditable() && codeArea.canPaste(); } }); pasteMenuItem.setText("Paste"); @@ -383,7 +383,7 @@ public void actionPerformed(ActionEvent e) { @Override public boolean isEnabled() { - return codeArea.hasSelection(); + return codeArea.isEditable() && codeArea.hasSelection(); } }); deleteMenuItem.setText("Delete"); diff --git a/src/main/java/org/exbin/bined/intellij/database/DbEditBinaryAction.java b/src/main/java/org/exbin/bined/intellij/database/DbEditBinaryAction.java index 94500fa..0dba772 100644 --- a/src/main/java/org/exbin/bined/intellij/database/DbEditBinaryAction.java +++ b/src/main/java/org/exbin/bined/intellij/database/DbEditBinaryAction.java @@ -21,10 +21,10 @@ import com.intellij.database.datagrid.GridModel; import com.intellij.database.datagrid.GridRow; import com.intellij.database.datagrid.SelectionModel; +import com.intellij.database.extractors.ExtractorsUtil; import com.intellij.database.extractors.TextInfo; import com.intellij.database.run.actions.GridAction; import com.intellij.database.run.ui.DataAccessType; -import com.intellij.database.run.ui.grid.editors.CoreGridCellEditorHelper; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; @@ -35,6 +35,7 @@ import com.intellij.util.ui.JBUI; import com.intellij.util.ui.components.BorderLayoutPanel; import org.exbin.auxiliary.paged_data.BinaryData; +import org.exbin.auxiliary.paged_data.ByteArrayData; import org.exbin.auxiliary.paged_data.ByteArrayEditableData; import org.exbin.auxiliary.paged_data.EditableBinaryData; import org.exbin.bined.EditMode; @@ -62,7 +63,7 @@ public class DbEditBinaryAction extends AnAction implements DumbAware, GridAction { private boolean actionVisible = true; - private ObjectValueConvertor objectValueConvertor = new ObjectValueConvertor(); + private final ObjectValueConvertor objectValueConvertor = new ObjectValueConvertor(); public DbEditBinaryAction() { BinEdPluginStartupActivity.addIntegrationOptionsListener(integrationOptions -> actionVisible = @@ -78,22 +79,28 @@ public void actionPerformed(AnActionEvent event) { GridRow row = Objects.requireNonNull(dataModel.getRow(selectionModel.getSelectedRow())); Object value = column.getValue(row); - // TODO detect BLOB types somehow? column.getType() -// switch (CoreGridCellEditorHelper.get(grid).guessJdbcTypeForEditing(grid, row, column)) { -// case -4: -// case -3: -// case -2: -// case 2004: -// return 1; -// default: -// return 0; -// } + boolean isBlobType; + // CoreGridCellEditorHelper.get(grid).guessJdbcTypeForEditing() is obsolete + switch (ExtractorsUtil.guessJdbcType(column, + dataModel.getValueAt(selectionModel.getSelectedRow(), selectionModel.getSelectedColumn()), + DataGridUtil.getDbms(grid))) { + case -4: + case -3: + case -2: + case 2004: + isBlobType = true; + break; + default: + isBlobType = false; + } BinaryData binaryData; - if (value instanceof byte[] || value == null) { - binaryData = value == null ? new ByteArrayEditableData() : new ByteArrayEditableData((byte[]) value); + if (value instanceof byte[]) { + binaryData = new ByteArrayEditableData((byte[]) value); } else if (value instanceof TextInfo) { binaryData = new ByteArrayEditableData(((TextInfo) value).bytes); + } else if (value == null) { + binaryData = isBlobType ? new ByteArrayEditableData() : new ByteArrayData(); } else { binaryData = objectValueConvertor.process(value).orElse(null); } @@ -131,14 +138,16 @@ private static class DataDialog extends DialogWrapper { private final BinEdComponentPanel viewPanel; private final DataGrid grid; + private final boolean editable; private DataDialog(Project project, DataGrid grid, @Nullable BinaryData binaryData) { super(project, false); this.grid = grid; + editable = binaryData instanceof EditableBinaryData; + setModal(false); setCancelButtonText("Close"); setOKButtonText("Set"); - boolean editable = binaryData instanceof EditableBinaryData; setOKActionEnabled(editable); setCrossClosesWindow(true); @@ -156,7 +165,7 @@ public void saveDocument() { @Override public void switchFileHandlingMode(FileHandlingMode newHandlingMode) { - throw new IllegalStateException("Save not supported"); + // Ignore } @Override @@ -197,7 +206,11 @@ protected void doOKAction() { @Nonnull @Override protected Action[] createActions() { - return new Action[] { getOKAction(), getCancelAction() }; + if (editable) { + return new Action[] { getOKAction(), getCancelAction() }; + } + + return new Action[] { getCancelAction() }; } @Nullable diff --git a/src/main/java/org/exbin/bined/intellij/diff/BinEdDiffTool.java b/src/main/java/org/exbin/bined/intellij/diff/BinEdDiffTool.java new file mode 100644 index 0000000..6d7b18b --- /dev/null +++ b/src/main/java/org/exbin/bined/intellij/diff/BinEdDiffTool.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) ExBin Project + * + * 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 + * + * https://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.exbin.bined.intellij.diff; + +import com.intellij.diff.DiffContext; +import com.intellij.diff.FrameDiffTool; +import com.intellij.diff.requests.ContentDiffRequest; +import com.intellij.diff.requests.DiffRequest; +import com.intellij.openapi.project.DumbAware; +import org.exbin.bined.intellij.BinEdPluginStartupActivity; +import org.jetbrains.annotations.Nls; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * BinEd diff support provider to compare binary files. + * + * @author ExBin Project (https://exbin.org) + */ +@ParametersAreNonnullByDefault +public class BinEdDiffTool implements FrameDiffTool, DumbAware { + + private boolean actionVisible = true; + + public BinEdDiffTool() { + BinEdPluginStartupActivity.addIntegrationOptionsListener( + integrationOptions -> actionVisible = integrationOptions.isRegisterByteToByteDiffTool() + ); + } + + @Nonnull + @Nls(capitalization = Nls.Capitalization.Sentence) + @Override + public String getName() { + return "Byte-to-byte compare (BinEd plugin)"; + } + + @Override + public boolean canShow(DiffContext context, DiffRequest request) { + return actionVisible && request instanceof ContentDiffRequest; + } + + @Nonnull + @Override + public DiffViewer createComponent(DiffContext context, DiffRequest request) { + return new BinEdDiffViewer(context, (ContentDiffRequest) request); + } +} diff --git a/src/main/java/org/exbin/bined/intellij/diff/BinEdDiffViewer.java b/src/main/java/org/exbin/bined/intellij/diff/BinEdDiffViewer.java new file mode 100644 index 0000000..8ccd6ef --- /dev/null +++ b/src/main/java/org/exbin/bined/intellij/diff/BinEdDiffViewer.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) ExBin Project + * + * 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 + * + * https://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.exbin.bined.intellij.diff; + +import com.intellij.diff.DiffContext; +import com.intellij.diff.requests.ContentDiffRequest; +import com.intellij.diff.tools.util.base.DiffViewerBase; +import com.intellij.openapi.progress.ProgressIndicator; +import org.exbin.bined.intellij.diff.gui.BinedDiffPanel; +import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; +import javax.swing.JComponent; + +/** + * BinEd diff support provider to compare binary files. + * + * @author ExBin Project (https://exbin.org) + */ +@ParametersAreNonnullByDefault +public class BinEdDiffViewer extends DiffViewerBase { + + private final BinedDiffPanel diffPanel = new BinedDiffPanel(); + + public BinEdDiffViewer(DiffContext context, ContentDiffRequest request) { + super(context, request); + + } + + @Nonnull + @Override + protected Runnable performRediff(ProgressIndicator indicator) { + return () -> { + // no activity + }; + } + + @Nonnull + @Override + public JComponent getComponent() { + diffPanel.setDiffContent(myRequest); + return diffPanel; + } + + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return diffPanel; + } +} diff --git a/src/main/java/org/exbin/bined/intellij/diff/gui/BinedDiffPanel.java b/src/main/java/org/exbin/bined/intellij/diff/gui/BinedDiffPanel.java new file mode 100644 index 0000000..7f521b2 --- /dev/null +++ b/src/main/java/org/exbin/bined/intellij/diff/gui/BinedDiffPanel.java @@ -0,0 +1,528 @@ +/* + * Copyright (C) ExBin Project + * + * 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 + * + * https://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.exbin.bined.intellij.diff.gui; + +import com.intellij.diff.requests.ContentDiffRequest; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.components.JBPanel; +import org.exbin.bined.CodeAreaCaretPosition; +import org.exbin.bined.CodeType; +import org.exbin.bined.EditMode; +import org.exbin.bined.EditOperation; +import org.exbin.bined.capability.CharsetCapable; +import org.exbin.bined.extended.layout.ExtendedCodeAreaLayoutProfile; +import org.exbin.bined.intellij.BinEdApplyOptions; +import org.exbin.bined.intellij.BinEdFileDataWrapper; +import org.exbin.bined.intellij.BinEdIntelliJPlugin; +import org.exbin.bined.intellij.BinEdPluginStartupActivity; +import org.exbin.bined.intellij.IntelliJPreferencesWrapper; +import org.exbin.bined.intellij.action.SearchAction; +import org.exbin.bined.intellij.gui.BinEdComponentPanel; +import org.exbin.bined.intellij.gui.BinEdOptionsPanel; +import org.exbin.bined.intellij.gui.BinEdOptionsPanelBorder; +import org.exbin.bined.intellij.gui.BinEdToolbarPanel; +import org.exbin.bined.intellij.options.IntegrationOptions; +import org.exbin.bined.operation.swing.CodeAreaOperationCommandHandler; +import org.exbin.bined.swing.basic.color.CodeAreaColorsProfile; +import org.exbin.bined.swing.capability.FontCapable; +import org.exbin.bined.swing.extended.ExtCodeArea; +import org.exbin.bined.swing.extended.diff.ExtCodeAreaDiffPanel; +import org.exbin.bined.swing.extended.theme.ExtendedCodeAreaThemeProfile; +import org.exbin.framework.bined.BinaryStatusApi; +import org.exbin.framework.bined.gui.BinaryStatusPanel; +import org.exbin.framework.bined.options.CodeAreaColorOptions; +import org.exbin.framework.bined.options.CodeAreaLayoutOptions; +import org.exbin.framework.bined.options.CodeAreaOptions; +import org.exbin.framework.bined.options.CodeAreaThemeOptions; +import org.exbin.framework.bined.options.EditorOptions; +import org.exbin.framework.bined.options.StatusOptions; +import org.exbin.framework.bined.options.impl.CodeAreaOptionsImpl; +import org.exbin.framework.bined.preferences.BinaryEditorPreferences; +import org.exbin.framework.editor.text.EncodingsHandler; +import org.exbin.framework.editor.text.TextEncodingStatusApi; +import org.exbin.framework.editor.text.options.TextEncodingOptions; +import org.exbin.framework.editor.text.options.TextFontOptions; +import org.exbin.framework.editor.text.service.TextFontService; +import org.exbin.framework.utils.DesktopUtils; +import org.exbin.framework.utils.WindowUtils; +import org.exbin.framework.utils.gui.OptionsControlPanel; +import org.exbin.framework.utils.handler.OptionsControlHandler; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JViewport; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseEvent; +import java.nio.charset.Charset; +import java.util.List; + +/** + * BinEd diff support provider to compare binary files. + * + * @author ExBin Project (https://exbin.org) + */ +@ParametersAreNonnullByDefault +public class BinedDiffPanel extends JBPanel { + + private static final String ONLINE_HELP_URL = "https://bined.exbin.org/intellij-plugin/?manual"; + + private final BinaryEditorPreferences preferences; + private final ExtCodeAreaDiffPanel diffPanel = new ExtCodeAreaDiffPanel(); + + private final Font defaultFont; + private final ExtendedCodeAreaLayoutProfile defaultLayoutProfile; + private final ExtendedCodeAreaThemeProfile defaultThemeProfile; + private final CodeAreaColorsProfile defaultColorProfile; + + private final BinEdToolbarPanel toolbarPanel; + private final BinaryStatusPanel statusPanel; + private EncodingsHandler encodingsHandler; + private BinaryStatusApi binaryStatus; + private TextEncodingStatusApi encodingStatus; + private BinEdComponentPanel.CharsetChangeListener charsetChangeListener = null; + + public BinedDiffPanel() { + setLayout(new java.awt.BorderLayout()); + + preferences = new BinaryEditorPreferences(new IntelliJPreferencesWrapper(getPreferences(), + BinEdIntelliJPlugin.PLUGIN_PREFIX)); + defaultFont = new Font(Font.MONOSPACED, Font.PLAIN, 12); + ExtCodeArea leftCodeArea = diffPanel.getLeftCodeArea(); + ExtCodeArea rightCodeArea = diffPanel.getRightCodeArea(); + defaultLayoutProfile = leftCodeArea.getLayoutProfile(); + defaultThemeProfile = leftCodeArea.getThemeProfile(); + defaultColorProfile = leftCodeArea.getColorsProfile(); + toolbarPanel = new BinEdToolbarPanel(preferences, diffPanel, + new BinEdToolbarPanel.Control() { + @Nonnull + @Override public CodeType getCodeType() { + return leftCodeArea.getCodeType(); + } + + @Override + public void setCodeType(CodeType codeType) { + leftCodeArea.setCodeType(codeType); + rightCodeArea.setCodeType(codeType); + } + + @Override + public boolean isShowUnprintables() { + return leftCodeArea.isShowUnprintables(); + } + + @Override + public void setShowUnprintables(boolean showUnprintables) { + leftCodeArea.setShowUnprintables(showUnprintables); + rightCodeArea.setShowUnprintables(showUnprintables); + } + + @Override + public void repaint() { + diffPanel.repaint(); + } + }, + new AnAction() { + @Override + public void actionPerformed(@Nonnull AnActionEvent anActionEvent) { + createOptionsAction().actionPerformed(new ActionEvent(BinedDiffPanel.this, 0, "COMMAND", 0)); + } + }, + new AnAction() { + @Override + public void actionPerformed(@Nonnull AnActionEvent anActionEvent) { + createOnlineHelpAction().actionPerformed(new ActionEvent(BinedDiffPanel.this, 0, "COMMAND", 0)); + } + } + ); + statusPanel = new BinaryStatusPanel(); + + init(); + } + + private void init() { + this.add(toolbarPanel, BorderLayout.NORTH); + registerEncodingStatus(statusPanel); + encodingsHandler = new EncodingsHandler(); + encodingsHandler.setParentComponent(this); + encodingsHandler.init(); + encodingsHandler.setTextEncodingStatus(new TextEncodingStatusApi() { + @Nonnull + @Override + public String getEncoding() { + return encodingStatus.getEncoding(); + } + + @Override + public void setEncoding(String encodingName) { + diffPanel.getLeftCodeArea().setCharset(Charset.forName(encodingName)); + diffPanel.getRightCodeArea().setCharset(Charset.forName(encodingName)); + encodingStatus.setEncoding(encodingName); + preferences.getEncodingPreferences().setSelectedEncoding(encodingName); + charsetChangeListener.charsetChanged(); + } + }); + + registerBinaryStatus(statusPanel); + + initialLoadFromPreferences(); + + this.add(statusPanel, BorderLayout.SOUTH); + this.add(diffPanel, BorderLayout.CENTER); + } + + public void setDiffContent(ContentDiffRequest request) { + List filesToRefresh = request.getFilesToRefresh(); + VirtualFile virtualFile = filesToRefresh.get(0); + diffPanel.setLeftContentData(new BinEdFileDataWrapper(virtualFile)); + ExtCodeArea leftCodeArea = diffPanel.getLeftCodeArea(); + leftCodeArea.setComponentPopupMenu(new JPopupMenu() { + @Override + public void show(Component invoker, int x, int y) { + JPopupMenu popupMenu = SearchAction.createCodeAreaPopupMenu(leftCodeArea, "left"); + popupMenu.show(invoker, x, y); + } + }); + if (filesToRefresh.size() > 1) { + VirtualFile secondFile = filesToRefresh.get(1); + diffPanel.setRightContentData(new BinEdFileDataWrapper(secondFile)); + } + ExtCodeArea rightCodeArea = diffPanel.getRightCodeArea(); + rightCodeArea.setComponentPopupMenu(new JPopupMenu() { + @Override + public void show(Component invoker, int x, int y) { + JPopupMenu popupMenu = SearchAction.createCodeAreaPopupMenu(rightCodeArea, "right"); + popupMenu.show(invoker, x, y); + } + }); + } + + public void registerBinaryStatus(BinaryStatusApi binaryStatusApi) { + this.binaryStatus = binaryStatusApi; + ExtCodeArea leftCodeArea = diffPanel.getLeftCodeArea(); + ExtCodeArea rightCodeArea = diffPanel.getRightCodeArea(); + leftCodeArea.addCaretMovedListener((CodeAreaCaretPosition caretPosition) -> { + binaryStatus.setCursorPosition(caretPosition); + }); + rightCodeArea.addCaretMovedListener((CodeAreaCaretPosition caretPosition) -> { + binaryStatus.setCursorPosition(caretPosition); + }); + leftCodeArea.addSelectionChangedListener(() -> { + binaryStatus.setSelectionRange(leftCodeArea.getSelection()); + }); + rightCodeArea.addSelectionChangedListener(() -> { + binaryStatus.setSelectionRange(rightCodeArea.getSelection()); + }); + + leftCodeArea.addEditModeChangedListener(binaryStatus::setEditMode); + rightCodeArea.addEditModeChangedListener(binaryStatus::setEditMode); + + leftCodeArea.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + updateBinaryStatus(leftCodeArea); + } + }); + rightCodeArea.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + updateBinaryStatus(rightCodeArea); + } + }); + + updateBinaryStatus(leftCodeArea); + + ((BinaryStatusPanel) binaryStatus).setStatusControlHandler(new BinaryStatusPanel.StatusControlHandler() { + @Override + public void changeEditOperation(EditOperation editOperation) { + leftCodeArea.setEditOperation(editOperation); + rightCodeArea.setEditOperation(editOperation); + } + + @Override + public void changeCursorPosition() { + // TODO goToPositionAction.actionPerformed(new ActionEvent(BinedDiffPanel.this, 0, "")); + } + + @Override + public void cycleEncodings() { + if (encodingsHandler != null) { + encodingsHandler.cycleEncodings(); + } + } + + @Override + public void encodingsPopupEncodingsMenu(MouseEvent mouseEvent) { + if (encodingsHandler != null) { + encodingsHandler.popupEncodingsMenu(mouseEvent); + } + } + + @Override + public void changeMemoryMode(BinaryStatusApi.MemoryMode memoryMode) { + // Ignore + } + }); + } + + private void updateBinaryStatus(ExtCodeArea codeArea) { + binaryStatus.setEditMode(codeArea.getEditMode(), codeArea.getActiveOperation()); + binaryStatus.setCursorPosition(codeArea.getCaretPosition()); + binaryStatus.setSelectionRange(codeArea.getSelection()); + } + + private void initialLoadFromPreferences() { + applyOptions(new BinEdApplyOptions() { + @Nonnull + @Override + public CodeAreaOptions getCodeAreaOptions() { + return preferences.getCodeAreaPreferences(); + } + + @Nonnull + @Override + public TextEncodingOptions getEncodingOptions() { + return preferences.getEncodingPreferences(); + } + + @Nonnull + @Override + public TextFontOptions getFontOptions() { + return preferences.getFontPreferences(); + } + + @Nonnull + @Override + public IntegrationOptions getIntegrationOptions() { + return preferences.getIntegrationPreferences(); + } + + @Nonnull + @Override + public EditorOptions getEditorOptions() { + return preferences.getEditorPreferences(); + } + + @Nonnull + @Override + public StatusOptions getStatusOptions() { + return preferences.getStatusPreferences(); + } + + @Nonnull + @Override + public CodeAreaLayoutOptions getLayoutOptions() { + return preferences.getLayoutPreferences(); + } + + @Nonnull + @Override + public CodeAreaColorOptions getColorOptions() { + return preferences.getColorPreferences(); + } + + @Nonnull + @Override + public CodeAreaThemeOptions getThemeOptions() { + return preferences.getThemePreferences(); + } + }); + + encodingsHandler.loadFromPreferences(preferences.getEncodingPreferences()); + statusPanel.loadFromPreferences(preferences.getStatusPreferences()); + toolbarPanel.loadFromPreferences(); + + updateCurrentMemoryMode(); + } + + private void updateCurrentMemoryMode() { + BinaryStatusApi.MemoryMode memoryMode = BinaryStatusApi.MemoryMode.READ_ONLY; + + if (binaryStatus != null) { + binaryStatus.setMemoryMode(memoryMode); + } + } + + @Nonnull + private AbstractAction createOptionsAction() { + return new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + final BinEdOptionsPanelBorder optionsPanelWrapper = new BinEdOptionsPanelBorder(); + optionsPanelWrapper.setPreferredSize(new Dimension(700, 460)); + BinEdOptionsPanel optionsPanel = optionsPanelWrapper.getOptionsPanel(); + optionsPanel.setPreferences(preferences); + optionsPanel.setTextFontService(new TextFontService() { + @Nonnull + @Override + public Font getCurrentFont() { + return diffPanel.getLeftCodeArea().getCodeFont(); + } + + @Nonnull + @Override + public Font getDefaultFont() { + return defaultFont; + } + + @Override + public void setCurrentFont(Font font) { + diffPanel.getLeftCodeArea().setCodeFont(font); + diffPanel.getRightCodeArea().setCodeFont(font); + } + }); + optionsPanel.loadFromPreferences(); + updateApplyOptions(optionsPanel); + OptionsControlPanel optionsControlPanel = new OptionsControlPanel(); + JPanel dialogPanel = WindowUtils.createDialogPanel(optionsPanelWrapper, optionsControlPanel); + WindowUtils.DialogWrapper dialog = WindowUtils.createDialog(dialogPanel, + (Component) e.getSource(), + "Options", + Dialog.ModalityType.APPLICATION_MODAL); + optionsControlPanel.setHandler((OptionsControlHandler.ControlActionType actionType) -> { + if (actionType != OptionsControlHandler.ControlActionType.CANCEL) { + optionsPanel.applyToOptions(); + if (actionType == OptionsControlHandler.ControlActionType.SAVE) { + optionsPanel.saveToPreferences(); + } + applyOptions(optionsPanel); + diffPanel.getLeftCodeArea().repaint(); + diffPanel.getRightCodeArea().repaint(); + } + + dialog.close(); + }); + dialog.showCentered((Component) e.getSource()); + dialog.dispose(); + } + }; + } + + public void registerEncodingStatus(TextEncodingStatusApi encodingStatusApi) { + this.encodingStatus = encodingStatusApi; + setCharsetChangeListener(() -> { + String selectedEncoding = diffPanel.getLeftCodeArea().getCharset().name(); + encodingStatus.setEncoding(selectedEncoding); + }); + } + + public void setCharsetChangeListener(BinEdComponentPanel.CharsetChangeListener charsetChangeListener) { + this.charsetChangeListener = charsetChangeListener; + } + + private void updateApplyOptions(BinEdApplyOptions applyOptions) { + ExtCodeArea leftCodeArea = diffPanel.getLeftCodeArea(); + ExtCodeArea rightCodeArea = diffPanel.getRightCodeArea(); + CodeAreaOptionsImpl.applyFromCodeArea(applyOptions.getCodeAreaOptions(), leftCodeArea); + CodeAreaOptionsImpl.applyFromCodeArea(applyOptions.getCodeAreaOptions(), rightCodeArea); + applyOptions.getEncodingOptions().setSelectedEncoding(((CharsetCapable) leftCodeArea).getCharset().name()); + applyOptions.getEncodingOptions().setSelectedEncoding(((CharsetCapable) rightCodeArea).getCharset().name()); + + EditorOptions editorOptions = applyOptions.getEditorOptions(); + if (leftCodeArea.getCommandHandler() instanceof CodeAreaOperationCommandHandler) { + editorOptions.setEnterKeyHandlingMode(((CodeAreaOperationCommandHandler) leftCodeArea.getCommandHandler()).getEnterKeyHandlingMode()); + } + if (rightCodeArea.getCommandHandler() instanceof CodeAreaOperationCommandHandler) { + editorOptions.setEnterKeyHandlingMode(((CodeAreaOperationCommandHandler) rightCodeArea.getCommandHandler()).getEnterKeyHandlingMode()); + } + + // TODO applyOptions.getStatusOptions().loadFromPreferences(preferences.getStatusPreferences()); + } + + private void applyOptions(BinEdApplyOptions applyOptions) { + applyOptions(applyOptions, diffPanel.getLeftCodeArea()); + applyOptions(applyOptions, diffPanel.getRightCodeArea()); + } + + private void applyOptions(BinEdApplyOptions applyOptions, ExtCodeArea codeArea) { + BinEdPluginStartupActivity.applyIntegrationOptions(applyOptions.getIntegrationOptions()); + CodeAreaOptionsImpl.applyToCodeArea(applyOptions.getCodeAreaOptions(), codeArea); + + ((CharsetCapable) codeArea).setCharset(Charset.forName(applyOptions.getEncodingOptions() + .getSelectedEncoding())); + encodingsHandler.setEncodings(applyOptions.getEncodingOptions().getEncodings()); + ((FontCapable) codeArea).setCodeFont(applyOptions.getFontOptions().isUseDefaultFont() ? + defaultFont : + applyOptions.getFontOptions().getFont(defaultFont)); + + EditorOptions editorOptions = applyOptions.getEditorOptions(); + // switchShowValuesPanel(editorOptions.isShowValuesPanel()); + if (codeArea.getCommandHandler() instanceof CodeAreaOperationCommandHandler) { + ((CodeAreaOperationCommandHandler) codeArea.getCommandHandler()).setEnterKeyHandlingMode(editorOptions.getEnterKeyHandlingMode()); + } + + StatusOptions statusOptions = applyOptions.getStatusOptions(); + statusPanel.setStatusOptions(statusOptions); + toolbarPanel.applyFromCodeArea(); + + CodeAreaLayoutOptions layoutOptions = applyOptions.getLayoutOptions(); + int selectedLayoutProfile = layoutOptions.getSelectedProfile(); + if (selectedLayoutProfile >= 0) { + codeArea.setLayoutProfile(layoutOptions.getLayoutProfile(selectedLayoutProfile)); + } else { + codeArea.setLayoutProfile(defaultLayoutProfile); + } + + CodeAreaThemeOptions themeOptions = applyOptions.getThemeOptions(); + int selectedThemeProfile = themeOptions.getSelectedProfile(); + if (selectedThemeProfile >= 0) { + codeArea.setThemeProfile(themeOptions.getThemeProfile(selectedThemeProfile)); + } else { + codeArea.setThemeProfile(defaultThemeProfile); + } + + CodeAreaColorOptions colorOptions = applyOptions.getColorOptions(); + int selectedColorProfile = colorOptions.getSelectedProfile(); + if (selectedColorProfile >= 0) { + codeArea.setColorsProfile(colorOptions.getColorsProfile(selectedColorProfile)); + } else { + codeArea.setColorsProfile(defaultColorProfile); + } + } + + @Nonnull + public static PropertiesComponent getPreferences() { + return PropertiesComponent.getInstance(); + } + + @Nonnull + private AbstractAction createOnlineHelpAction() { + return new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + DesktopUtils.openDesktopURL(ONLINE_HELP_URL); + } + }; + } + + private Icon load(String path) { + return IconLoader.getIcon(path, getClass()); + } +} diff --git a/src/main/java/org/exbin/bined/intellij/gui/BinEdComponentPanel.java b/src/main/java/org/exbin/bined/intellij/gui/BinEdComponentPanel.java index b5bcef2..6070bac 100644 --- a/src/main/java/org/exbin/bined/intellij/gui/BinEdComponentPanel.java +++ b/src/main/java/org/exbin/bined/intellij/gui/BinEdComponentPanel.java @@ -25,6 +25,7 @@ import com.intellij.ui.components.JBScrollPane; import org.exbin.auxiliary.paged_data.BinaryData; import org.exbin.bined.CodeAreaCaretPosition; +import org.exbin.bined.CodeType; import org.exbin.bined.EditMode; import org.exbin.bined.EditOperation; import org.exbin.bined.PositionCodeType; @@ -76,6 +77,7 @@ import org.exbin.framework.utils.gui.CloseControlPanel; import org.exbin.framework.utils.gui.OptionsControlPanel; import org.exbin.framework.utils.handler.OptionsControlHandler; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -115,7 +117,7 @@ * @author ExBin Project (https://exbin.org) */ @ParametersAreNonnullByDefault -public class BinEdComponentPanel extends JBPanel implements DumbAware { +public class BinEdComponentPanel extends JBPanel { public static final String ACTION_CLIPBOARD_CUT = "cut-to-clipboard"; public static final String ACTION_CLIPBOARD_COPY = "copy-to-clipboard"; @@ -194,6 +196,33 @@ protected Graphics getComponentGraphics(Graphics g) { defaultThemeProfile = codeArea.getThemeProfile(); defaultColorProfile = codeArea.getColorsProfile(); toolbarPanel = new BinEdToolbarPanel(preferences, codeArea, + new BinEdToolbarPanel.Control() { + @Nonnull + @Override + public CodeType getCodeType() { + return codeArea.getCodeType(); + } + + @Override + public void setCodeType(CodeType codeType) { + codeArea.setCodeType(codeType); + } + + @Override + public boolean isShowUnprintables() { + return codeArea.isShowUnprintables(); + } + + @Override + public void setShowUnprintables(boolean showUnprintables) { + codeArea.setShowUnprintables(showUnprintables); + } + + @Override + public void repaint() { + codeArea.repaint(); + } + }, new AnAction() { @Override public void actionPerformed(@Nonnull AnActionEvent anActionEvent) { @@ -714,8 +743,10 @@ private void createContextMenu(final JPopupMenu menu, int x, int y) { JMenuItem compareFilesMenuItem = createCompareFilesMenuItem(); menu.add(compareFilesMenuItem); - JMenuItem reloadFileMenuItem = createReloadFileMenuItem(); - menu.add(reloadFileMenuItem); + if (fileApi instanceof BinEdFileHandler || fileApi instanceof BinEdNativeFile) { + JMenuItem reloadFileMenuItem = createReloadFileMenuItem(); + menu.add(reloadFileMenuItem); + } final JMenuItem optionsMenuItem = new JMenuItem("Options..."); optionsMenuItem.setIcon(new ImageIcon(getClass().getResource("/org/exbin/framework/options/gui/resources/icons/Preferences16.gif"))); diff --git a/src/main/java/org/exbin/bined/intellij/gui/BinEdToolbarPanel.java b/src/main/java/org/exbin/bined/intellij/gui/BinEdToolbarPanel.java index d929a64..b403357 100644 --- a/src/main/java/org/exbin/bined/intellij/gui/BinEdToolbarPanel.java +++ b/src/main/java/org/exbin/bined/intellij/gui/BinEdToolbarPanel.java @@ -15,22 +15,30 @@ */ package org.exbin.bined.intellij.gui; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.actionSystem.Toggleable; import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Key; import com.intellij.ui.components.JBPanel; import org.exbin.bined.CodeType; import org.exbin.bined.operation.undo.BinaryDataUndoHandler; -import org.exbin.bined.swing.extended.ExtCodeArea; import org.exbin.framework.bined.preferences.BinaryEditorPreferences; import org.exbin.framework.utils.LanguageUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; -import javax.swing.*; -import java.awt.*; +import javax.swing.Icon; +import javax.swing.JComponent; +import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -47,7 +55,7 @@ public class BinEdToolbarPanel extends JBPanel { private static final Key SELECTED_PROPERTY_KEY = Key.create(Toggleable.SELECTED_PROPERTY); private final BinaryEditorPreferences preferences; - private final ExtCodeArea codeArea; + private final Control codeAreaControl; private final AnAction optionsAction; private final AnAction onlineHelpAction; private BinaryDataUndoHandler undoHandler; @@ -64,16 +72,16 @@ public class BinEdToolbarPanel extends JBPanel { private final AnAction hexadecimalCodeTypeAction; private boolean modified = false; - public BinEdToolbarPanel(BinaryEditorPreferences preferences, ExtCodeArea codeArea, AnAction optionsAction, AnAction onlineHelpAction) { + public BinEdToolbarPanel(BinaryEditorPreferences preferences, JComponent targetComponent, Control codeAreaControl, AnAction optionsAction, AnAction onlineHelpAction) { this.preferences = preferences; - this.codeArea = codeArea; + this.codeAreaControl = codeAreaControl; this.optionsAction = optionsAction; this.onlineHelpAction = onlineHelpAction; setLayout(new java.awt.BorderLayout()); actionGroup = new DefaultActionGroup(); toolbar = (ActionToolbarImpl) ActionManager.getInstance().createActionToolbar(TOOLBAR_PLACE, actionGroup, true); - toolbar.setTargetComponent(codeArea); + toolbar.setTargetComponent(targetComponent); add(toolbar, BorderLayout.CENTER); binaryCodeTypeAction = new AnAction( @@ -83,7 +91,7 @@ public BinEdToolbarPanel(BinaryEditorPreferences preferences, ExtCodeArea codeAr ) { @Override public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - codeArea.setCodeType(CodeType.BINARY); + codeAreaControl.setCodeType(CodeType.BINARY); updateCycleButtonState(); } }; @@ -95,7 +103,7 @@ public void actionPerformed(@NotNull AnActionEvent anActionEvent) { ) { @Override public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - codeArea.setCodeType(CodeType.OCTAL); + codeAreaControl.setCodeType(CodeType.OCTAL); updateCycleButtonState(); } }; @@ -106,7 +114,7 @@ public void actionPerformed(@NotNull AnActionEvent anActionEvent) { ) { @Override public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - codeArea.setCodeType(CodeType.DECIMAL); + codeAreaControl.setCodeType(CodeType.DECIMAL); updateCycleButtonState(); } }; @@ -117,7 +125,7 @@ public void actionPerformed(@NotNull AnActionEvent anActionEvent) { ) { @Override public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - codeArea.setCodeType(CodeType.HEXADECIMAL); + codeAreaControl.setCodeType(CodeType.HEXADECIMAL); updateCycleButtonState(); } }; @@ -155,7 +163,7 @@ public void setUndoHandler(BinaryDataUndoHandler undoHandler) { } private void updateCycleButtonState() { - CodeType codeType = codeArea.getCodeType(); + CodeType codeType = codeAreaControl.getCodeType(); switch (codeType) { case BINARY: { @@ -192,7 +200,7 @@ public void applyFromCodeArea() { } public void loadFromPreferences() { - codeArea.setCodeType(preferences.getCodeAreaPreferences().getCodeType()); + codeAreaControl.setCodeType(preferences.getCodeAreaPreferences().getCodeType()); updateCycleButtonState(); updateUnprintables(); } @@ -203,7 +211,7 @@ public void updateUndoState() { } public void updateUnprintables() { - boolean showUnprintables = codeArea.isShowUnprintables(); + boolean showUnprintables = codeAreaControl.isShowUnprintables(); setActionSelection(showUnprintablesToggleButton, showUnprintables); } @@ -293,12 +301,12 @@ public void update(@NotNull AnActionEvent e) { ) { @Override public boolean isSelected(@NotNull AnActionEvent anActionEvent) { - return codeArea.isShowUnprintables(); + return codeAreaControl.isShowUnprintables(); } @Override public void setSelected(@NotNull AnActionEvent anActionEvent, boolean selected) { - codeArea.setShowUnprintables(selected); + codeAreaControl.setShowUnprintables(selected); updateUnprintables(); } }; @@ -343,7 +351,7 @@ public void actionPerformed(@NotNull AnActionEvent anActionEvent) { private void undoEditButtonActionPerformed() { try { undoHandler.performUndo(); - codeArea.repaint(); + codeAreaControl.repaint(); updateUndoState(); } catch (Exception e) { e.printStackTrace(); @@ -353,7 +361,7 @@ private void undoEditButtonActionPerformed() { private void redoEditButtonActionPerformed() { try { undoHandler.performRedo(); - codeArea.repaint(); + codeAreaControl.repaint(); updateUndoState(); } catch (Exception e) { e.printStackTrace(); @@ -371,4 +379,19 @@ private void setActionSelection(AnAction action, boolean selected) { private Icon load(String path) { return IconLoader.getIcon(path, getClass()); } + + @ParametersAreNonnullByDefault + public interface Control { + + @Nonnull + CodeType getCodeType(); + + void setCodeType(CodeType codeType); + + boolean isShowUnprintables(); + + void setShowUnprintables(boolean showUnprintables); + + void repaint(); + } } diff --git a/src/main/java/org/exbin/framework/bined/options/impl/CodeAreaOptionsImpl.java b/src/main/java/org/exbin/framework/bined/options/impl/CodeAreaOptionsImpl.java index 93c5049..bf0ffbc 100644 --- a/src/main/java/org/exbin/framework/bined/options/impl/CodeAreaOptionsImpl.java +++ b/src/main/java/org/exbin/framework/bined/options/impl/CodeAreaOptionsImpl.java @@ -15,24 +15,26 @@ */ package org.exbin.framework.bined.options.impl; -import org.exbin.framework.bined.options.CodeAreaOptions; -import javax.annotation.Nonnull; -import javax.annotation.ParametersAreNonnullByDefault; -import org.exbin.bined.basic.CodeAreaViewMode; import org.exbin.bined.CodeCharactersCase; import org.exbin.bined.CodeType; import org.exbin.bined.PositionCodeType; +import org.exbin.bined.RowWrappingMode; +import org.exbin.bined.basic.CodeAreaViewMode; import org.exbin.bined.capability.CodeCharactersCaseCapable; import org.exbin.bined.capability.CodeTypeCapable; -import org.exbin.bined.RowWrappingMode; import org.exbin.bined.capability.ViewModeCapable; import org.exbin.bined.extended.capability.PositionCodeTypeCapable; import org.exbin.bined.extended.capability.ShowUnprintablesCapable; import org.exbin.bined.highlight.swing.extended.ExtendedHighlightNonAsciiCodeAreaPainter; +import org.exbin.bined.swing.CodeAreaPainter; import org.exbin.bined.swing.extended.ExtCodeArea; +import org.exbin.framework.bined.options.CodeAreaOptions; import org.exbin.framework.bined.preferences.CodeAreaPreferences; import org.exbin.framework.options.api.OptionsData; +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + /** * Code area options. * @@ -189,7 +191,10 @@ public static void applyFromCodeArea(CodeAreaOptions codeAreaOptions, ExtCodeAre codeAreaOptions.setCodeCharactersCase(((CodeCharactersCaseCapable) codeArea).getCodeCharactersCase()); codeAreaOptions.setPositionCodeType(((PositionCodeTypeCapable) codeArea).getPositionCodeType()); codeAreaOptions.setViewMode(((ViewModeCapable) codeArea).getViewMode()); - codeAreaOptions.setCodeColorization(((ExtendedHighlightNonAsciiCodeAreaPainter) codeArea.getPainter()).isNonAsciiHighlightingEnabled()); + CodeAreaPainter painter = codeArea.getPainter(); + if (painter instanceof ExtendedHighlightNonAsciiCodeAreaPainter) { + codeAreaOptions.setCodeColorization(((ExtendedHighlightNonAsciiCodeAreaPainter) painter).isNonAsciiHighlightingEnabled()); + } codeAreaOptions.setRowWrappingMode(codeArea.getRowWrapping()); codeAreaOptions.setMaxBytesPerRow(codeArea.getMaxBytesPerRow()); codeAreaOptions.setMinRowPositionLength(codeArea.getMinRowPositionLength()); @@ -202,7 +207,10 @@ public static void applyToCodeArea(CodeAreaOptions codeAreaOptions, ExtCodeArea ((CodeCharactersCaseCapable) codeArea).setCodeCharactersCase(codeAreaOptions.getCodeCharactersCase()); ((PositionCodeTypeCapable) codeArea).setPositionCodeType(codeAreaOptions.getPositionCodeType()); ((ViewModeCapable) codeArea).setViewMode(codeAreaOptions.getViewMode()); - ((ExtendedHighlightNonAsciiCodeAreaPainter) codeArea.getPainter()).setNonAsciiHighlightingEnabled(codeAreaOptions.isCodeColorization()); + CodeAreaPainter painter = codeArea.getPainter(); + if (painter instanceof ExtendedHighlightNonAsciiCodeAreaPainter) { + ((ExtendedHighlightNonAsciiCodeAreaPainter) painter).setNonAsciiHighlightingEnabled(codeAreaOptions.isCodeColorization()); + } codeArea.setRowWrapping(codeAreaOptions.getRowWrappingMode()); codeArea.setMaxBytesPerRow(codeAreaOptions.getMaxBytesPerRow()); codeArea.setMinRowPositionLength(codeAreaOptions.getMinRowPositionLength()); diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index a08199f..f1c8ac6 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -5,7 +5,7 @@ BinEd - Binary/Hexadecimal Editor - 0.2.8.snapshot + 0.2.8 ExBin Project @@ -42,8 +42,12 @@ Sources: https://github ]]>
  • -
  • - +
    • Added edit as binary action for columns in database view
    • +
    • Added byte-to-byte compare diff option
    • +
    • Added integration options page
    • +
    • Reworked save on close
    • +
    • Added reload file action (issue #49)
    • +
    • Fixed illegal argument exception (issue #50)
    ]]>
    @@ -88,7 +92,7 @@ Sources:
    https://github - + @@ -96,10 +100,6 @@ Sources: https://github - - - -