-
-
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
Searchable/Filterable preferences #4415
Conversation
First of all, thanks for your contribtion! 👍 If you look at the code fo the old PreferencesFilterDialog, you see that the data comes from the If you have further questions you can also ask in out gitter chat. https://gitter.im/JabRef/jabref Edit// Adjusted my comment |
The easiest solution is probably to transverse the complete control node tree and take the text of all label controls. |
9fb4e3e
to
1f16301
Compare
@Siedlerchr Its still on my todo list. Havent found the time to investigate further and were stuck on how I display the filtered preferences. I think @paulKra doesnt work on it, he still didnt accept my invitation link to my forked repo |
Okay thanks for the udpate! Take your time. If you have any questions just ask here or in gitter and we try to help |
Maybe the JFXHighlighter from https://github.com/jfoenixadmin/JFoenix/ works to highlight the matches |
488540f
to
3ac59ef
Compare
src/main/java/org/jabref/gui/preferences/PreferencesSearchHandler.java
Outdated
Show resolved
Hide resolved
src/main/java/org/jabref/gui/preferences/PreferencesSearchHandler.java
Outdated
Show resolved
Hide resolved
src/main/java/org/jabref/gui/preferences/PreferencesDialog.java
Outdated
Show resolved
Hide resolved
@tobiasdiez Thanks for the hint, however I tested it locally but I didnt liked it that much (for example it did mark the buttons for importing/exporting/show/reset preferences also). |
still work in progress mapping search to preference and start searching it still needs a way to filter the found items
also be explicit about method visibility
Verified this is not the case: label names dont contain tab names
…ablePreferences
…ablePreferences
@CaptainDaVinci is this ready for review or do you need to further work on it? |
@tobiasdiez Yes, this is ready for review. |
|
||
private final Labeled labeled; | ||
|
||
LabeledWrapper(Labeled _labeled) { |
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.
Please do not use an underscore. In java it's more common to do:
LabeledWrapper(Labeled _labeled) { | |
LabeledWrapper(Labeled labeled){ | |
this.labeled= labeled; |
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.
And maybe use a better name to indicate what the purpose of the class actually is. LabeledWrapper sounds a bit too generic for me.
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.
Initial idea with the inner class was to handle Labeled
being treated as a key to mapping from Labeled
to PrefsTab
. Now that the relation is reversed, I don't think the LabeledWrapper
class is required anymore.
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.
Thanks for the contribution!
In general looks good to me, just some minor code style things.
And also please add a screenshot
} | ||
} | ||
|
||
PreferencesSearchHandler(List<PrefsTab> preferenceTabs, StringProperty searchText) { |
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.
Please remove the StringProperty as constructor argument, instead expose the property through a method:
And initialize the variable with new SimpleStringProperty("")
public StringProperty searchTextProperty()
{
return this.searchText;
}
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.
As I understand, this should then be used to bind to searchBox.textProperty()
in PerferencesDialog
,
searchHandler.searchTextProperty().bind(searchBox.textProperty());
?
Also, shouldn't tabsList.itemsProperty().bindBidirectional(searchHandler.filteredPreferenceTabsProperty());
have a unidirectional binding instead?
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.
@Siedlerchr I am facing some issues on implementing this.
I have removed the StringProperty
from the constructor argument as per your suggestion.
In PreferencesDialog
, the searchHandler.searchStringProperty()
is bound to searchBox.textProperty()
. However, when the searchBox
text changes, it doesn't trigger the ChangeListener for searchText
. Unless, I add a statement to listen for changes on searchBox
as well.
searchBox.textProperty().addListener((o, p, n) -> {
// dummy reference to the text property.
searchHandler.searchTextProperty();
});
I am not able to understand the reason for this, is it necessary to have listeners on both the properties which are bound?
TextField searchBox = new TextField(); | ||
searchBox.setPromptText(Localization.lang("Search")); | ||
|
||
PreferencesSearchHandler searchHandler = new PreferencesSearchHandler(preferenceTabs, searchBox.textProperty()); |
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.
Bind the searchBox.textProperty the same ways as you do with the itemsProperty below
return prefsTabLabelMap; | ||
} | ||
|
||
protected ListProperty<PrefsTab> getFilteredPreferenceTabsProperty() { |
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.
Just the wording, remove the "get" from the name., e.g. just FilteredPreviewPreferencesTabsProperty()
to conform to the javafx code naming conventions
|
||
private final Labeled labeled; | ||
|
||
LabeledWrapper(Labeled _labeled) { |
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.
And maybe use a better name to indicate what the purpose of the class actually is. LabeledWrapper sounds a bit too generic for me.
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've only two small suggestions in addition to the ones of @Siedlerchr.
@@ -12,3 +12,7 @@ | |||
.preferencePaneContainer { | |||
-fx-padding: 0em 1em 0em 3em; | |||
} | |||
|
|||
*:search-highlight { | |||
-fx-background-color: #ed7474; |
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.
Can you please reuse one of the colors defined in base.css. In case you find no suitable color there, then please define a new one there.
} | ||
} | ||
|
||
if (tabContainsLabel) { |
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.
As you suggested yourself, I think it is a good idea to move the logic of filterByTabName
here (if (tabContainsLabel || tabNameIsMatchedBySearchQuery
) instead of having two separate methods.
Thank you for the suggestions @tobiasdiez and @Siedlerchr! I have refactored the code for the most part to account for the changes and will push the code once I have implemented all changes. |
@CaptainDaVinci Look at my patch: (Import via git am < file.patch) |
@Siedlerchr Thank you for sharing the patch, however, this did not work for me. The change listener for The only way I could make this work was to add a listener to
|
Hm this is odd. It worked fine for me with this line: Under the hood the bidirectional is nothing else than a wrapper around the changeLIstener stuff. |
Also, note that its necessary to have a reference to Edit: For me changing the text in the GUI field did not update the view or highlight the labels. |
Bindings are created using WeakListener, so they might get garbage collected. But I still don't understand why it works for me with the patch. I would propose you test again with my patch or at least commit the changes and let others test as well. |
Okay, I have pushed changes, in the mean time I will try testing it again. P.S: Since the |
searchBox.setPromptText(Localization.lang("Search")); | ||
|
||
PreferencesSearchHandler searchHandler = new PreferencesSearchHandler(preferenceTabs); | ||
tabsList.itemsProperty().bindBidirectional(searchHandler.filteredPreferenceTabsProperty()); |
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'm not sure if this is the reason for the problem, but it should suffice to replace the filteredPreferenceTabsProperty
by an observable list (instead of an list property) and then use the bindContentsBidirectional
method to bind tabsList.getItems()
to this observable list.
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.
Unfortunately, this did not work either. The problem is that searchHandler.searchText
does not reflect the changes from the searchBox
, unless an explicit listener is added to searchBox
and searchHandler.searchText
is simply accessed there.
searchBox.textProperty().addListener((o, p, n) -> {
searchHandler.searchTextProperty(); // required, so that changed are reflected.
});
|
||
PreferencesSearchHandler searchHandler = new PreferencesSearchHandler(preferenceTabs); | ||
tabsList.itemsProperty().bindBidirectional(searchHandler.filteredPreferenceTabsProperty()); | ||
searchHandler.searchTextProperty().bindBidirectional(searchBox.textProperty()); |
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.
Another try would be to pass the searchBox.textProperty()
as the constructor argument and then add the listener directly (I think you had something similar before). I think both approaches are valid although it's strange that the current code does not work for you.
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.
Indeed, that was the previous approach.
How about another approach where we add a listener on searchBox
, which makes call to searchHandler.filterTabs
directly, without the need of having StringProperty
in between?
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, that sounds like the easiest solution. Please go ahead and make the corresponding changes. Thanks!
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.
@tobiasdiez I have implemented the required changes in the recent commit.
Thanks to both @WtfJoke and @CaptainDaVinci for joining forces! |
Fixes #1019
Up so far I just created the textbox for searching and fixed a deprecation warning.
I added @paulKra as collaborator on my fork.
Last step so far: I was asking myself how I can access the text of the different Preferences-Categories and I was wondering if I need a new Interface (something like PrefTabContents or PrefTabContainer for it or extend existing PrefsTab Interface.