22
33import java .io .File ;
44import java .nio .file .Path ;
5- import java .util .Collection ;
65import java .util .Collections ;
76import java .util .HashMap ;
87import java .util .LinkedList ;
4342import org .jabref .gui .menus .ChangeEntryTypeMenu ;
4443import org .jabref .gui .mergeentries .FetchAndMergeEntry ;
4544import org .jabref .gui .preferences .GuiPreferences ;
45+ import org .jabref .gui .preview .PreviewPanel ;
4646import org .jabref .gui .theme .ThemeManager ;
4747import org .jabref .gui .undo .CountingUndoManager ;
4848import org .jabref .gui .undo .RedoAction ;
6969import com .tobiasdiez .easybind .EasyBind ;
7070import com .tobiasdiez .easybind .Subscription ;
7171import jakarta .inject .Inject ;
72+ import org .jspecify .annotations .NonNull ;
7273import org .slf4j .Logger ;
7374import org .slf4j .LoggerFactory ;
7475
@@ -91,6 +92,7 @@ public class EntryEditor extends BorderPane {
9192 private final BibDatabaseContext databaseContext ;
9293 private final EntryEditorPreferences entryEditorPreferences ;
9394 private final ExternalFilesEntryLinker fileLinker ;
95+ private final PreviewPanel previewPanel ;
9496 private final DirectoryMonitorManager directoryMonitorManager ;
9597 private final UndoAction undoAction ;
9698 private final RedoAction redoAction ;
@@ -121,7 +123,6 @@ public class EntryEditor extends BorderPane {
121123 @ Inject private AiService aiService ;
122124
123125 private final List <EntryEditorTab > allPossibleTabs ;
124- private final Collection <OffersPreview > previewTabs ;
125126
126127 public EntryEditor (LibraryTab libraryTab , UndoAction undoAction , RedoAction redoAction ) {
127128 this .libraryTab = libraryTab ;
@@ -135,14 +136,22 @@ public EntryEditor(LibraryTab libraryTab, UndoAction undoAction, RedoAction redo
135136 .load ();
136137
137138 this .entryEditorPreferences = preferences .getEntryEditorPreferences ();
138- this .fileLinker = new ExternalFilesEntryLinker (preferences .getExternalApplicationsPreferences (), preferences .getFilePreferences (), databaseContext , dialogService );
139+ this .fileLinker = new ExternalFilesEntryLinker (preferences .getExternalApplicationsPreferences (), preferences .getFilePreferences (), dialogService , stateManager );
140+ this .previewPanel = new PreviewPanel (
141+ dialogService ,
142+ preferences .getKeyBindingRepository (),
143+ preferences ,
144+ themeManager ,
145+ taskExecutor ,
146+ stateManager ,
147+ libraryTab .searchQueryProperty ());
148+ this .previewPanel .setDatabase (databaseContext );
139149
140150 setupKeyBindings ();
141151
142152 this .allPossibleTabs = createTabs ();
143- this .previewTabs = this .allPossibleTabs .stream ().filter (OffersPreview .class ::isInstance ).map (OffersPreview .class ::cast ).toList ();
144153
145- setupDragAndDrop (libraryTab );
154+ setupDragAndDrop ();
146155
147156 EasyBind .subscribe (tabbed .getSelectionModel ().selectedItemProperty (), tab -> {
148157 EntryEditorTab activeTab = (EntryEditorTab ) tab ;
@@ -155,11 +164,18 @@ public EntryEditor(LibraryTab libraryTab, UndoAction undoAction, RedoAction redo
155164 (obs , oldValue , newValue ) -> {
156165 if (currentlyEditedEntry != null ) {
157166 adaptVisibleTabs ();
167+ Tab tab = tabbed .getSelectionModel ().selectedItemProperty ().get ();
168+ if (newValue && tab instanceof FieldsEditorTab fieldsEditorTab ) {
169+ fieldsEditorTab .removePreviewPanelFromThisTab ();
170+ }
171+ if (tab instanceof TabWithPreviewPanel previewTab ) {
172+ previewTab .handleFocus ();
173+ }
158174 }
159175 });
160176 }
161177
162- private void setupDragAndDrop (LibraryTab libraryTab ) {
178+ private void setupDragAndDrop () {
163179 this .setOnDragOver (event -> {
164180 if (event .getDragboard ().hasFiles ()) {
165181 event .acceptTransferModes (TransferMode .COPY , TransferMode .MOVE , TransferMode .LINK );
@@ -267,21 +283,21 @@ private void navigateToNextEntry() {
267283 private List <EntryEditorTab > createTabs () {
268284 List <EntryEditorTab > tabs = new LinkedList <>();
269285
270- tabs .add (new PreviewTab (databaseContext , dialogService , preferences , themeManager , taskExecutor , libraryTab . searchQueryProperty () ));
286+ tabs .add (new PreviewTab (databaseContext , preferences , previewPanel ));
271287
272288 // Required, optional (important+detail), deprecated, and "other" fields
273- tabs .add (new RequiredFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , dialogService , preferences , themeManager , bibEntryTypesManager , taskExecutor , journalAbbreviationRepository , libraryTab . searchQueryProperty () ));
274- tabs .add (new ImportantOptionalFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , dialogService , preferences , themeManager , bibEntryTypesManager , taskExecutor , journalAbbreviationRepository , libraryTab . searchQueryProperty () ));
275- tabs .add (new DetailOptionalFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , dialogService , preferences , themeManager , bibEntryTypesManager , taskExecutor , journalAbbreviationRepository , libraryTab . searchQueryProperty () ));
276- tabs .add (new DeprecatedFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , dialogService , preferences , themeManager , bibEntryTypesManager , taskExecutor , journalAbbreviationRepository , libraryTab . searchQueryProperty () ));
277- tabs .add (new OtherFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , dialogService , preferences , themeManager , bibEntryTypesManager , taskExecutor , journalAbbreviationRepository , libraryTab . searchQueryProperty () ));
289+ tabs .add (new RequiredFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , preferences , bibEntryTypesManager , journalAbbreviationRepository , previewPanel ));
290+ tabs .add (new ImportantOptionalFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , preferences , bibEntryTypesManager , journalAbbreviationRepository , previewPanel ));
291+ tabs .add (new DetailOptionalFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , preferences , bibEntryTypesManager , journalAbbreviationRepository , previewPanel ));
292+ tabs .add (new DeprecatedFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , preferences , bibEntryTypesManager , journalAbbreviationRepository , previewPanel ));
293+ tabs .add (new OtherFieldsTab (databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , preferences , bibEntryTypesManager , journalAbbreviationRepository , previewPanel ));
278294
279295 // Comment Tab: Tab for general and user-specific comments
280- tabs .add (new CommentsTab (preferences , databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , dialogService , themeManager , taskExecutor , journalAbbreviationRepository , libraryTab . searchQueryProperty () ));
296+ tabs .add (new CommentsTab (preferences , databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , journalAbbreviationRepository , previewPanel ));
281297
282298 Map <String , Set <Field >> entryEditorTabList = getAdditionalUserConfiguredTabs ();
283299 for (Map .Entry <String , Set <Field >> tab : entryEditorTabList .entrySet ()) {
284- tabs .add (new UserDefinedFieldsTab (tab .getKey (), tab .getValue (), databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , dialogService , preferences , themeManager , taskExecutor , journalAbbreviationRepository , libraryTab . searchQueryProperty () ));
300+ tabs .add (new UserDefinedFieldsTab (tab .getKey (), tab .getValue (), databaseContext , libraryTab .getSuggestionProviders (), undoManager , undoAction , redoAction , preferences , journalAbbreviationRepository , previewPanel ));
285301 }
286302
287303 tabs .add (new MathSciNetTab ());
@@ -374,8 +390,12 @@ public BibEntry getCurrentlyEditedEntry() {
374390 return currentlyEditedEntry ;
375391 }
376392
377- public void setCurrentlyEditedEntry (BibEntry currentlyEditedEntry ) {
378- this .currentlyEditedEntry = Objects .requireNonNull (currentlyEditedEntry );
393+ public void setCurrentlyEditedEntry (@ NonNull BibEntry currentlyEditedEntry ) {
394+ if (Objects .equals (this .currentlyEditedEntry , currentlyEditedEntry )) {
395+ return ;
396+ }
397+
398+ this .currentlyEditedEntry = currentlyEditedEntry ;
379399
380400 // Subscribe to type changes for rebuilding the currently visible tab
381401 if (typeSubscription != null ) {
@@ -385,16 +405,13 @@ public void setCurrentlyEditedEntry(BibEntry currentlyEditedEntry) {
385405 typeSubscription = EasyBind .subscribe (this .currentlyEditedEntry .typeProperty (), type -> {
386406 typeLabel .setText (new TypedBibEntry (currentlyEditedEntry , databaseContext .getMode ()).getTypeForDisplay ());
387407 adaptVisibleTabs ();
408+ setupToolBar ();
388409 getSelectedTab ().notifyAboutFocus (currentlyEditedEntry );
389410 });
390411
391- adaptVisibleTabs ();
392- setupToolBar ();
393-
394412 if (entryEditorPreferences .showSourceTabByDefault ()) {
395413 tabbed .getSelectionModel ().select (sourceTab );
396414 }
397- getSelectedTab ().notifyAboutFocus (currentlyEditedEntry );
398415 }
399416
400417 private EntryEditorTab getSelectedTab () {
@@ -457,10 +474,10 @@ public void setFocusToField(Field field) {
457474 }
458475
459476 public void nextPreviewStyle () {
460- this .previewTabs . forEach ( OffersPreview :: nextPreviewStyle );
477+ this .previewPanel . nextPreviewStyle ( );
461478 }
462479
463480 public void previousPreviewStyle () {
464- this .previewTabs . forEach ( OffersPreview :: previousPreviewStyle );
481+ this .previewPanel . previousPreviewStyle ( );
465482 }
466483}
0 commit comments