-
-
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
Convert SharedDatabaseConnect Dialog to Javafx #4040
Conversation
add stub
* upstream/maintable-beta: Switch to org.postgresql (#4031)
The display problem probably results from us playing around with different styles and changing defaults. Since there is no checkbox in the main view, it was not noticed that some of the input controls look strange. I'll have a look at it later... |
add migration help message remove old dialogs
The database connection works so far. Tested with PostgresSQL. I reworked the dialog and fixed an error in the listener which led to freezes. The only thing open is the GUI styling. The dialog looks a bit odd. But that's due to some missing CSS stuff I think. |
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.
In general the rework looks good. Thanks for the work!
It would be nice if you could move all the logic to the view model so that we have a nice separation of concerns. The other remarks are mostly minor.
<Label text="%Database Type:" /> | ||
<ComboBox fx:id="cmbDbType" prefHeight="25.0" prefWidth="606.0" GridPane.columnIndex="1" GridPane.columnSpan="2" /> | ||
<Label text="%Host/Port:" GridPane.rowIndex="1" /> | ||
<TextField fx:id="tbHost" GridPane.columnIndex="1" GridPane.rowIndex="1" /> |
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 don't have a strong opinion on this, but this Hungarian notation is against the usual naming convention. Probably, host
or hostTextField
is preferable. @koppor what's your opinion about this?
this.frame = frame; | ||
this.setTitle(Localization.lang("Connect to shared database")); | ||
|
||
this.getDialogPane().getButtonTypes().addAll(connect, ButtonType.CANCEL); |
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 preferable to set the buttons in the fxml
jabref/src/main/java/org/jabref/gui/help/AboutDialog.fxml
Lines 99 to 100 in 390c387
<ButtonType fx:id="copyVersionButton" text="%Copy Version" /> | |
<ButtonType fx:constant="CLOSE" /> |
and then add the action in the code-behind
ControlHelper.setAction(copyVersionButton, getDialogPane(), event -> copyVersionToClipboard()); |
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 results in an NPE here for the connect butotn which I don't understand. The lookUpButton returns null.
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.
Did you also tried it without the surrounding buttontypes
tag?
|
||
} | ||
|
||
private void openDatabase(ActionEvent e) { |
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 method and essentially everything below should be moved to the ViewModel
. The view should contain no logic whatsoever and just binds the fxml file to the properties in the view model.
cmbDbType.getSelectionModel().select(0); | ||
viewModel.selectedDbmstypeProperty().bind(cmbDbType.getSelectionModel().selectedItemProperty()); | ||
|
||
viewModel.selectedDbmstypeProperty().addListener((observable, oldValue, newValue) -> { |
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.
EasyBind.subscribe
is usually easier to read. Moreover, this logic should also be moved to the view model.
FileDialogConfiguration fileDialogConfiguration = new FileDialogConfiguration.Builder() | ||
.addExtensionFilter(FileType.BIBTEX_DB) | ||
.withDefaultExtension(FileType.BIBTEX_DB) | ||
.withInitialDirectory(Globals.prefs.get(JabRefPreferences.WORKING_DIRECTORY)) |
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 extract the Globals.prefs
dependency. The new JavaFX stuff should no longer depend on Globals
.
} | ||
|
||
private void setLoadingConnectButtonText(boolean isLoading) { | ||
btnConnect.setDisable(isLoading); |
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 viewModel
should have a boolean property connectionInProgress
so that the functionality of this method can be realized by binding.
private DBMSConnectionProperties connectionProperties; | ||
private SharedDatabaseLoginDialogViewModel viewModel; | ||
|
||
public SharedDatabaseLoginDialogView(JabRefFrame frame) { |
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 really don't like that we need a frame here. Can you please investigate if it can be replaced by the StateManager
(maybe after extending the latter).
} | ||
|
||
private void checkFields() throws JabRefException { | ||
if (isEmptyField(tbHost)) { |
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.
Validation should be done using the validation framework so that the user get immediate feedback (have a look at the usage of ControlsFxVisualizer).
jabRefFrame.closeCurrentTab(); | ||
new SharedDatabaseLoginDialogView(jabRefFrame).showAndWait(); | ||
|
||
} |
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.
else if
(and remove empty line above)
|
||
SwingUtilities.invokeLater(() -> panel.closeBottomPane()); | ||
dialogService.showInformationDialogAndWait(Localization.lang("Shared entry is no longer present"), | ||
Localization.lang("The BibEntry you currently work on has been deleted on the shared side.") |
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.
BibEntry
is for our internal usage and entry
should be used for dialogs.
</header> | ||
<buttonTypes> | ||
<ButtonType fx:constant="CLOSE" /> | ||
<ButtonType fx:id="connectButton" text="Connect" /> |
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 I add the button
@FXML private TextField tbFolder; | ||
@FXML private Button btnBrowse; | ||
@FXML private CheckBox chkAutosave; | ||
@FXML private ButtonType connectButton; |
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 buttonType is initalized here
.load() | ||
.setAsContent(this.getDialogPane()); | ||
|
||
ControlHelper.setAction(connectButton, this.getDialogPane(), event -> openDatabase()); |
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.
In this method the lookup method from the dialogPane returns null. I don't understand why.
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.
Somehow the buttons are in the content property of the dialog pane. Does not make any sense to me
Yes I tried both with and without the tags. Same behavior. I don't
understand this.
Tobias Diez <notifications@github.com> schrieb am Fr., 25. Mai 2018, 15:39:
… ***@***.**** commented on this pull request.
------------------------------
In src/main/java/org/jabref/gui/shared/SharedDatabaseLoginDialogView.java
<#4040 (comment)>:
> + @Inject private DialogService dialogService;
+
+ private final SharedDatabasePreferences prefs = new SharedDatabasePreferences();
+
+ private final ButtonType connect = new ButtonType("Connect", ButtonData.YES);
+ private final Button btnConnect;
+ private final JabRefFrame frame;
+
+ private DBMSConnectionProperties connectionProperties;
+ private SharedDatabaseLoginDialogViewModel viewModel;
+
+ public SharedDatabaseLoginDialogView(JabRefFrame frame) {
+ this.frame = frame;
+ this.setTitle(Localization.lang("Connect to shared database"));
+
+ this.getDialogPane().getButtonTypes().addAll(connect, ButtonType.CANCEL);
Did you also tried it without the surrounding buttontypes tag?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#4040 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AATi5GBJ--hYtjBd1unf_oiZTC9_5v_Zks5t2AmsgaJpZM4UGDLC>
.
|
|
||
ViewLoader.view(this) | ||
.load() | ||
.setAsContent(this.getDialogPane()); |
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.
Should be .setAsDialogPane(this);
* upstream/master: (89 commits) Fix that sometimes an empty side pane is shown (#4105) Update gradle from 4.7 to 4.8 (#4102) Add gradle task downloadDependencies and use it at CircleCI (#4091) Set minimum java to 171 (#4095) Also use https in the CHANGELOG itself Add missing CHANGELOG entry Fix localiazation test Use official TempFolder extension for JUnit 5 tests Remove menu* from crowdin.yml (#4094) Merge recent changes to exporter/importer Add missing CHANGELOG entry New translations JabRef_en.properties (Vietnamese) New translations JabRef_en.properties (Dutch) New translations JabRef_en.properties (French) New translations JabRef_en.properties (German) New translations JabRef_en.properties (Greek) New translations JabRef_en.properties (Indonesian) New translations JabRef_en.properties (Italian) New translations JabRef_en.properties (Japanese) New translations JabRef_en.properties (Danish) ... # Conflicts: # src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java
renamings and other refactorings
* upstream/master: (129 commits) Fix Export to clipbaord action (#4286) Add minimal height for entry editor (#4283) Fix exceptions when trying to change settings (#4284) Added a comment for the purpose of the class (#4282) Fix NPE when importing from CLI (#4281) Fix display of key patterns convert bibtexkeypatterndlg to javafx as well (#4277) Style preference sections using css Fix a few style issues Changed the behavior of the field formatting dialog (#4275) Fix checkbox display Remove small font size Style side pane in preferences Wrap preference tabs in scrollpane Fix NPE with bibdatabasecontext in preview style dialog update xmlunit and log4j jul and checkstyle Update mysql driver to 8.0.12 Rework preference dialog main class Move preferences stuff to gui.preferences Implement drag and drop for maintable (#3765) ... # Conflicts: # src/main/java/org/jabref/gui/shared/ConnectToSharedDatabaseDialog.java
* upstream/master: Fix error prone warnings (#4290) Fix freeze on import into current library (#4299) Upgrade gradle to 4.10 update xmlunit and postgres update xmlunit-matchers from 2.6.0 -> 2.6.1 update gradle build-scan from 1.15.2 -> 1.16 checkstyle execute changes only if disk db present fix npe in Merge entries dialog
fix layoout enable ssl stuff only when postgres is enabeld
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.
Since this already looks pretty good, I took the opportunity and reviewed the code again. Feel free to merge directly after fixing my comments.
}); | ||
}); | ||
|
||
viewModel.applyPreferences(); |
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.
call this in the constructor of the view model
databaseType.valueProperty().bindBidirectional(viewModel.selectedDbmstypeProperty()); | ||
|
||
folder.textProperty().bindBidirectional(viewModel.folderProperty()); | ||
browseButton.disableProperty().bind(autosave.selectedProperty().not()); |
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 to viewModel.autosaveProperty()
(the view model controls the view).
|
||
fileKeystore.textProperty().bindBidirectional(viewModel.keyStoreProperty()); | ||
|
||
browseKeystore.disableProperty().bind(useSSL.selectedProperty().not()); |
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
hostValidator = new FunctionBasedValidator<>(host, predicate, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("Port")))); | ||
portValidator = new FunctionBasedValidator<>(port, predicate, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("Host")))); | ||
userValidator = new FunctionBasedValidator<>(user, predicate, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("User")))); | ||
folderValidator = new FunctionBasedValidator<>(folder, predicate, ValidationMessage.error(Localization.lang("Please enter a valid file path."))); |
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.
Really test that the files exists.
ButtonType.OK, openHelp); | ||
|
||
result.filter(btn -> btn.equals(openHelp)).ifPresent(btn -> HelpAction.openHelpPage(HelpFile.SQL_DATABASE_MIGRATION)); | ||
result.filter(btn -> btn == ButtonType.OK).ifPresent(btn -> openSharedDatabase()); |
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 but equals
might be necessary here.
this.connection = DriverManager.getConnection( | ||
properties.getType().getUrl(properties.getHost(), properties.getPort(), properties.getDatabase()), | ||
properties.getUser(), properties.getPassword()); | ||
Properties props = new Properties(); |
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 move these additions to the DBMSConnectionProperties
class as two methods Properties asJavaProperties()
and String getUrl
.
&& this.host.equalsIgnoreCase(properties.getHost()) | ||
&& (this.port == properties.getPort()) | ||
&& this.database.equals(properties.getDatabase()) | ||
&& this.user.equals(properties.getUser()); |
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.
add useSSL
in equals and hash
@@ -89,7 +89,8 @@ public void startNotificationListener(DBMSSynchronizer dbmsSynchronizer) { | |||
// Otherwise the listener is going to be deleted by GC. | |||
PGConnection pgConnection = connection.unwrap(PGConnection.class); | |||
listener = new PostgresSQLNotificationListener(dbmsSynchronizer, pgConnection); | |||
listener.start(); | |||
new Thread(listener, "PostgresSQLNotificationListener").start(); |
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.
Better reuse our threading infrastructure so that we are sure that the thread is shutdown on exit etc.
|
||
public PostgresSQLNotificationListener(DBMSSynchronizer dbmsSynchronizer, PGConnection pgConnection) { | ||
this.dbmsSynchronizer = dbmsSynchronizer; | ||
this.pgConnection = pgConnection; | ||
} | ||
|
||
public void start() { | ||
stop = false; | ||
new Thread(this).start(); |
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.
same
@@ -71,6 +72,11 @@ public boolean getRememberPassword() { | |||
return internalPrefs.getBoolean(SHARED_DATABASE_REMEMBER_PASSWORD, false); | |||
} | |||
|
|||
public boolean isUseSSL() | |||
{ |
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.
code style
Connection works so far. No more freezes regarding addTabs. in basePanel
Somehow the dialog looks odd, @tobiasdiez Any idea what is missing? The checkboxes are not visible correct. I just see that it looks really odd in he maintable-beta branch, too. e..g. int he Event Log
Edit// The conection and the synchronization seems to be working.
Fixes: #3419 PostgresSQL database connection now supports SSL
TODO for documentaition:
Create and configure Server certs
https://www.postgresql.org/docs/current/static/ssl-tcp.html
Convert to keystore format
https://jdbc.postgresql.org/documentation/head/ssl-client.html
Currently I only tested it with PostgresSQL, but I see that mySQL should also work
https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html
TODO:
check conflict merge dialog
Change in CHANGELOG.md described
Tests created for changes
Manually tested changed features in running JabRef
Screenshots added in PR description (for bigger UI changes)
Ensured that the git commit message is a good one
Check documentation status (Issue created for outdated help page at help.jabref.org?)