Skip to content

Fix CSL files are not removed properly if already exist#15463

Merged
Siedlerchr merged 10 commits intoJabRef:mainfrom
pluto-han:fix-for-issue-15438
Apr 7, 2026
Merged

Fix CSL files are not removed properly if already exist#15463
Siedlerchr merged 10 commits intoJabRef:mainfrom
pluto-han:fix-for-issue-15438

Conversation

@pluto-han
Copy link
Copy Markdown
Contributor

@pluto-han pluto-han commented Mar 31, 2026

Related issues and pull requests

Closes #15438

PR Description

When users remove a citation style, if the style already exists in the list, it will not be removed immediately unless users reopen the dialog.

This PR added a duplication check to find styles with the same title (or short title) before insersion. In addition, this PR did some refactor to the related logic (mainly refactored some ifPresent logic to avoid nested if) for more readability.

Steps to test

  1. Open OpenOffice component, click "select style" -> "add .csl file"
  2. Add acm-sig-proceedings-long-author-list.csl, which is already in the list -> An error dialog shows up, saying it is already in the list
image
  1. Add ieee-bold-author.csl, which is a new citation style -> Added succesfully
image

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 CSL style duplicate detection and immediate removal

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Add duplicate detection for citation styles before insertion
• Refactor CSL style addition logic for improved readability
• Separate validation and duplicate checking from style addition
• Add user-friendly error messages for duplicate styles
Diagram
flowchart LR
  A["User selects CSL file"] --> B["Create citation style"]
  B --> C["Validate style"]
  C -->|Invalid| D["Show error dialog"]
  C -->|Valid| E["Check for duplicates"]
  E -->|Duplicate found| F["Show info dialog"]
  E -->|No duplicate| G["Add style to list"]
  G --> H["Update UI and preferences"]
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java 🐞 Bug fix +54/-27

Refactor style addition with duplicate detection

• Refactored addCslStyleFile() method to separate validation, duplicate checking, and addition
 logic
• Added findDuplicate() method to detect existing styles with same title or short title
• Added hasSameStyleName() helper method to compare citation styles
• Improved error handling with early returns instead of nested if statements
• Changed to use CSLStyleUtils.createCitationStyleFromFile() directly for style creation

jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java


2. jablib/src/main/java/org/jabref/logic/citationstyle/CSLStyleLoader.java Refactoring +4/-14

Simplify style addition method

• Replaced addStyleIfValid() method with simpler addStyle() method
• Removed validation logic from this class (moved to caller)
• Method now only handles adding pre-validated styles and storing preferences
• Simplified method signature and documentation

jablib/src/main/java/org/jabref/logic/citationstyle/CSLStyleLoader.java


3. CHANGELOG.md 📝 Documentation +1/-0

Document CSL style removal fix

• Added entry documenting the fix for issue #15438
• Describes that CSL files are now removed immediately when removing style

CHANGELOG.md


View more (1)
4. jablib/src/main/resources/l10n/JabRef_en.properties Localization +2/-0

Add localization for duplicate style messages

• Added new localization keys for duplicate style detection
• Added "Style already available" message
• Added "The selected CSL style is already available in the list." message

jablib/src/main/resources/l10n/JabRef_en.properties


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown
Contributor

qodo-free-for-open-source-projects bot commented Mar 31, 2026

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (2)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (1)
📘\ ☼ Reliability (1) ⚙ Maintainability (1)

Grey Divider


Action required

1. No tests for CSL logic 📘
Description
This PR changes CSL style import behavior (new validation/duplicate detection and a new
CSLStyleLoader.addStyle API), but no corresponding tests are added/updated in the diff. This risks
regressions and violates the requirement to update tests when behavior changes.
Code

jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[R197-250]

+            // Create a citation style
+            Optional<CitationStyle> citationStyleToAddOptional = CSLStyleUtils.createCitationStyleFromFile(stylePath);
-            if (newStyleOptional.isPresent()) {
-                CitationStyle newStyle = newStyleOptional.get();
+            // Check if citation style is valid
+            if (citationStyleToAddOptional.isEmpty()) {
+                dialogService.showErrorDialogAndWait(
+                        Localization.lang("Invalid style selected"),
+                        Localization.lang("You must select a valid CSL style file.")
+                );
+                return;
+            }
-                List<CitationStyle> allStyles = CSLStyleLoader.getStyles();
-                List<CitationStylePreviewLayout> updatedLayouts = allStyles.stream()
-                                                                           .map(style -> new CitationStylePreviewLayout(style, bibEntryTypesManager))
-                                                                           .toList();
+            CitationStyle citationStyleToAdd = citationStyleToAddOptional.get();
-                availableCslLayouts.setAll(updatedLayouts);
+            // Check if citation style is duplicate in the list
+            Optional<CitationStylePreviewLayout> existingLayout = findDuplicate(citationStyleToAdd);
+            if (existingLayout.isPresent()) {
+                dialogService.showInformationDialogAndWait(
+                        Localization.lang("Style already available"),
+                        Localization.lang("The selected CSL style is already available in the list.")
+                );
+                return;
+            }
-                Optional<CitationStylePreviewLayout> newLayoutOptional = updatedLayouts.stream()
-                                                                                       .filter(layout -> layout.getFilePath().equals(stylePath))
-                                                                                       .findFirst();
+            // Citation style is good to add
+            cslStyleLoader.addStyle(citationStyleToAdd);
-                if (newLayoutOptional.isPresent()) {
-                    CitationStylePreviewLayout newLayout = newLayoutOptional.get();
-                    selectedCslLayoutProperty.set(newLayout);
+            List<CitationStyle> allStyles = CSLStyleLoader.getStyles();
+            List<CitationStylePreviewLayout> updatedLayouts = allStyles.stream()
+                                                                       .map(style -> new CitationStylePreviewLayout(style, bibEntryTypesManager))
+                                                                       .toList();
-                    openOfficePreferences.setCurrentStyle(newStyle);
+            availableCslLayouts.setAll(updatedLayouts);
-                    dialogService.showInformationDialogAndWait(
-                            Localization.lang("Style added"),
-                            Localization.lang("The CSL style has been added successfully.")
-                    );
-                } else {
-                    dialogService.showErrorDialogAndWait(
-                            Localization.lang("Style not found"),
-                            Localization.lang("The CSL style was added but could not be found in the list.")
-                    );
-                }
+            Optional<CitationStylePreviewLayout> newLayoutOptional = updatedLayouts.stream()
+                                                                                   .filter(layout -> layout.getFilePath().equals(stylePath))
+                                                                                   .findFirst();
+
+            if (newLayoutOptional.isPresent()) {
+                CitationStylePreviewLayout newLayout = newLayoutOptional.get();
+                selectedCslLayoutProperty.set(newLayout);
+
+                openOfficePreferences.setCurrentStyle(citationStyleToAdd);
+
+                dialogService.showInformationDialogAndWait(
+                        Localization.lang("Style added"),
+                        Localization.lang("The CSL style has been added successfully.")
+                );
  } else {
      dialogService.showErrorDialogAndWait(
-                        Localization.lang("Invalid style selected"),
-                        Localization.lang("You must select a valid CSL style file.")
+                        Localization.lang("Style not found"),
+                        Localization.lang("The CSL style was added but could not be found in the list.")
      );
  }
Evidence
PR Compliance ID 11 requires tests to be updated/added when behavior changes; the diff shows
behavioral changes in production code for CSL style handling without any accompanying test changes.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[197-250]
jablib/src/main/java/org/jabref/logic/citationstyle/CSLStyleLoader.java[117-121]

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

## Issue description
CSL style importing behavior was changed (duplicate detection + new loader API), but the PR does not add/update tests to prevent regressions.
## Issue Context
At minimum, tests should cover: (1) rejecting invalid CSL files, (2) detecting duplicates by title/short title, and (3) persisting newly added external styles.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[197-250]
- jablib/src/main/java/org/jabref/logic/citationstyle/CSLStyleLoader.java[117-121]

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


2. Duplicate check uses stale list🐞
Description
addCslStyleFile() detects duplicates only via availableCslLayouts, which is populated
asynchronously; if the list is not yet loaded, duplicates can still be added, undermining the
intended fix and allowing the “delete doesn’t remove” confusion to reappear.
Code

jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[R211-219]

+            // Check if citation style is duplicate in the list
+            Optional<CitationStylePreviewLayout> existingLayout = findDuplicate(citationStyleToAdd);
+            if (existingLayout.isPresent()) {
+                dialogService.showInformationDialogAndWait(
+                        Localization.lang("Style already available"),
+                        Localization.lang("The selected CSL style is already available in the list.")
+                );
+                return;
+            }
Evidence
CSL styles are loaded into availableCslLayouts asynchronously (BackgroundTask) and the Add button is
always available in the dialog. The duplicate check uses availableCslLayouts (findDuplicate) before
adding, so if that list is not populated yet it cannot detect duplicates even though CSLStyleLoader
may already know about them.

jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[89-95]
jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[211-219]
jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[292-296]
jabgui/src/main/resources/org/jabref/gui/openoffice/StyleSelectDialog.fxml[27-31]

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

## Issue description
`addCslStyleFile()` checks for duplicates using `availableCslLayouts`, but that list is populated asynchronously. If the user clicks **Add .csl file** before `availableCslLayouts` is filled, the duplicate check can miss existing styles and allow duplicates.
### Issue Context
The dialog loads CSL styles in a `BackgroundTask` and later calls `availableCslLayouts.setAll(...)`. The duplicate check should not rely on the UI list being already populated.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[211-219]
- jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[292-301]
### Suggested fix direction
Use `CSLStyleLoader.getStyles()` (or another source-of-truth list) for duplicate detection, or disable the add button until the async load finishes. This ensures duplicates are prevented even when the UI list is not yet initialized.

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



Remediation recommended

3. Trivial // comments added 📘
Description
addCslStyleFile() introduces multiple comments that restate the code’s obvious intent, adding
noise without documenting rationale. This violates the guideline to avoid trivial comments and keep
the codebase clean and reviewable.
Code

jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[R197-222]

+            // Create a citation style
+            Optional<CitationStyle> citationStyleToAddOptional = CSLStyleUtils.createCitationStyleFromFile(stylePath);
-            if (newStyleOptional.isPresent()) {
-                CitationStyle newStyle = newStyleOptional.get();
+            // Check if citation style is valid
+            if (citationStyleToAddOptional.isEmpty()) {
+                dialogService.showErrorDialogAndWait(
+                        Localization.lang("Invalid style selected"),
+                        Localization.lang("You must select a valid CSL style file.")
+                );
+                return;
+            }
-                List<CitationStyle> allStyles = CSLStyleLoader.getStyles();
-                List<CitationStylePreviewLayout> updatedLayouts = allStyles.stream()
-                                                                           .map(style -> new CitationStylePreviewLayout(style, bibEntryTypesManager))
-                                                                           .toList();
+            CitationStyle citationStyleToAdd = citationStyleToAddOptional.get();
-                availableCslLayouts.setAll(updatedLayouts);
+            // Check if citation style is duplicate in the list
+            Optional<CitationStylePreviewLayout> existingLayout = findDuplicate(citationStyleToAdd);
+            if (existingLayout.isPresent()) {
+                dialogService.showInformationDialogAndWait(
+                        Localization.lang("Style already available"),
+                        Localization.lang("The selected CSL style is already available in the list.")
+                );
+                return;
+            }
-                Optional<CitationStylePreviewLayout> newLayoutOptional = updatedLayouts.stream()
-                                                                                       .filter(layout -> layout.getFilePath().equals(stylePath))
-                                                                                       .findFirst();
+            // Citation style is good to add
+            cslStyleLoader.addStyle(citationStyleToAdd);
Evidence
PR Compliance ID 5 forbids adding trivial comments that merely restate what the code does; the added
comments (e.g., // Create a citation style, // Check if citation style is valid, `// Citation
style is good to add`) are exactly that.

AGENTS.md
jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[197-222]

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

## Issue description
`addCslStyleFile()` contains newly added comments that restate the immediately visible code behavior (what), rather than explaining rationale (why).
## Issue Context
Project guidance requires avoiding trivial comments to reduce noise.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[197-222]

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


4. Changelog entry grammar issue📘
Description
The new CHANGELOG line contains awkward phrasing (when removing style) and should be rewritten in
professional, grammatically correct end-user language. This violates the documentation/release-notes
professionalism requirement.
Code

CHANGELOG.md[46]

+- We fixed an issue where CSL files are not removed immediately when removing style. [#15438](https://github.com/JabRef/jabref/issues/15438)
Evidence
PR Compliance ID 21 requires professional, precise, grammatically correct release notes; the added
sentence is ungrammatical/awkward and should be improved for end users.

CHANGELOG.md[46-46]
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 newly added CHANGELOG entry is not grammatically polished for end users.
## Issue Context
Release notes should be professional and precisely worded.
## Fix Focus Areas
- CHANGELOG.md[46-46]

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


5. Path compare may misfire 🐞
Description
After adding a style, the code looks it up via layout.getFilePath().equals(stylePath), but
CitationStyle normalizes paths (Path.of(filePath).toString()), so the lookup can fail and wrongly
show “Style not found” (and not select/set the new style) even though it was added.
Code

jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[R231-233]

+            Optional<CitationStylePreviewLayout> newLayoutOptional = updatedLayouts.stream()
+                                                                                   .filter(layout -> layout.getFilePath().equals(stylePath))
+                                                                                   .findFirst();
Evidence
The lookup for the newly added layout compares against the raw stylePath string. CitationStyle
normalizes file paths in its constructor, so the path stored in the newly-created CitationStyle (and
therefore in the layout) can differ from the raw string, causing the search to fail and triggering
the error branch.

jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[231-249]
jablib/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java[26-29]

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 newly added style is searched in `updatedLayouts` using the raw `stylePath` string. Since `CitationStyle` normalizes the file path internally, `layout.getFilePath()` may not equal the original `stylePath`, causing a false "Style not found" dialog and skipping selection/current-style update.
### Issue Context
`CitationStyle` normalizes paths via `Path.of(filePath).toString()`. The view model currently uses the unnormalized `stylePath` for equality.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[231-249]
- jablib/src/main/java/org/jabref/logic/citationstyle/CitationStyle.java[26-29]
### Suggested fix direction
Compare against a normalized path (e.g., `String normalized = Path.of(stylePath).toString();`) or, better, compare to `citationStyleToAdd.getFilePath()` when searching `updatedLayouts`.

ⓘ 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

@github-actions github-actions bot added good first issue An issue intended for project-newcomers. Varies in difficulty. component: libre-office labels Mar 31, 2026
Comment on lines +197 to 250
// Create a citation style
Optional<CitationStyle> citationStyleToAddOptional = CSLStyleUtils.createCitationStyleFromFile(stylePath);

if (newStyleOptional.isPresent()) {
CitationStyle newStyle = newStyleOptional.get();
// Check if citation style is valid
if (citationStyleToAddOptional.isEmpty()) {
dialogService.showErrorDialogAndWait(
Localization.lang("Invalid style selected"),
Localization.lang("You must select a valid CSL style file.")
);
return;
}

List<CitationStyle> allStyles = CSLStyleLoader.getStyles();
List<CitationStylePreviewLayout> updatedLayouts = allStyles.stream()
.map(style -> new CitationStylePreviewLayout(style, bibEntryTypesManager))
.toList();
CitationStyle citationStyleToAdd = citationStyleToAddOptional.get();

availableCslLayouts.setAll(updatedLayouts);
// Check if citation style is duplicate in the list
Optional<CitationStylePreviewLayout> existingLayout = findDuplicate(citationStyleToAdd);
if (existingLayout.isPresent()) {
dialogService.showInformationDialogAndWait(
Localization.lang("Style already available"),
Localization.lang("The selected CSL style is already available in the list.")
);
return;
}

Optional<CitationStylePreviewLayout> newLayoutOptional = updatedLayouts.stream()
.filter(layout -> layout.getFilePath().equals(stylePath))
.findFirst();
// Citation style is good to add
cslStyleLoader.addStyle(citationStyleToAdd);

if (newLayoutOptional.isPresent()) {
CitationStylePreviewLayout newLayout = newLayoutOptional.get();
selectedCslLayoutProperty.set(newLayout);
List<CitationStyle> allStyles = CSLStyleLoader.getStyles();
List<CitationStylePreviewLayout> updatedLayouts = allStyles.stream()
.map(style -> new CitationStylePreviewLayout(style, bibEntryTypesManager))
.toList();

openOfficePreferences.setCurrentStyle(newStyle);
availableCslLayouts.setAll(updatedLayouts);

dialogService.showInformationDialogAndWait(
Localization.lang("Style added"),
Localization.lang("The CSL style has been added successfully.")
);
} else {
dialogService.showErrorDialogAndWait(
Localization.lang("Style not found"),
Localization.lang("The CSL style was added but could not be found in the list.")
);
}
Optional<CitationStylePreviewLayout> newLayoutOptional = updatedLayouts.stream()
.filter(layout -> layout.getFilePath().equals(stylePath))
.findFirst();

if (newLayoutOptional.isPresent()) {
CitationStylePreviewLayout newLayout = newLayoutOptional.get();
selectedCslLayoutProperty.set(newLayout);

openOfficePreferences.setCurrentStyle(citationStyleToAdd);

dialogService.showInformationDialogAndWait(
Localization.lang("Style added"),
Localization.lang("The CSL style has been added successfully.")
);
} else {
dialogService.showErrorDialogAndWait(
Localization.lang("Invalid style selected"),
Localization.lang("You must select a valid CSL style file.")
Localization.lang("Style not found"),
Localization.lang("The CSL style was added but could not be found in the list.")
);
}
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. No tests for csl logic 📘 Rule violation ☼ Reliability

This PR changes CSL style import behavior (new validation/duplicate detection and a new
CSLStyleLoader.addStyle API), but no corresponding tests are added/updated in the diff. This risks
regressions and violates the requirement to update tests when behavior changes.
Agent Prompt
## Issue description
CSL style importing behavior was changed (duplicate detection + new loader API), but the PR does not add/update tests to prevent regressions.

## Issue Context
At minimum, tests should cover: (1) rejecting invalid CSL files, (2) detecting duplicates by title/short title, and (3) persisting newly added external styles.

## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/openoffice/StyleSelectDialogViewModel.java[197-250]
- jablib/src/main/java/org/jabref/logic/citationstyle/CSLStyleLoader.java[117-121]

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

@testlens-app

This comment has been minimized.

@Siedlerchr
Copy link
Copy Markdown
Member

Thanks for tackling this issue, maybe another point you can think about: When adding a new CSL style it would be great to select/focus it in the list. I think this is what I missed

@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 31, 2026
@testlens-app
Copy link
Copy Markdown

testlens-app bot commented Mar 31, 2026

✅ All tests passed ✅

🏷️ Commit: ed76532
▶️ Tests: 10212 executed
⚪️ Checks: 56/56 completed


Learn more about TestLens at testlens.app.

@pluto-han
Copy link
Copy Markdown
Contributor Author

When adding a new CSL style it would be great to select/focus it in the list.

Thank you for the suggestion. I have updated the code.

@github-actions github-actions bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Mar 31, 2026
Optional<Path> path = dialogService.showFileOpenDialog(fileDialogConfiguration);

path.map(Path::toAbsolutePath).map(Path::toString).ifPresent(stylePath -> {
Optional<CitationStyle> newStyleOptional = cslStyleLoader.addStyleIfValid(stylePath);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can't the duplicate checking logic be incorporated into the existing addStyleIfValid method?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can't the duplicate checking logic be incorporated into the existing addStyleIfValid method?

Yeah I have tried it before, but then both "Invalid style" and "Duplicate style" return Optional.empty(), so viewmodel cannot distinguish between them.

I have a new workaround:
put CSLStyleUtils.createCitationStyleFromFile in viewmodel and let viewmodel check style validity. Then pass valid citation style to addStyleIfValid, which incorporats duplication check. What do you think?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi, I am slightly busy till the weekend. I'll get back to this soon.

Copy link
Copy Markdown
Member

@subhramit subhramit Apr 4, 2026

Choose a reason for hiding this comment

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

Now that I think, the design of addStyleIfValid is a bit misleading.
It suggests a void action, but is also returning the style optional for further processing by the viewModel.
Since CSLStyleLoader and JStyleLoader (currently) don't implement a common interface, it is okay to remove that method from CSLStyleLoader and do it the way it is done in this PR now.

That being said, do check the requirements for consistency - the EXTERNAL_STYLES list (which was a private member of CSLStyleLoader) is no longer being updated on addition now, which was in turn being used in storeExternalStyles() to update the list of externally added styles in openOfficePreferences. So now the loader may no longer be "aware" of the addition of a new style. The action is symmetric in case of removal - so one way to check would be to add a valid, non-duplicate external style now, restart JabRef to see if it still persists, and try removing it. Compare the logic carefully and see why or why not it'll work.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

P.S. During the upcoming refactoring phases, we can think on how both of the style loaders can implement an interface to share these methods - as both have internal, external styles addition, removal and preference storage.
Maybe that was the idea I had when I named this method - I see an analogue in JStyleLoader which returns a boolean instead. We can later on look how duplicates are handled there.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the detailed comment, they are very insightful. But I have a question here:

the EXTERNAL_STYLES list (which was a private member of CSLStyleLoader) is no longer being updated on addition now

Could you please explain about this? Because in my view, EXTERNAL_STYLES.add() and storeExternalStyles() are still kept in addStyle in this PR.

I have checked the consistency following the steps above. External style can persist when JabRef restarts and can be removed properly.

During the upcoming refactoring phases, we can think on how both of the style loaders can implement an interface to share these methods

We then maybe need to refactor addStyleIfValid() and other methods in JStyleLoader as well, since they currently have different method signature.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you please explain about this? Because in my view, EXTERNAL_STYLES.add() and storeExternalStyles() are still kept in addStyle in this PR.

Ah that was a miss from my side - when I was looking at the viewmodel changes in this PR while checking CSLStyleLoader in my IDE where I did not have this PR checked out. This should work. Thanks!

We then maybe need to refactor addStyleIfValid() and other methods in JStyleLoader as well, since they currently have different method signature.

Correct - we will deal with that later.

}
}

private boolean findDuplicate(CitationStyle style) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Better name would be isDuplicate(...) so that it reads as

    if (isDuplicate(citationStyleToAdd)) {
    ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good idea!
Code updated.

@github-actions github-actions bot added status: changes-required Pull requests that are not yet complete and removed status: no-bot-comments labels Apr 4, 2026
@github-actions github-actions bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Apr 4, 2026
Copy link
Copy Markdown
Member

@subhramit subhramit left a comment

Choose a reason for hiding this comment

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

One last comment


return Optional.empty();
/// Adds a new external CSL style.
public void addStyle(@NonNull CitationStyle citationStyle) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rename to addExternalStyle

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated.

subhramit
subhramit previously approved these changes Apr 4, 2026
@subhramit subhramit added the status: awaiting-second-review For non-trivial changes label Apr 4, 2026
@subhramit subhramit requested a review from Siedlerchr April 4, 2026 17:46
@pluto-han
Copy link
Copy Markdown
Contributor Author

Did one small modification:
I renamed variable name in isDuplicate for more consistency and readability.

subhramit
subhramit previously approved these changes Apr 4, 2026
@github-actions github-actions bot added status: changes-required Pull requests that are not yet complete and removed status: no-bot-comments labels Apr 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

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.

@github-actions github-actions bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Apr 6, 2026
@Siedlerchr Siedlerchr added this pull request to the merge queue Apr 7, 2026
@github-actions github-actions bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Apr 7, 2026
Merged via the queue into JabRef:main with commit e3a4f35 Apr 7, 2026
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: libre-office good first issue An issue intended for project-newcomers. Varies in difficulty. status: awaiting-second-review For non-trivial changes 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.

CSL files are not removed immediately when removing style

3 participants