Skip to content

Fix the working of shortcut keys for linked files#15261

Merged
Siedlerchr merged 2 commits into
JabRef:mainfrom
priyanshu16095:fixShortcutR
Mar 11, 2026
Merged

Fix the working of shortcut keys for linked files#15261
Siedlerchr merged 2 commits into
JabRef:mainfrom
priyanshu16095:fixShortcutR

Conversation

@priyanshu16095

Copy link
Copy Markdown
Contributor

Fixes #12564

This PR ensures that the shortcut keys that were not working for the linked files in the entry editor works as expected, they were not being triggered properly.

expected_behavior_linked_files.mov

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • [/] I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix shortcut keys for linked files in entry editor

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Fixed shortcut key handling for linked files in entry editor
• Added proper key binding mapping for file operations
• Implemented keyboard event handlers for rename, open, copy actions
• Created new RENAME_FILE_TO_NAME key binding with shortcut+P
Diagram
flowchart LR
  KB["KeyBinding.java<br/>Add RENAME_FILE_TO_NAME"] -->|maps to| SA["StandardActions.java<br/>Fix key binding reference"]
  SA -->|used by| LFE["LinkedFilesEditor.java<br/>Implement key event handlers"]
  LFE -->|executes| CA["ContextAction<br/>File operations"]
  LFE -->|executes| CFA["CopyLinkedFilesAction<br/>Copy files"]
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java ✨ Enhancement +2/-1

Add RENAME_FILE_TO_NAME key binding

• Added new RENAME_FILE_TO_NAME key binding enum constant
• Configured with shortcut+P as default binding
• Assigned to EDIT category for file operations

jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java


2. jabgui/src/main/java/org/jabref/gui/actions/StandardActions.java 🐞 Bug fix +1/-1

Fix key binding reference for rename action

• Fixed RENAME_FILE_TO_NAME action to use correct KeyBinding.RENAME_FILE_TO_NAME
• Previously incorrectly referenced KeyBinding.REPLACE_STRING

jabgui/src/main/java/org/jabref/gui/actions/StandardActions.java


3. jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java ✨ Enhancement +43/-3

Implement keyboard shortcuts for file operations

• Added imports for StandardActions, CopyLinkedFilesAction, and ContextAction
• Implemented key event handlers for DELETE_ENTRY, RENAME_FILE_TO_NAME, OPEN_FILE, OPEN_FOLDER,
 EDIT_FILE_LINK, and COPY
• Each handler retrieves selected file and executes corresponding action
• Converted switch statement to modern switch expression syntax

jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java


View more (1)
4. CHANGELOG.md 📝 Documentation +1/-0

Document shortcut key fix in changelog

• Added entry documenting fix for shortcut keys not working with linked files
• References issue #12564

CHANGELOG.md


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Rename shortcut conflict 🐞 Bug ✓ Correctness
Description
The new key binding for renaming linked files defaults to "shortcut+P", which conflicts with the
Bash preset mapping "shortcut+P" to EDITOR_UP; due to first-match resolution by enum order,
RENAME_FILE_TO_NAME may never be detected. Result: the rename shortcut won’t work for users using
that preset (or any configuration with duplicate bindings).
Code

jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[R130-131]

+    LOOKUP_DOC_IDENTIFIER("Search document identifier online", Localization.lang("Search document identifier online"), "alt+F", KeyBindingCategory.EDIT),
+    RENAME_FILE_TO_NAME("Rename file(s) to configured filename format pattern", Localization.lang("Rename file(s) to configured filename format pattern"), "shortcut+P", KeyBindingCategory.EDIT);
Evidence
RENAME_FILE_TO_NAME is bound to shortcut+P, but Bash preset assigns shortcut+P to EDITOR_UP.
KeyBindingRepository.mapToKeyBinding returns only the first match when iterating KeyBinding.values()
in enum declaration order, so the earlier EDITOR_UP binding will win and LinkedFilesEditor’s switch
will not reach RENAME_FILE_TO_NAME.

jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[5-7]
jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[128-132]
jabgui/src/main/java/org/jabref/gui/preferences/keybindings/presets/BashKeyBindingPreset.java[15-36]
jabgui/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java[110-120]
jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[268-283]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RENAME_FILE_TO_NAME` uses `shortcut+P`, which conflicts with the Bash preset’s `EDITOR_UP`. Because shortcut resolution uses the *first* matching enum constant, the linked-files rename shortcut may never fire.

### Issue Context
`LinkedFilesEditor` currently uses `mapToKeyBinding(event)` (first-match) and then switches on a single resolved binding.

### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[268-317]
- jabgui/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java[110-136]
- jabgui/src/main/java/org/jabref/gui/preferences/keybindings/presets/BashKeyBindingPreset.java[15-36]
- jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[128-132]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Executes disabled actions 🐞 Bug ⛯ Reliability
Description
The new linked-files shortcut handler runs ContextAction/CopyLinkedFilesAction without checking
executableProperty, so users can trigger actions that are disabled in the context menu (e.g.,
copy-to-folder on missing/online links), causing confusing dialogs and failures. Keyboard shortcuts
should generally respect the same enable/disable conditions as the UI actions they mirror.
Code

jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[R277-310]

+                    case RENAME_FILE_TO_NAME -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.RENAME_FILE_TO_NAME, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case OPEN_FILE -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.OPEN_FILE, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case OPEN_FOLDER -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.OPEN_FOLDER, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case OPEN_CLOSE_ENTRY_EDITOR -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.EDIT_FILE_LINK, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case COPY -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new CopyLinkedFilesAction(selectedFile.getFile(), dialogService, databaseContext, preferences.getFilePreferences()).execute();
+                            event.consume();
+                        }
Evidence
LinkedFilesEditor directly calls execute() for commands on keypress. But these commands explicitly
bind executable to preconditions (file exists, not online). Since execute() does not self-guard
(e.g., CopyLinkedFilesAction always opens a directory chooser first), shortcuts can invoke disabled
operations unlike the context menu which is disabled via executableProperty.

jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[268-311]
jabgui/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ContextAction.java[43-98]
jabgui/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ContextAction.java[105-128]
jabgui/src/main/java/org/jabref/gui/copyfiles/CopyLinkedFilesAction.java[47-50]
jabgui/src/main/java/org/jabref/gui/copyfiles/CopyLinkedFilesAction.java[52-71]
jabgui/src/main/java/org/jabref/gui/actions/JabRefAction.java[20-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The linked-files key handler executes commands even when they are not executable (the same commands that would be disabled in the context menu). This can trigger directory choosers and error flows for missing/online links.

### Issue Context
`CopyLinkedFilesAction` and `ContextAction` both compute `executable` preconditions, but `LinkedFilesEditor` calls `execute()` directly on keypress.

### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[268-311]
- jabgui/src/main/java/org/jabref/gui/copyfiles/CopyLinkedFilesAction.java[47-71]
- jabgui/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ContextAction.java[43-128]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. selectedFile retrieval duplicated 📘 Rule violation ⛯ Reliability
Description
The new keybinding handling repeats listView.getSelectionModel().getSelectedItem() and the same
null-check in multiple switch cases, increasing maintenance cost and the chance of inconsistent
future fixes. This should be consolidated into a shared helper (or a single retrieval + switch) to
keep the method focused and DRY.
Code

jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[R277-311]

+                    case RENAME_FILE_TO_NAME -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.RENAME_FILE_TO_NAME, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case OPEN_FILE -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.OPEN_FILE, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case OPEN_FOLDER -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.OPEN_FOLDER, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case OPEN_CLOSE_ENTRY_EDITOR -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new ContextAction(StandardActions.EDIT_FILE_LINK, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
+                            event.consume();
+                        }
+                    }
+                    case COPY -> {
+                        LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
+                        if (selectedFile != null) {
+                            new CopyLinkedFilesAction(selectedFile.getFile(), dialogService, databaseContext, preferences.getFilePreferences()).execute();
+                            event.consume();
+                        }
+                    }
Evidence
PR Compliance IDs 21 and 3 require refactoring duplicated logic and keeping code
focused/maintainable. In setUpKeyBindings(), multiple added cases repeat the same selectedFile
lookup and if (selectedFile != null) guard before executing actions.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[277-311]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new keybinding switch duplicates `selectedFile` lookup and null-check logic across multiple cases.

## Issue Context
This violates the project’s compliance requirements to avoid duplication and keep code focused/maintainable.

## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[277-311]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Keybinding not persisted 🐞 Bug ⛯ Reliability
Description
Adding the new KeyBinding can leave it missing from the persisted keybinding map for upgraded users,
meaning it may not appear in the keybinding preferences UI and may not be written back to
preferences. This makes the new shortcut hard/impossible to discover or customize after upgrade.
Code

jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[R130-131]

+    LOOKUP_DOC_IDENTIFIER("Search document identifier online", Localization.lang("Search document identifier online"), "alt+F", KeyBindingCategory.EDIT),
+    RENAME_FILE_TO_NAME("Rename file(s) to configured filename format pattern", Localization.lang("Rename file(s) to configured filename format pattern"), "shortcut+P", KeyBindingCategory.EDIT);
Evidence
When loading keybindings from stored bindNames/bindings lists, the repository only loads the
provided lists (no backfill for new enum constants). The preferences UI is built by iterating
keyBindingRepository.getKeyBindings(), so missing keys won’t be shown/configurable even though
get(String) falls back to the enum default.

jabgui/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java[35-48]
jabgui/src/main/java/org/jabref/gui/preferences/keybindings/KeyBindingsTabViewModel.java[62-80]
jabgui/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java[68-76]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
When a new `KeyBinding` enum constant is introduced, upgraded users’ stored `bindNames/bindings` lists won’t include it. The current repository load path does not backfill missing keys, and the preferences UI iterates only over `getKeyBindings()`, so the new binding may not be displayed or persisted.

### Issue Context
This PR adds `KeyBinding.RENAME_FILE_TO_NAME`, which is a new enum constant.

### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java[35-48]
- jabgui/src/main/java/org/jabref/gui/preferences/keybindings/KeyBindingsTabViewModel.java[62-80]
- jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[128-132]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

5. Trailing blank line added 📘 Rule violation ✓ Correctness
Description
An extra blank line was added at the end of LinkedFilesEditor.java without any functional change.
This is unrelated reformatting and makes diffs noisier than necessary.
Code

jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[389]

+
Evidence
PR Compliance ID 2 requires avoiding unrelated formatting-only changes. The PR adds an extra
trailing blank line at the end of the file.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[384-389]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
There is an unrelated trailing blank line added at end-of-file.

## Issue Context
The compliance checklist requires avoiding unrelated reformatting.

## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[384-389]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +130 to +131
LOOKUP_DOC_IDENTIFIER("Search document identifier online", Localization.lang("Search document identifier online"), "alt+F", KeyBindingCategory.EDIT),
RENAME_FILE_TO_NAME("Rename file(s) to configured filename format pattern", Localization.lang("Rename file(s) to configured filename format pattern"), "shortcut+P", KeyBindingCategory.EDIT);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Rename shortcut conflict 🐞 Bug ✓ Correctness

The new key binding for renaming linked files defaults to "shortcut+P", which conflicts with the
Bash preset mapping "shortcut+P" to EDITOR_UP; due to first-match resolution by enum order,
RENAME_FILE_TO_NAME may never be detected. Result: the rename shortcut won’t work for users using
that preset (or any configuration with duplicate bindings).
Agent Prompt
### Issue description
`RENAME_FILE_TO_NAME` uses `shortcut+P`, which conflicts with the Bash preset’s `EDITOR_UP`. Because shortcut resolution uses the *first* matching enum constant, the linked-files rename shortcut may never fire.

### Issue Context
`LinkedFilesEditor` currently uses `mapToKeyBinding(event)` (first-match) and then switches on a single resolved binding.

### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[268-317]
- jabgui/src/main/java/org/jabref/gui/keyboard/KeyBindingRepository.java[110-136]
- jabgui/src/main/java/org/jabref/gui/preferences/keybindings/presets/BashKeyBindingPreset.java[15-36]
- jabgui/src/main/java/org/jabref/gui/keyboard/KeyBinding.java[128-132]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +277 to +310
case RENAME_FILE_TO_NAME -> {
LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
if (selectedFile != null) {
new ContextAction(StandardActions.RENAME_FILE_TO_NAME, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
event.consume();
}
}
case OPEN_FILE -> {
LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
if (selectedFile != null) {
new ContextAction(StandardActions.OPEN_FILE, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
event.consume();
}
}
case OPEN_FOLDER -> {
LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
if (selectedFile != null) {
new ContextAction(StandardActions.OPEN_FOLDER, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
event.consume();
}
}
case OPEN_CLOSE_ENTRY_EDITOR -> {
LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
if (selectedFile != null) {
new ContextAction(StandardActions.EDIT_FILE_LINK, selectedFile, databaseContext, bibEntry, preferences, viewModel).execute();
event.consume();
}
}
case COPY -> {
LinkedFileViewModel selectedFile = listView.getSelectionModel().getSelectedItem();
if (selectedFile != null) {
new CopyLinkedFilesAction(selectedFile.getFile(), dialogService, databaseContext, preferences.getFilePreferences()).execute();
event.consume();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Executes disabled actions 🐞 Bug ⛯ Reliability

The new linked-files shortcut handler runs ContextAction/CopyLinkedFilesAction without checking
executableProperty, so users can trigger actions that are disabled in the context menu (e.g.,
copy-to-folder on missing/online links), causing confusing dialogs and failures. Keyboard shortcuts
should generally respect the same enable/disable conditions as the UI actions they mirror.
Agent Prompt
### Issue description
The linked-files key handler executes commands even when they are not executable (the same commands that would be disabled in the context menu). This can trigger directory choosers and error flows for missing/online links.

### Issue Context
`CopyLinkedFilesAction` and `ContextAction` both compute `executable` preconditions, but `LinkedFilesEditor` calls `execute()` directly on keypress.

### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/fieldeditors/LinkedFilesEditor.java[268-311]
- jabgui/src/main/java/org/jabref/gui/copyfiles/CopyLinkedFilesAction.java[47-71]
- jabgui/src/main/java/org/jabref/gui/fieldeditors/contextmenu/ContextAction.java[43-128]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@testlens-app

This comment has been minimized.

@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: no-bot-comments labels Mar 4, 2026
@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Your pull request conflicts with the target branch.

Please merge with your code. For a step-by-step guide to resolve merge conflicts, see https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line.

Siedlerchr
Siedlerchr previously approved these changes Mar 11, 2026
@testlens-app

testlens-app Bot commented Mar 11, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: df6082e
▶️ Tests: 10126 executed
⚪️ Checks: 52/52 completed


Learn more about TestLens at testlens.app.

@Siedlerchr Siedlerchr enabled auto-merge March 11, 2026 19:34
@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Mar 11, 2026
@Siedlerchr Siedlerchr added this pull request to the merge queue Mar 11, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Mar 11, 2026
Merged via the queue into JabRef:main with commit 6fb013b Mar 11, 2026
51 of 52 checks passed
FynnianB pushed a commit to FynnianB/jabref that referenced this pull request Mar 19, 2026
Co-authored-by: Christoph <siedlerkiller@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shortcut Ctrl+R does not work

2 participants