diff --git a/src/org/infinity/gui/ResourceTree.java b/src/org/infinity/gui/ResourceTree.java index 05f751c4e..5049c8d32 100644 --- a/src/org/infinity/gui/ResourceTree.java +++ b/src/org/infinity/gui/ResourceTree.java @@ -668,7 +668,8 @@ private void maybeShowPopup(MouseEvent e) { private final class TreePopupMenu extends JPopupMenu implements ActionListener, PopupMenuListener { private final JMenuItem miOpen = new JMenuItem("Open"); - private final JMenuItem miOpennew = new JMenuItem("Open in new window"); + private final JMenuItem miOpenNew = new JMenuItem("Open in new window"); + private final JMenuItem miOpenBiffedNew = new JMenuItem("Open biffed resource in new window"); private final JMenuItem miReference = new JMenuItem("Find references"); private final JMenuItem miExport = new JMenuItem("Export"); private final JMenuItem miAddCopy = new JMenuItem("Add copy of"); @@ -681,8 +682,8 @@ private final class TreePopupMenu extends JPopupMenu implements ActionListener, miReference.setEnabled(false); miZip.setToolTipText("Create a zip archive out of the selected saved game."); Font fnt = miOpen.getFont().deriveFont(Font.PLAIN); - for (JMenuItem mi : new JMenuItem[] { miOpen, miOpennew, miReference, miExport, miZip, miAddCopy, miRename, - miDelete, miRestore }) { + for (JMenuItem mi : new JMenuItem[] { miOpen, miOpenNew, miOpenBiffedNew, miReference, miExport, + miZip, miAddCopy, miRename, miDelete, miRestore }) { add(mi); mi.addActionListener(this); mi.setFont(fnt); @@ -701,7 +702,7 @@ private ResourceEntry getResourceEntry() { @Override public void actionPerformed(ActionEvent event) { showResource = true; - ResourceEntry node = getResourceEntry(); + final ResourceEntry node = getResourceEntry(); if (event.getSource() == miOpen && node != null) { if (prevNextNode != null) { prevStack.push(prevNextNode); @@ -712,11 +713,24 @@ public void actionPerformed(ActionEvent event) { prevNextNode = node; shownResource = node; NearInfinity.getInstance().setViewable(ResourceFactory.getResource(node)); - } else if (event.getSource() == miOpennew && node != null) { + } else if (event.getSource() == miOpenNew && node != null) { Resource res = ResourceFactory.getResource(node); if (res != null) { new ViewFrame(NearInfinity.getInstance(), res); } + } else if (event.getSource() == miOpenBiffedNew && node != null) { + try { + final BIFFResourceEntry biffedNode = + new BIFFResourceEntry(ResourceFactory.getKeyfile().getResourceEntry(node.getResourceName()), false); + final Resource res = ResourceFactory.getResource(biffedNode); + if (res != null) { + new ViewFrame(NearInfinity.getInstance(), res); + } + } catch (NullPointerException e) { + System.err.println("Does not exist in BIFF: " + node); + JOptionPane.showMessageDialog(NearInfinity.getInstance(), + "Does not exist in BIFF: " + node, "Error", JOptionPane.ERROR_MESSAGE); + } } else if (event.getSource() == miReference && node != null) { Resource res = ResourceFactory.getResource(node); if (res != null && res instanceof Referenceable) { @@ -764,7 +778,14 @@ public void actionPerformed(ActionEvent event) { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent event) { - ResourceEntry entry = getResourceEntry(); + final ResourceEntry entry = getResourceEntry(); + + boolean biffEnable = + (!BrowserMenuBar.getInstance().getOptions().ignoreOverrides() || + BrowserMenuBar.getInstance().getOptions().getOverrideMode() == OverrideMode.InOverride) && + entry.hasOverride(); + miOpenBiffedNew.setEnabled(biffEnable); + Class cls = ResourceFactory.getResourceType(entry); miReference.setEnabled(cls != null && Referenceable.class.isAssignableFrom(cls)); miRename.setEnabled(entry instanceof FileResourceEntry); diff --git a/src/org/infinity/gui/ViewFrame.java b/src/org/infinity/gui/ViewFrame.java index 3431b14ec..54d441593 100644 --- a/src/org/infinity/gui/ViewFrame.java +++ b/src/org/infinity/gui/ViewFrame.java @@ -17,6 +17,7 @@ import org.infinity.resource.Viewable; import org.infinity.resource.ViewableContainer; import org.infinity.resource.graphics.BamResource; +import org.infinity.resource.key.BIFFResourceEntry; import org.infinity.resource.key.Keyfile; import org.infinity.resource.key.ResourceEntry; @@ -82,7 +83,13 @@ public void setViewable(Viewable viewable) { ResourceEntry entry = ((Resource) viewable).getResourceEntry(); // setTitle(entry.toString()); setIconImage(entry.getIcon().getImage()); - statusBar.setMessage(entry.getActualPath().toString()); + final String path; + if (entry instanceof BIFFResourceEntry) { + path = ((BIFFResourceEntry) entry).getActualPath(!entry.hasOverride()).toString(); + } else { + path = entry.getActualPath().toString(); + } + statusBar.setMessage(path); } else { setIconImage(Keyfile.ICON_STRUCT.getImage()); setTitle(((StructEntry) viewable).getName()); diff --git a/src/org/infinity/gui/menu/FileMenu.java b/src/org/infinity/gui/menu/FileMenu.java index 0df287e61..5b7403984 100644 --- a/src/org/infinity/gui/menu/FileMenu.java +++ b/src/org/infinity/gui/menu/FileMenu.java @@ -23,6 +23,7 @@ import org.infinity.resource.Resource; import org.infinity.resource.ResourceFactory; import org.infinity.resource.StructureFactory; +import org.infinity.resource.key.BIFFResourceEntry; import org.infinity.resource.key.FileResourceEntry; import org.infinity.resource.key.ResourceEntry; @@ -78,6 +79,7 @@ public class FileMenu extends JMenu implements BrowserSubMenu, ActionListener { private final JMenu newFileMenu; private final JMenuItem fileOpenNew; + private final JMenuItem fileOpenBiffedNew; private final JMenuItem fileReference; private final JMenuItem fileExport; private final JMenuItem fileAddCopy; @@ -98,6 +100,10 @@ public FileMenu(BrowserMenuBar parent) { fileOpenNew = BrowserMenuBar.makeMenuItem("Open in New Window", KeyEvent.VK_W, Icons.ICON_OPEN_16.getIcon(), -1, this); fileOpenNew.setEnabled(false); add(fileOpenNew); + fileOpenBiffedNew = BrowserMenuBar.makeMenuItem("Open Biffed Resource in New Window", KeyEvent.VK_W, + Icons.ICON_OPEN_16.getIcon(), -1, this); + fileOpenBiffedNew.setEnabled(false); + add(fileOpenBiffedNew); fileReference = BrowserMenuBar.makeMenuItem("Find references...", KeyEvent.VK_F, Icons.ICON_FIND_16.getIcon(), -1, this); fileReference.setEnabled(false); add(fileReference); @@ -136,9 +142,17 @@ public void gameLoaded() { } public void resourceEntrySelected(ResourceEntry entry) { + boolean biffEnable = entry != null && + (!BrowserMenuBar.getInstance().getOptions().ignoreOverrides() || + BrowserMenuBar.getInstance().getOptions().getOverrideMode() == OverrideMode.InOverride) && + entry.hasOverride(); + fileOpenBiffedNew.setEnabled(biffEnable); + fileOpenNew.setEnabled(entry != null); + Class cls = ResourceFactory.getResourceType(entry); fileReference.setEnabled(cls != null && Referenceable.class.isAssignableFrom(cls)); + fileExport.setEnabled(entry != null); fileAddCopy.setEnabled(entry != null); fileRename.setEnabled(entry instanceof FileResourceEntry); @@ -158,6 +172,20 @@ public void actionPerformed(ActionEvent event) { if (res != null) { new ViewFrame(NearInfinity.getInstance(), res); } + } else if (event.getSource() == fileOpenBiffedNew) { + final ResourceEntry node = NearInfinity.getInstance().getResourceTree().getSelected(); + try { + final BIFFResourceEntry biffedNode = + new BIFFResourceEntry(ResourceFactory.getKeyfile().getResourceEntry(node.getResourceName()), false); + final Resource res = ResourceFactory.getResource(biffedNode); + if (res != null) { + new ViewFrame(NearInfinity.getInstance(), res); + } + } catch (NullPointerException e) { + System.err.println("Does not exist in BIFF: " + node); + JOptionPane.showMessageDialog(NearInfinity.getInstance(), + "Does not exist in BIFF: " + node, "Error", JOptionPane.ERROR_MESSAGE); + } } else if (event.getSource() == fileReference) { Resource res = ResourceFactory.getResource(NearInfinity.getInstance().getResourceTree().getSelected()); if (res instanceof Referenceable) { diff --git a/src/org/infinity/resource/key/BIFFResourceEntry.java b/src/org/infinity/resource/key/BIFFResourceEntry.java index ebc2e9d5c..5368c2fa7 100644 --- a/src/org/infinity/resource/key/BIFFResourceEntry.java +++ b/src/org/infinity/resource/key/BIFFResourceEntry.java @@ -59,6 +59,16 @@ public BIFFResourceEntry(BIFFEntry bifEntry, String resourceName, int offset) { } } + public BIFFResourceEntry(BIFFResourceEntry entry, boolean hasOverride) { + Objects.requireNonNull(entry); + this.keyFile = entry.keyFile; + this.resourceName = entry.resourceName; + this.type = entry.type; + this.extension = entry.extension; + this.locator = entry.locator; + this.hasOverride = hasOverride; + } + BIFFResourceEntry(Path keyFile, ByteBuffer buffer, int offset) { if (keyFile == null || buffer == null) { throw new NullPointerException("Path to KEY file and byte buffer with BIFF content must not be null"); @@ -192,7 +202,7 @@ public int getLocator() { @Override public ByteBuffer getResourceBuffer(boolean ignoreOverride) throws Exception { - if (!ignoreOverride) { + if (!ignoreOverride && hasOverride) { List overrides = Profile.getOverrideFolders(false); Path file = FileManager.query(overrides, getResourceName()); if (file != null && FileEx.create(file).isFile()) {