-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Fix custom exporter not displayed in file chooser #4015
Conversation
Rename FileType -> BasicFileType Fix error with layout file in custom export Fix problem with custom export and file types Remove old ExportFileFilter Importer still uses BasicFileType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just had a quick look but I'm a bit confused. The problem that custom export formats are not displayed correctly sounds like a gui problem to me. However, the solution involves redefining / changing a lot of logic code. Thus I think there should be an easier solution.
The exporter are displayed using the FileChooser.ExtensionFilter
. Thus I suspect that one only needs to change the way how an exporter is converted to an ExtensionFilter
. For the "All import formats" option, this is done in
jabref/src/main/java/org/jabref/gui/util/FileFilterConverter.java
Lines 47 to 49 in e32bdc8
public static FileChooser.ExtensionFilter forAllImporters(SortedSet<Importer> importers) { | |
return convertImporter(Localization.lang("Available import formats"), importers); | |
} |
and I don't see why such an approach shouldn't work also for custom exporters.
But as I said, I only had a quick look and so probably missed something obvious.
allfileTypes.add(fileType); | ||
} | ||
|
||
public static FileType parse(String description) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears to me that the parse
method is no longer needed and I suspect that hence the allFileTypes
list can be removed. Right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes missed that.
The core problem is not the gui but that each exporter has a file type and this file type was also added for the custom exporter. These file type used the parse method to find a file type based on the extension. The file type class is used for the file filter chooser. And an exporter is matched on the file type description. The core changes are in the enum which now implemented an interface. To avoid code duplicates in the anonymous class and the enum I moved them to private static methods. |
ok, thanks for the explanation. I thought a bit more about this problem and came to the conclusion that the cleanest solution is probably to split the description from the "file type". If the later is only a list of extensions (xml, bib, txt, ...) and the importer/exporter itself contains the description, then you can easily create a |
This would only work if the custom export follows the standard file types. If I want my exporter to have filetype xyz then this would not be possible. Another thing which just came to my mind was that we with this approach could also resuse the functionality for the ExternalFileType stuff. Than we could get rid of that completely. |
ok, good point. Do you want to improve the code around I would still separate the file extension from the description text. |
I would rather do this in a follow up on the maintable directly |
CHANGELOG.md
Outdated
@@ -16,6 +16,10 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# | |||
- We changed the implementation of the `[shorttitle]` key pattern. It now removes small words like `a`, `an`, `on`, `the` etc. Refer to the help page for a complete overview. [Feature request in the forum](http://discourse.jabref.org/t/jabref-differences-in-shorttitle-between-versions-3-8-1-and-4-not-discounting-the-a-an-of-in-titles/1147) | |||
|
|||
### Fixed | |||
We fixed an issue where the export to clipboard functionality could not be invoked [#3994](https://github.com/JabRef/jabref/issues/3994) | |||
We fixed an issue with the migration of invalid Look and Feels [#3995, comment](https://github.com/JabRef/jabref/issues/3995#issuecomment-385649448) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a duplication (probably due to a problem while merging).
@@ -101,7 +102,7 @@ public Builder withInitialDirectory(String directory) { | |||
return this; | |||
} | |||
|
|||
public Builder withDefaultExtension(FileType fileType) { | |||
public Builder withDefaultExtension(BasicFileType fileType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this method should still accept FileType
return toExtensionFilter(description, fileTypes); | ||
} | ||
|
||
private static FileChooser.ExtensionFilter toExtensionFilter(String description, List<FileType> fileTypes) { | ||
private static FileChooser.ExtensionFilter toExtensionFilter(String description, List<BasicFileType> fileTypes) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here also FileType
@@ -117,7 +118,7 @@ public TemplateExporter(String consoleName, String lfFileName, String directory, | |||
* @param savePreferences Preferences for saving | |||
* @param deleteBlankLines If blank lines should be remove (default: false) | |||
*/ | |||
public TemplateExporter(String consoleName, String lfFileName, String directory, FileType extension, LayoutFormatterPreferences layoutPreferences, SavePreferences savePreferences, boolean deleteBlankLines) { | |||
public TemplateExporter(String consoleName, String lfFileName, String directory, BasicFileType extension, LayoutFormatterPreferences layoutPreferences, SavePreferences savePreferences, boolean deleteBlankLines) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here too
*/ | ||
public abstract FileType getFileType(); | ||
public abstract BasicFileType getFileType(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here as well...
import org.jabref.logic.l10n.Localization; | ||
|
||
/** | ||
* This enum contains a list of file types used in open and save dialogs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't reference dialogs here (as we are in the logic package).
DEFAULT(Localization.lang("%0 file", "DEFAULT"), "default"); | ||
|
||
private static Set<FileType> allfileTypes = new HashSet<>(EnumSet.allOf(BasicFileType.class)); | ||
private final String[] extensions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably makes the code below a bit easier to read if you simply store the extensions as a List. Moreover, the comment below can probably be removed.
public String getFirstExtensionWithDot() { | ||
return "." + extensions[0].trim(); | ||
} | ||
String getFirstExtensionWithDot(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For these two method you can provide a default implementation.
} | ||
|
||
public static FileType addnewFileType(String description, String... extensions) { | ||
FileType fileType = new FileType() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is probably better to extract this anonymous class to a separate class since it looks to be the standard implementation that can be reused in custom importers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have created a factory method for this. So the caller does not need to create it's own file type objects
public static FileType addnewFileType(String description, String... extensions) {
} | ||
return sj.toString(); | ||
} | ||
String getDescription(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also on a second look, I'm strongly in favor of removing the description
from the file type. It is actually the description of the exporter/importer that we should show in the dialog...if you want to reuse the strings you can extract the descriptions in BasicFileType
to a new class, but its also ok if you just repeat the description in the importer and exporter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would not solve the underlying problem and in fact would result in the same problem I intend to fix here.
As we have multiple file types with the same extension e.g. html. We already have Html Table, Html LIst etc. Only with the added description, the file type is unique
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think your example is a good illustration why the current mix of file extensions and description is misleading. The file type is html
in both examples, but the exporter used is different (tables vs list). You don't get these kind of problems if the FileType
is only an abstraction of the extension and the description comes from the exporter...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least we need the description in the extension filter. Otherwise we can't map it. I will think about this. I will look and see how this would affect the importer
…leType * upstream/master: (33 commits) Import inspection uses now same font size setttings as maintable (#4062) Add date checker (#4007) Enable tests macOs push to application fix Fix #4041 to make Push to Application work again on OSX. (#4057) Add NormalizeEnDashesFormatter (#4045) Package private for tests Shutdown duplicate code Move migrations to PreferencesMigrations Structure startup Extract migrations A first solution for the cli problem #4038 (#4047) New translations JabRef_en.properties (French) (#4052) Update CHANGELOG.md Fix checkstyle Make test more informative in the failing case New translations JabRef_en.properties (French) (#4051) New translations JabRef_en.properties (Vietnamese) (#4050) Make Formatter an abstract class (and remove AbstractFormatter) New Crowdin translations (#4048) ... # Conflicts: # CHANGELOG.md
remove list of custom file types as it's not needed use list instead of varargs params
…abref into fixCustomExportFileType * 'fixCustomExportFileType' of https://github.com/JabRef/jabref: # Conflicts: # CHANGELOG.md
…leType * upstream/master: Update guava and checkstyle (#4066)
@tobiasdiez I now removed the exporter stuff from the FileTypes. So currently it's only used for the importers. The key problem with the importers is, that we have an "All available import formats" plus all the extensions. In this case I see no way to filter the importer without having a description in the extension format. |
A shot in the blue: Instead of jabref/src/main/java/org/jabref/gui/util/FileFilterConverter.java Lines 26 to 29 in e32bdc8
try private static FileChooser.ExtensionFilter convertImporter(Importer importer) {
return toExtensionFilter(importer.getDisplayName(), Collections.singletonList(importer.getFileType));
} and at the same time change jabref/src/main/java/org/jabref/gui/util/FileFilterConverter.java Lines 39 to 41 in e32bdc8
to public static Optional<Importer> getImporter(FileChooser.ExtensionFilter extensionFilter, Collection<Importer> importers) {
return importers.stream().filter(importer -> importer.getDisplayName().equals(extensionFilter.getDescription())).findFirst();
} If |
only keep those with multiple extensions TODO: convert each importer
group extensions
@tobiasdiez I noticed that it was already possible. I just needed to create the Map with Description/Name and FileType like I did for export. It is now analogous to export. I removed the not needed FileTypes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good! There are still some unimplemented comments from previous reviews (the only big one being that the description part should now be removed from the filetype interface).
@@ -152,7 +155,7 @@ public void update() { | |||
} | |||
|
|||
private static FileDialogConfiguration createExportFileChooser(ExporterFactory exportFactory, String currentDir) { | |||
List<FileType> fileTypes = exportFactory.getExporters().stream().map(Exporter::getFileType).collect(Collectors.toList()); | |||
Map<String, FileType> fileTypes = exportFactory.getExporters().stream().collect(Collectors.toMap(Exporter::getDisplayName, Exporter::getFileType)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic to convert an exporter (and importer below) to a FileExtensionFilter should reside in FileFilterConverter
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, in this case it would not have any additional benefit. It would still return a map. The map is internally handled in the file dialog configuration and there handled.
If I understand correctly, this should go into |
Yes definitely. |
I've refactored a bit more (it was easier to hijack this PR than describe the refactorings in detail -sorry). If you are happy with these changes, feel free to merge; otherwise just revert my commits... |
Looks good so far. If someone can merge this with co authoring ( i got this wrong last time) |
Fixes #4013
Fixed several issues with the Custom Exporter.