20
20
import javafx .scene .control .Button ;
21
21
import javafx .scene .control .ButtonType ;
22
22
import javafx .scene .control .DialogPane ;
23
+ import javafx .scene .control .Hyperlink ;
23
24
import javafx .scene .control .Label ;
24
25
import javafx .scene .control .ProgressIndicator ;
25
26
import javafx .scene .control .ScrollPane ;
52
53
import org .jabref .logic .citation .SearchCitationsRelationsService ;
53
54
import org .jabref .logic .database .DuplicateCheck ;
54
55
import org .jabref .logic .exporter .BibWriter ;
56
+ import org .jabref .logic .importer .fetcher .CrossRef ;
55
57
import org .jabref .logic .importer .fetcher .citation .CitationFetcher ;
56
58
import org .jabref .logic .l10n .Localization ;
57
59
import org .jabref .logic .os .OS ;
@@ -199,48 +201,34 @@ private SplitPane getPaneAndStartSearch(BibEntry entry) {
199
201
citingVBox .getChildren ().addAll (citingHBox , citingListView );
200
202
citedByVBox .getChildren ().addAll (citedByHBox , citedByListView );
201
203
202
- refreshCitingButton .setOnMouseClicked (_ -> {
203
- searchForRelations (
204
- entry ,
205
- citingListView ,
206
- abortCitingButton ,
207
- refreshCitingButton ,
208
- CitationFetcher .SearchType .CITES ,
209
- importCitingButton ,
210
- citingProgress );
211
- });
204
+ CitationComponents citingComponents = new CitationComponents (
205
+ entry ,
206
+ citingListView ,
207
+ abortCitingButton ,
208
+ refreshCitingButton ,
209
+ CitationFetcher .SearchType .CITES ,
210
+ importCitingButton ,
211
+ citingProgress );
212
212
213
- refreshCitedByButton . setOnMouseClicked ( _ -> searchForRelations (
214
- entry ,
215
- citedByListView ,
213
+ CitationComponents citedByComponents = new CitationComponents (
214
+ entry ,
215
+ citedByListView ,
216
216
abortCitedButton ,
217
- refreshCitedByButton ,
218
- CitationFetcher .SearchType .CITED_BY ,
219
- importCitedByButton ,
220
- citedByProgress ));
217
+ refreshCitedByButton ,
218
+ CitationFetcher .SearchType .CITED_BY ,
219
+ importCitedByButton ,
220
+ citedByProgress );
221
+
222
+ refreshCitingButton .setOnMouseClicked (_ -> searchForRelations (citingComponents , citedByComponents ));
223
+ refreshCitedByButton .setOnMouseClicked (_ -> searchForRelations (citedByComponents , citingComponents ));
221
224
222
225
// Create SplitPane to hold all nodes above
223
226
SplitPane container = new SplitPane (citingVBox , citedByVBox );
224
227
styleFetchedListView (citedByListView );
225
228
styleFetchedListView (citingListView );
226
229
227
- searchForRelations (
228
- entry ,
229
- citingListView ,
230
- abortCitingButton ,
231
- refreshCitingButton ,
232
- CitationFetcher .SearchType .CITES ,
233
- importCitingButton ,
234
- citingProgress );
235
-
236
- searchForRelations (
237
- entry ,
238
- citedByListView ,
239
- abortCitedButton ,
240
- refreshCitedByButton ,
241
- CitationFetcher .SearchType .CITED_BY ,
242
- importCitedByButton ,
243
- citedByProgress );
230
+ searchForRelations (citingComponents , citedByComponents );
231
+ searchForRelations (citedByComponents , citingComponents );
244
232
245
233
return container ;
246
234
}
@@ -271,9 +259,9 @@ private void styleFetchedListView(CheckListView<CitationRelationItem> listView)
271
259
jumpTo .getStyleClass ().add ("addEntryButton" );
272
260
jumpTo .setOnMouseClicked (_ -> jumpToEntry (entry ));
273
261
hContainer .setOnMouseClicked (event -> {
274
- if (event .getClickCount () == 2 ) {
275
- jumpToEntry (entry );
276
- }
262
+ if (event .getClickCount () == 2 ) {
263
+ jumpToEntry (entry );
264
+ }
277
265
});
278
266
vContainer .getChildren ().add (jumpTo );
279
267
@@ -423,59 +411,89 @@ protected void bindToEntry(BibEntry entry) {
423
411
setContent (getPaneAndStartSearch (entry ));
424
412
}
425
413
426
- /**
427
- * Method to start search for relations and display them in the associated ListView
428
- *
429
- * @param entry BibEntry currently selected in Jabref Database
430
- * @param listView ListView to use
431
- * @param abortButton Button to stop the search
432
- * @param refreshButton refresh Button to use
433
- * @param searchType type of search (CITING / CITEDBY)
434
- */
435
- private void searchForRelations (BibEntry entry , CheckListView <CitationRelationItem > listView , Button abortButton ,
436
- Button refreshButton , CitationFetcher .SearchType searchType , Button importButton ,
437
- ProgressIndicator progress ) {
438
- if (entry .getDOI ().isEmpty ()) {
439
- hideNodes (abortButton , progress );
440
- showNodes (refreshButton );
441
- listView .getItems ().clear ();
442
- listView .setPlaceholder (
443
- new Label (Localization .lang ("The selected entry doesn't have a DOI linked to it. Lookup a DOI and try again." )));
414
+ private void searchForRelations (CitationComponents citationComponents ,
415
+ CitationComponents otherCitationComponents ) {
416
+ if (citationComponents .entry ().getDOI ().isEmpty ()) {
417
+ setUpEmptyPanel (citationComponents , otherCitationComponents );
444
418
return ;
445
419
}
420
+ executeSearch (citationComponents );
421
+ }
446
422
447
- ObservableList <CitationRelationItem > observableList = FXCollections .observableArrayList ();
423
+ private void setUpEmptyPanel (CitationComponents citationComponents ,
424
+ CitationComponents otherCitationComponents ) {
425
+ hideNodes (citationComponents .abortButton (), citationComponents .progress ());
426
+ showNodes (citationComponents .refreshButton ());
427
+
428
+ HBox hBox = new HBox ();
429
+ Label label = new Label (Localization .lang ("The selected entry doesn't have a DOI linked to it." ));
430
+ Hyperlink link = new Hyperlink (Localization .lang ("Look up a DOI and try again." ));
431
+
432
+ link .setOnAction (e -> {
433
+ CrossRef doiFetcher = new CrossRef ();
434
+
435
+ BackgroundTask .wrap (() -> doiFetcher .findIdentifier (citationComponents .entry ()))
436
+ .onRunning (() -> {
437
+ showNodes (citationComponents .progress (), otherCitationComponents .progress ());
438
+ setLabelOn (citationComponents .listView (), Localization .lang ("Looking up DOI..." ));
439
+ setLabelOn (otherCitationComponents .listView (), Localization .lang ("Looking up DOI..." ));
440
+ })
441
+ .onSuccess (identifier -> {
442
+ if (identifier .isPresent ()) {
443
+ citationComponents .entry ().setField (StandardField .DOI , identifier .get ().asString ());
444
+ executeSearch (citationComponents );
445
+ executeSearch (otherCitationComponents );
446
+ } else {
447
+ dialogService .notify (Localization .lang ("No DOI found" ));
448
+ setUpEmptyPanel (citationComponents , otherCitationComponents );
449
+ setUpEmptyPanel (otherCitationComponents , citationComponents );
450
+ }
451
+ }).onFailure (ex -> {
452
+ hideNodes (citationComponents .progress (), otherCitationComponents .progress ());
453
+ setLabelOn (citationComponents .listView (), "Error " + ex .getMessage ());
454
+ setLabelOn (otherCitationComponents .listView (), "Error " + ex .getMessage ());
455
+ }).executeWith (taskExecutor );
456
+ });
457
+
458
+ hBox .getChildren ().add (label );
459
+ hBox .getChildren ().add (link );
460
+ hBox .setSpacing (2d );
461
+ hBox .setStyle ("-fx-alignment: center;" );
462
+ hBox .setFillHeight (true );
463
+
464
+ citationComponents .listView ().getItems ().clear ();
465
+ citationComponents .listView ().setPlaceholder (hBox );
466
+ }
467
+
468
+ private static void setLabelOn (CheckListView <CitationRelationItem > listView , String message ) {
469
+ Label lookingUpDoiLabel = new Label (message );
470
+ listView .getItems ().clear ();
471
+ listView .setPlaceholder (lookingUpDoiLabel );
472
+ }
448
473
449
- listView .setItems (observableList );
474
+ private void executeSearch (CitationComponents citationComponents ) {
475
+ ObservableList <CitationRelationItem > observableList = FXCollections .observableArrayList ();
476
+ citationComponents .listView ().setItems (observableList );
450
477
451
478
// TODO: It should not be possible to cancel a search task that is already running for same tab
452
- if (citingTask != null && !citingTask .isCancelled () && searchType == CitationFetcher .SearchType .CITES ) {
479
+ if (citingTask != null && !citingTask .isCancelled () && citationComponents . searchType () == CitationFetcher .SearchType .CITES ) {
453
480
citingTask .cancel ();
454
- } else if (citedByTask != null && !citedByTask .isCancelled () && searchType == CitationFetcher .SearchType .CITED_BY ) {
481
+ } else if (citedByTask != null && !citedByTask .isCancelled () && citationComponents . searchType () == CitationFetcher .SearchType .CITED_BY ) {
455
482
citedByTask .cancel ();
456
483
}
457
484
458
- this .createBackgroundTask (entry , searchType )
459
- .consumeOnRunning (task -> prepareToSearchForRelations (
460
- abortButton , refreshButton , importButton , progress , task
461
- ))
462
- .onSuccess (fetchedList -> onSearchForRelationsSucceed (
463
- entry ,
464
- listView ,
465
- abortButton ,
466
- refreshButton ,
467
- searchType ,
468
- importButton ,
469
- progress ,
470
- fetchedList ,
471
- observableList
485
+ this .createBackgroundTask (citationComponents .entry (), citationComponents .searchType ())
486
+ .consumeOnRunning (task -> prepareToSearchForRelations (citationComponents , task ))
487
+ .onSuccess (fetchedList -> onSearchForRelationsSucceed (citationComponents ,
488
+ fetchedList ,
489
+ observableList
472
490
))
473
491
.onFailure (exception -> {
474
492
LOGGER .error ("Error while fetching citing Articles" , exception );
475
- hideNodes (abortButton , progress , importButton );
476
- listView .setPlaceholder (new Label (Localization .lang ("Error while fetching citing entries: %0" ,
493
+ hideNodes (citationComponents . abortButton (), citationComponents . progress (), citationComponents . importButton () );
494
+ citationComponents . listView () .setPlaceholder (new Label (Localization .lang ("Error while fetching citing entries: %0" ,
477
495
exception .getMessage ())));
478
- refreshButton .setVisible (true );
496
+ citationComponents . refreshButton () .setVisible (true );
479
497
dialogService .notify (exception .getMessage ());
480
498
})
481
499
.executeWith (taskExecutor );
@@ -503,15 +521,13 @@ private BackgroundTask<List<BibEntry>> createBackgroundTask(
503
521
};
504
522
}
505
523
506
- private void onSearchForRelationsSucceed (BibEntry entry , CheckListView <CitationRelationItem > listView ,
507
- Button abortButton , Button refreshButton ,
508
- CitationFetcher .SearchType searchType , Button importButton ,
509
- ProgressIndicator progress , List <BibEntry > fetchedList ,
524
+ private void onSearchForRelationsSucceed (CitationComponents citationComponents ,
525
+ List <BibEntry > fetchedList ,
510
526
ObservableList <CitationRelationItem > observableList ) {
511
- hideNodes (abortButton , progress );
512
527
513
- BibDatabase database = stateManager .getActiveDatabase ().map (BibDatabaseContext ::getDatabase )
514
- .orElse (new BibDatabase ());
528
+ hideNodes (citationComponents .abortButton (), citationComponents .progress ());
529
+
530
+ BibDatabase database = stateManager .getActiveDatabase ().map (BibDatabaseContext ::getDatabase ).orElse (new BibDatabase ());
515
531
observableList .setAll (
516
532
fetchedList .stream ().map (entr ->
517
533
duplicateCheck .containsDuplicate (
@@ -524,27 +540,26 @@ private void onSearchForRelationsSucceed(BibEntry entry, CheckListView<CitationR
524
540
);
525
541
526
542
if (!observableList .isEmpty ()) {
527
- listView .refresh ();
543
+ citationComponents . listView () .refresh ();
528
544
} else {
529
545
Label placeholder = new Label (Localization .lang ("No articles found" ));
530
- listView .setPlaceholder (placeholder );
546
+ citationComponents . listView () .setPlaceholder (placeholder );
531
547
}
532
- BooleanBinding booleanBind = Bindings .isEmpty (listView .getCheckModel ().getCheckedItems ());
533
- importButton .disableProperty ().bind (booleanBind );
534
- importButton .setOnMouseClicked (event -> importEntries (listView .getCheckModel ().getCheckedItems (), searchType , entry ));
535
- showNodes (refreshButton , importButton );
548
+ BooleanBinding booleanBind = Bindings .isEmpty (citationComponents . listView () .getCheckModel ().getCheckedItems ());
549
+ citationComponents . importButton () .disableProperty ().bind (booleanBind );
550
+ citationComponents . importButton () .setOnMouseClicked (event -> importEntries (citationComponents . listView () .getCheckModel ().getCheckedItems (), citationComponents . searchType (), citationComponents . entry () ));
551
+ showNodes (citationComponents . refreshButton (), citationComponents . importButton () );
536
552
}
537
553
538
- private void prepareToSearchForRelations (Button abortButton , Button refreshButton , Button importButton ,
539
- ProgressIndicator progress , BackgroundTask <List <BibEntry >> task ) {
540
- showNodes (abortButton , progress );
541
- hideNodes (refreshButton , importButton );
554
+ private void prepareToSearchForRelations (CitationComponents citationComponents , BackgroundTask <List <BibEntry >> task ) {
555
+ showNodes (citationComponents .abortButton (), citationComponents .progress ());
556
+ hideNodes (citationComponents .refreshButton (), citationComponents .importButton ());
542
557
543
- abortButton .setOnAction (event -> {
544
- hideNodes (abortButton , progress , importButton );
545
- showNodes (refreshButton );
558
+ citationComponents . abortButton () .setOnAction (event -> {
559
+ hideNodes (citationComponents . abortButton (), citationComponents . progress (), citationComponents . importButton () );
560
+ showNodes (citationComponents . refreshButton () );
546
561
task .cancel ();
547
- dialogService .notify (Localization .lang ("Search aborted! " ));
562
+ dialogService .notify (Localization .lang ("Search aborted. " ));
548
563
});
549
564
}
550
565
0 commit comments