Skip to content
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

Add welcome screen to JabRef GUI that displays when no database/library is open #12017

Draft
wants to merge 38 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
13b1b58
made a basic welcome screen here in WelcomeScreen.java
Oct 15, 2024
3c63145
got rid of welcome screen and made a welcome tab instead. Welcome tab…
Oct 15, 2024
0715fcd
made welcome page, works dynamically if no tabs are open
Oct 15, 2024
b27ddb6
opening new tab dismisses welcome screen
Oct 15, 2024
e88edc5
corrected reference to JabRefGui.mainFrame
Oct 16, 2024
e14b016
remove some debug loggers
Oct 17, 2024
ec78771
Merge pull request #1 from HaynesCrossley-ANU/issue-96
HaynesCrossley-ANU Oct 17, 2024
69005e9
update CHANGELOG.md
Oct 17, 2024
d9ae0ee
Merge branch 'main' of https://github.com/HaynesCrossley-ANU/jabref
Oct 17, 2024
14984a9
update CHANGELOG.md
Oct 17, 2024
eade258
update welcome screen with hyperlinks instead of plain text
Oct 17, 2024
a031c35
welcome screen now has links for new library and open library
Oct 18, 2024
1b76f86
update CHANGELOG.md
Oct 18, 2024
2e38635
fix typo in CHANGELOG.md
Oct 18, 2024
64f7f38
Merge branch 'JabRef:main' into main
HaynesCrossley-ANU Oct 18, 2024
90ca2d2
Merge branch 'main' into issue-96
HaynesCrossley-ANU Oct 18, 2024
e9c04fd
remove comments
Oct 18, 2024
5d50f08
move styling on WelcomePage to Base.css
Oct 18, 2024
325debb
Merge branch 'main' into issue-96
surymishra Oct 19, 2024
e15cdb9
remove comments from WelcomePage.java
Oct 20, 2024
0a392f7
Merge branch 'issue-96' of https://github.com/HaynesCrossley-ANU/jabr…
Oct 20, 2024
33dab83
Merge branch 'main' into issue-96
koppor Oct 20, 2024
eab1844
modify updateContent() method
Oct 20, 2024
0c07f52
Merge remote-tracking branch 'origin/issue-96' into issue-96
Oct 20, 2024
b616970
modify updateSidePane method
Oct 22, 2024
5b5a63c
FIX: fix sidebar resizing exception
Chethin Oct 23, 2024
89d6985
CHORE: remove unnecessary logic
Chethin Oct 23, 2024
64a09e7
Merge branch 'main' into issue-96
koppor Oct 23, 2024
bd07c06
Merge pull request #3 from HaynesCrossley-ANU/issue-96-review-changes
HaynesCrossley-ANU Oct 23, 2024
a495fe8
FEAT: made entire welcome sentences into links
Chethin Oct 25, 2024
aab2694
FEAT: Localisation for welcome strings in welcome page
Chethin Oct 25, 2024
f8dabfb
CHORE: remove redundant divider subscription rebinding
Chethin Oct 25, 2024
0e428ab
CHORE: remove welcome-text after making entire sentence link
Chethin Oct 25, 2024
c72d89d
CHORE: revert lines to make PR cleaner
Chethin Oct 25, 2024
3ccd6d3
Merge branch 'main' into issue-96
chethin-ANU Oct 25, 2024
1dcf28e
FEAT: update JabRef_en.properties with localisation keys
Chethin Oct 26, 2024
f83de2a
Merge remote-tracking branch 'origin/issue-96' into issue-96
Chethin Oct 26, 2024
e346076
CHORE: remove welcome page javadocs
Chethin Oct 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We added a different background color to the search bar to indicate when the search syntax is wrong. [#11658](https://github.com/JabRef/jabref/pull/11658)
- We added a setting which always adds the literal "Cited on pages" text before each JStyle citation. [#11691](https://github.com/JabRef/jabref/pull/11732)
- We added a new plain citation parser that uses LLMs. [#11825](https://github.com/JabRef/jabref/issues/11825)
- We added a welcome screen that displays when no database is open [koppor#96](https://github.com/koppor/jabref/issues/96)
- We added a compare button to the duplicates in the citation relations tab to open the "Possible duplicate entries" window. [#11192](https://github.com/JabRef/jabref/issues/11192)
- We added automatic browser extension install on Windows for Chrome and Edge. [#6076](https://github.com/JabRef/jabref/issues/6076)
- We added a search bar for filtering keyboard shortcuts. [#11686](https://github.com/JabRef/jabref/issues/11686)
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/jabref/gui/Base.css
Original file line number Diff line number Diff line change
Expand Up @@ -1732,5 +1732,25 @@ We want to have a look that matches our icons in the tool-bar */
-fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.6), 8, 0.0, 0, 0);
}

/* Welcome Page Styles */
.welcome-label {
-fx-font-size: 40px;
-fx-text-fill: -jr-theme-text;
-fx-font-family: "Arial";
}

.welcome-text {
-fx-font-size: 22px;
-fx-text-fill: -jr-gray-3;
}

.welcome-hyperlink {
-fx-font-size: 22px;
-fx-text-fill: -jr-theme;
}

.welcome-hyperlink:visited {
-fx-text-fill: -jr-theme;
}

/* endregion */
10 changes: 4 additions & 6 deletions src/main/java/org/jabref/gui/JabRefGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,10 @@ public static void setup(List<UiCommand> uiCommands,
public void start(Stage stage) {
this.mainStage = stage;

FallbackExceptionHandler.installExceptionHandler((exception, thread) -> {
UiTaskExecutor.runInJavaFXThread(() -> {
DialogService dialogService = Injector.instantiateModelOrService(DialogService.class);
dialogService.showErrorDialogAndWait("Uncaught exception occurred in " + thread, exception);
});
});
FallbackExceptionHandler.installExceptionHandler((exception, thread) -> UiTaskExecutor.runInJavaFXThread(() -> {
DialogService dialogService = Injector.instantiateModelOrService(DialogService.class);
dialogService.showErrorDialogAndWait("Uncaught exception occurred in " + thread, exception);
}));

initialize();

Expand Down
74 changes: 72 additions & 2 deletions src/main/java/org/jabref/gui/frame/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import javafx.scene.control.TabPane;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

Expand All @@ -45,6 +46,7 @@
import org.jabref.gui.sidepane.SidePane;
import org.jabref.gui.sidepane.SidePaneType;
import org.jabref.gui.undo.CountingUndoManager;
import org.jabref.gui.util.WelcomePage;
import org.jabref.logic.UiCommand;
import org.jabref.logic.ai.AiService;
import org.jabref.logic.journals.JournalAbbreviationRepository;
Expand Down Expand Up @@ -99,6 +101,9 @@ public class JabRefFrame extends BorderPane implements LibraryTabContainer, UiMe

private Subscription dividerSubscription;

private final WelcomePage welcomePage;
private final StackPane contentPane = new StackPane(); // Holds both WelcomePage and TabPane

public JabRefFrame(Stage mainStage,
DialogService dialogService,
FileUpdateMonitor fileUpdateMonitor,
Expand All @@ -120,6 +125,19 @@ public JabRefFrame(Stage mainStage,
this.clipBoardManager = clipBoardManager;
this.taskExecutor = taskExecutor;

this.welcomePage = new WelcomePage(
this,
preferences,
aiService,
dialogService,
stateManager,
fileUpdateMonitor,
entryTypesManager,
undoManager,
clipBoardManager,
taskExecutor
);

setId("frame");

// Create components
Expand Down Expand Up @@ -181,10 +199,13 @@ public JabRefFrame(Stage mainStage,
}
});

// Initialize layout and bindings
initLayout();
initKeyBindings();
frameDndHandler.initDragAndDrop();
initBindings();
bindDatabaseChanges();
updateContent();
}

private void initLayout() {
Expand Down Expand Up @@ -223,12 +244,42 @@ private void initLayout() {
head.setSpacing(0d);
setTop(head);

splitPane.getItems().addAll(tabbedPane);
contentPane.getChildren().addAll(welcomePage, tabbedPane);
splitPane.getItems().add(contentPane);

SplitPane.setResizableWithParent(sidePane, false);
sidePane.widthProperty().addListener(c -> updateSidePane());
sidePane.getChildren().addListener((InvalidationListener) c -> updateSidePane());
updateSidePane();

setCenter(splitPane);
updateContent(); // Ensure layout is consistent on load
}

private void updateContent() {
boolean hasOpenDatabases = !stateManager.getOpenDatabases().isEmpty();

// Toggle visibility between welcome page and tabbed pane
welcomePage.setVisible(!hasOpenDatabases);
tabbedPane.setVisible(hasOpenDatabases);

if (hasOpenDatabases) {
if (!splitPane.getItems().contains(sidePane)) {
sidePane.setPrefWidth(260);
splitPane.getItems().addFirst(sidePane);

// Ensure divider position is set before rendering
splitPane.setDividerPositions(0.2);

// Ensure smooth transition by updating the layout immediately
Platform.runLater(() -> splitPane.setDividerPositions(0.2));
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand that. Both values are equal. I think, only the statement on line 271 is required?

The code of org.jabref.gui.frame.JabRefFrame#updateDividerPosition shows different values. I think you should just call

splitPane.setDividerPositions(preferences.getGuiPreferences().getSidePaneWidth() / splitPane.getWidth());

Copy link
Author

Choose a reason for hiding this comment

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

You are right - splitPane.setDividerPositions(preferences.getGuiPreferences().getSidePaneWidth() / splitPane.getWidth()); works fine!

eab1844

}
} else {
splitPane.getItems().remove(sidePane);
}
}

private void bindDatabaseChanges() {
stateManager.getOpenDatabases().addListener((InvalidationListener) obs -> Platform.runLater(this::updateContent));
}

private void updateSidePane() {
Expand Down Expand Up @@ -446,12 +497,31 @@ public void addTab(@NonNull BibDatabaseContext databaseContext, boolean raisePan

public void addTab(@NonNull LibraryTab libraryTab, boolean raisePanel) {
tabbedPane.getTabs().add(libraryTab);

if (raisePanel) {
tabbedPane.getSelectionModel().select(libraryTab);
tabbedPane.requestFocus();
}

libraryTab.setContextMenu(createTabContextMenuFor(libraryTab));

// Ensure layout is updated
updateContent();
updateSidePane();

// Set the preferred width and divider position explicitly
sidePane.setPrefWidth(260);
Copy link
Member

Choose a reason for hiding this comment

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

260 is a new value. Should be stored as constant in this class. - Why is sidePane used and not SplitPane?

Platform.runLater(() -> {
if (!sidePane.getChildren().isEmpty() && !splitPane.getItems().contains(sidePane)) {
splitPane.getItems().addFirst(sidePane);

// Force divider to a known position (e.g., 0.2 of the total width)
LOGGER.info("Forcing divider position after adding tab.");
splitPane.setDividerPositions(0.2);
Copy link
Member

Choose a reason for hiding this comment

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

See above.


updateDividerPosition(); // Ensure any further updates are applied
}
});
}

private ContextMenu createTabContextMenuFor(LibraryTab tab) {
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/org/jabref/gui/util/WelcomePage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.jabref.gui.util;

import javafx.geometry.Pos;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;

import org.jabref.gui.ClipBoardManager;
import org.jabref.gui.DialogService;
import org.jabref.gui.StateManager;
import org.jabref.gui.frame.JabRefFrame;
import org.jabref.gui.importer.NewDatabaseAction;
import org.jabref.gui.importer.actions.OpenDatabaseAction;
import org.jabref.gui.preferences.GuiPreferences;
import org.jabref.gui.undo.CountingUndoManager;
import org.jabref.logic.ai.AiService;
import org.jabref.logic.util.TaskExecutor;
import org.jabref.model.entry.BibEntryTypesManager;
import org.jabref.model.util.FileUpdateMonitor;

/**
* A simple Welcome Page for the JabRef application.
*/
Copy link
Member

Choose a reason for hiding this comment

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

Remove JavaDoc - the class name already says this.

Choose a reason for hiding this comment

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

Noted thanks! comments removed

public class WelcomePage extends VBox {

public WelcomePage(JabRefFrame frame,
GuiPreferences preferences,
AiService aiService,
DialogService dialogService,
StateManager stateManager,
FileUpdateMonitor fileUpdateMonitor,
BibEntryTypesManager entryTypesManager,
CountingUndoManager undoManager,
ClipBoardManager clipBoardManager,
TaskExecutor taskExecutor) {

setAlignment(Pos.CENTER);
setSpacing(10);

// Title
Label welcomeLabel = new Label("Welcome to JabRef!");
Copy link
Member

Choose a reason for hiding this comment

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

This is not translated. You need to use Localization.lang. See https://devdocs.jabref.org/code-howtos/localization.html#localization for details.

@InAnYan How did you do it in the AiTab with links and sentences? Did we come up with a good solution.

@HaynesCrossley-ANU I am asking for help here, because for translation, we aim for translating whole sentences. Reason: In different languages, the ordering of words within a sentence is different. (Because the grammar differs from langauge to langauge)

welcomeLabel.getStyleClass().add("welcome-label");

// Text and hyperlink for "New Library"
Text openNewLibraryText = new Text("Open a ");
openNewLibraryText.getStyleClass().add("welcome-text");

Hyperlink newLibraryLink = new Hyperlink("New Library");
newLibraryLink.getStyleClass().add("welcome-hyperlink");
newLibraryLink.setOnAction(e -> new NewDatabaseAction(frame, preferences).execute());

// Text and hyperlink for "Open Library"
Hyperlink openLibraryLink = new Hyperlink("Existing Library");
openLibraryLink.getStyleClass().add("welcome-hyperlink");
openLibraryLink.setOnAction(e -> new OpenDatabaseAction(frame, preferences, aiService, dialogService,
stateManager, fileUpdateMonitor, entryTypesManager, undoManager, clipBoardManager,
taskExecutor).execute());

Text orExistingDatabaseText = new Text(" or open an ");
orExistingDatabaseText.getStyleClass().add("welcome-text");

// TextFlows for each section
TextFlow newLibraryFlow = new TextFlow(openNewLibraryText, newLibraryLink);
newLibraryFlow.setTextAlignment(TextAlignment.CENTER);

TextFlow openLibraryFlow = new TextFlow(orExistingDatabaseText, openLibraryLink);
openLibraryFlow.setTextAlignment(TextAlignment.CENTER);

// Add elements to the VBox
Copy link
Member

Choose a reason for hiding this comment

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

Do not add comments just stating the words of the statement. You can remove these kinds of comments.

Copy link
Author

Choose a reason for hiding this comment

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

Noted thank you - comments removed.

e15cdb9

getChildren().addAll(welcomeLabel, newLibraryFlow, openLibraryFlow);
}
}
Loading