Skip to content

Fix for issue 10042 #12854

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed

Conversation

dennisarimi
Copy link

@dennisarimi dennisarimi commented Mar 31, 2025

Closes #10042

Description

This pull request addresses the issue where, when an entry is copied from one library to another, the linked files are not copied over. The linked files need to be stored according to the destination library directory settings + file path, as opposed to source library directory settings + file path. The latter is the current implementation, which results in losing the file(s) or making them inaccessible.

Our change adds the default behaviour of copying over linked files to a different library when copying over an entry. This setting can later be disabled depending on the user's preference, through the Linked Files tab in Preferences.

Additionally, we have introduced a preference for setting a default file path if the database file path is inaccessible. This helps prevent issues when database-specific paths are unavailable or incorrectly stored.

Change Locations

  • src/main/.../gui/LibraryTab.java
  • src/main/.../gui/desktop/os/NativeDesktop.java
  • src/main/.../gui/preferences/linkedfiles/LinkedFilesTab.fxml
  • src/main/.../gui/preferences/linkedfiles/LinkedFilesTab.java
  • src/main/.../gui/preferences/linkedfiles/LinkedFilesTabViewModel.java
  • src/main/.../logic/FilePreferences.java
  • src/main/.../logic/preferences/JabRefCliPreferences.java
  • src/main/resources/l10n/JabRef_en.properties

Added a checkbox to toggle the copy setting and a text field to store the destination library directory path within which the linked files will be copied. Also added a preference for a default file path if the database file path is inaccessible.

Next Steps

While working on adding a default file path if the database file path is inaccessible, we faced an issue where database.getMetaData().getLibrarySpecificFileDirectory(); currently returns Optional.empty every time. Due to time constraints, we were unable to look more into this, and an investigation as to what might be the issue may be required.

Tests

We used manual testing to determine if the file path name was being changed when adding entries to the shared library

Screenshots

  • Linked Files tab in Preferences with updated features
Linked Files tab with updated features
  • Setting a default file path if database file path is inaccessible
Setting default file path

Mandatory checks

  • I own the copyright of the code submitted and I license it under the MIT license
  • Change in CHANGELOG.md described in a way that is understandable for the average user (if change is visible to the user)
  • Tests created for changes (if applicable)
  • Manually tested changed features in running JabRef (always required)
  • Screenshots added in PR description (if change is visible to the user)
  • Checked developer's documentation: Is the information available and up to date? If not, I outlined it in this pull request.
  • Checked documentation: Is the information available and up to date? If not, I created an issue at https://github.com/JabRef/user-documentation/issues or, even better, I submitted a pull request to the documentation repository.

@koppor
Copy link
Member

koppor commented Mar 31, 2025

Hi, my team and I have been working on this issue as a university project and have added the UI change to include a checkbox to toggle the setting in the Linked Files tab in Preferences. We however have not been able to set it to be the default state

Did you search for "default" in JabRef's code? Hint: org.jabref.gui.preferences.JabRefGuiPreferences#JabRefGuiPreferences

I replied here, because the question belongs more to the code than to the issue itself.

@dennisarimi
Copy link
Author

org.jabref.gui.preferences.JabRefGuiPreferences#JabRefGuiPreferences

Hi, yes, I looked into the JabRefGuiPreferences file. However, there is no gui/linkedfiles/LinkedFilesPreferences similar to say gui/groups/GroupsPreferences or gui/entryeditors/EntryEditorPreferences, and was wondering how the linked files preferences, such as autolinking files with names starting with the citation key or moving deleted files to trash are set. (I could not find where any of the linked file preferences are set either together or separately)

I may be overlooking something simple, but in this case, would it require me to create the gui/linkedfile/LinkedFilesPreferences and refactor?

@Siedlerchr
Copy link
Member

AUTOLINK_EXACT_KEY_ONLY is in CliPreferences, use double shift in Intellij so search for stuff

storagepath += preferences.getFilePreferences().getLinkedFileDirectory();
}

Pattern pattern = Pattern.compile("/");
Copy link

Choose a reason for hiding this comment

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

The pattern is compiled inside the method and used multiple times. It should be a static final field to avoid recompilation and improve performance.

Comment on lines +955 to +959
if (generalFileDirectory.isPresent()) {
storagepath += generalFileDirectory.get();
} else {
storagepath += preferences.getFilePreferences().getLinkedFileDirectory();
}
Copy link

Choose a reason for hiding this comment

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

The code should follow the fail-fast principle by handling invalid states early and avoiding else branches. This can be refactored for better readability.

@dennisarimi
Copy link
Author

AUTOLINK_EXACT_KEY_ONLY is in CliPreferences, use double shift in Intellij so search for stuff

Thank you!

@dennisarimi dennisarimi force-pushed the fix-for-issue-10042 branch from b702a3d to 411c380 Compare April 1, 2025 04:08
Comment on lines +202 to +204
public BooleanProperty copyLinkedFilesProperty() {
return this.copyLinkedFilesProperty;
}
Copy link

Choose a reason for hiding this comment

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

The method 'copyLinkedFilesProperty' should return an Optional instead of potentially returning null, adhering to modern Java practices.

Comment on lines +206 to +208
public StringProperty linkedFileDirectoryProperty() {
return linkedFileDirectoryProperty;
}
Copy link

Choose a reason for hiding this comment

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

The method 'linkedFileDirectoryProperty' should return an Optional instead of potentially returning null, following modern Java practices.

@jabref-machine
Copy link
Collaborator

Do not force-push! Force pushing is a very bad practice when working together on a project (mainly because it is not supported well by GitHub itself). Commits are lost and comments on commits lose their context, thus making it harder to review changes. At the end, all commits will be squashed anyway before being merged into the main branch.

Comment on lines +238 to +240
public String getLinkedFileDirectory() {
return linkedFileDirectory.get();
}
Copy link

Choose a reason for hiding this comment

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

The method 'getLinkedFileDirectory' should return an Optional to avoid returning null and handle absent values safely.

Copy link
Member

Choose a reason for hiding this comment

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

JabRef works with ...Property; not with the data directly.

Please refer to other methods and class variables in that class.

Copy link
Member

@Siedlerchr Siedlerchr Apr 1, 2025

Choose a reason for hiding this comment

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

This is correct. See other Preferences e.g.


    public boolean shouldKeepDownloadUrl() {
        return shouldKeepDownloadUrl.get();
    }

@dennisarimi dennisarimi marked this pull request as ready for review April 1, 2025 04:47
importHandler.importEntriesWithDuplicateCheck(bibDatabaseContext, entriesToAdd);
boolean checkCopyPreferences = preferences.getFilePreferences().copyLinkedFiles();

if (checkCopyPreferences && (bibDatabaseContext.getLocation() == DatabaseLocation.SHARED)) {
Copy link

Choose a reason for hiding this comment

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

The condition should follow the fail-fast principle by handling invalid states early and returning, instead of nesting logic inside else branches.

@FXML private CheckBox confirmLinkedFileDelete;
@FXML private CheckBox moveToTrash;

@FXML private CheckBox copyLinkedFiles;
Copy link

Choose a reason for hiding this comment

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

The addition of the 'copyLinkedFiles' checkbox should be accompanied by a preference migration to handle any changes in default settings.

@subhramit
Copy link
Member

Please give a title to the PR that summarizes your changes/what issue it fixes.
For reference, look at the titles of other PRs.

@Siedlerchr
Copy link
Member

Closing this PR due to inactivity 💤 Please reopen the PR when you continue working on this

@Siedlerchr Siedlerchr closed this Apr 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Copying entry to another library does not copy linked file(s)
5 participants