2
2
3
3
import java .io .IOException ;
4
4
import java .nio .file .Paths ;
5
+ import java .util .ArrayList ;
5
6
import java .util .Optional ;
6
7
import java .util .regex .Pattern ;
7
8
import java .util .regex .PatternSyntaxException ;
8
9
9
10
import javafx .beans .value .ChangeListener ;
10
11
import javafx .beans .value .ObservableValue ;
11
12
import javafx .geometry .Insets ;
13
+ import javafx .geometry .Orientation ;
12
14
import javafx .scene .Node ;
13
15
import javafx .scene .control .ButtonType ;
14
16
import javafx .scene .control .CheckBox ;
15
17
import javafx .scene .control .Label ;
16
18
import javafx .scene .control .RadioButton ;
17
19
import javafx .scene .control .ScrollPane ;
18
20
import javafx .scene .control .ScrollPane .ScrollBarPolicy ;
21
+ import javafx .scene .control .Separator ;
19
22
import javafx .scene .control .TextField ;
20
23
import javafx .scene .control .Toggle ;
21
24
import javafx .scene .control .ToggleGroup ;
26
29
import javafx .scene .text .FontPosture ;
27
30
import javafx .scene .text .Text ;
28
31
import javafx .scene .text .TextFlow ;
29
- import javafx .scene .web .WebView ;
30
32
31
33
import org .jabref .Globals ;
32
34
import org .jabref .JabRefGUI ;
@@ -104,7 +106,7 @@ class GroupDialog extends BaseDialog<AbstractGroup> {
104
106
private final TextField texGroupFilePath = new TextField ();
105
107
106
108
// for all types
107
- private final WebView descriptionWebView = new WebView ();
109
+ private final TextFlow descriptionTextFlow = new TextFlow ();
108
110
private final StackPane optionsPanel = new StackPane ();
109
111
110
112
@@ -120,7 +122,10 @@ public GroupDialog(JabRefFrame jabrefFrame, AbstractGroup editedGroup) {
120
122
121
123
explicitRadioButton .setSelected (true );
122
124
123
- descriptionWebView .setPrefWidth (585 );
125
+ descriptionTextFlow .setMinWidth (585 );
126
+ descriptionTextFlow .setPrefWidth (585 );
127
+ descriptionTextFlow .setMinHeight (180 );
128
+ descriptionTextFlow .setPrefHeight (180 );
124
129
125
130
// set default values (overwritten if editedGroup != null)
126
131
keywordGroupSearchField .setText (jabrefFrame .prefs ().get (JabRefPreferences .GROUPS_DEFAULT_FIELD ));
@@ -196,26 +201,31 @@ public GroupDialog(JabRefFrame jabrefFrame, AbstractGroup editedGroup) {
196
201
selectPanel .setPadding (new Insets (0 , 0 , 0 , 10 ));
197
202
198
203
// Description panel
199
- ScrollPane descriptionPane = new ScrollPane (descriptionWebView );
204
+ ScrollPane descriptionPane = new ScrollPane (descriptionTextFlow );
200
205
descriptionPane .setHbarPolicy (ScrollBarPolicy .AS_NEEDED );
201
206
descriptionPane .setVbarPolicy (ScrollBarPolicy .AS_NEEDED );
202
207
203
208
// create layout
204
- VBox mainPanel = new VBox (15 );
209
+ HBox mainPanel = new HBox (15 );
205
210
getDialogPane ().setContent (mainPanel );
206
211
mainPanel .setPadding (new Insets (5 , 15 , 5 , 15 ));
207
212
mainPanel .getChildren ().setAll (
208
- generalPanel ,
209
213
new VBox (5 ,
210
- new Label (Localization .lang ("Type" )),
211
- selectPanel
212
- ),
213
- new VBox (
214
- new Label (Localization .lang ("Options" )),
215
- optionsPanel
214
+ generalPanel ,
215
+ new VBox (5 ,
216
+ new Label (Localization .lang ("Type" )),
217
+ selectPanel
218
+ )
216
219
),
217
- new Label (Localization .lang ("Description" )),
218
- descriptionPane
220
+ new Separator (Orientation .VERTICAL ),
221
+ new VBox (5 ,
222
+ new VBox (
223
+ new Label (Localization .lang ("Options" )),
224
+ optionsPanel
225
+ ),
226
+ new Label (Localization .lang ("Description" )),
227
+ descriptionPane
228
+ )
219
229
);
220
230
221
231
updateComponents ();
@@ -393,6 +403,9 @@ groupName, getContext(),
393
403
texGroupFilePath .setText (group .getFilePath ().toString ());
394
404
}
395
405
}
406
+
407
+ setResizable (false );
408
+ getDialogPane ().getScene ().getWindow ().sizeToScene ();
396
409
}
397
410
398
411
public GroupDialog () {
@@ -517,7 +530,7 @@ private void updateComponents() {
517
530
boolean okEnabled = !nameField .getText ().trim ().isEmpty ();
518
531
if (!okEnabled ) {
519
532
setDescription (Localization .lang ("Please enter a name for the group." ));
520
- //TODO: okButton .setDisable(true);
533
+ getDialogPane (). lookupButton ( ButtonType . OK ) .setDisable (true );
521
534
return ;
522
535
}
523
536
String s1 ;
@@ -532,27 +545,27 @@ private void updateComponents() {
532
545
try {
533
546
Pattern .compile (s2 );
534
547
setDescription (GroupDescriptions .getDescriptionForPreview (s1 , s2 , keywordGroupCaseSensitive .isSelected (),
535
- keywordGroupRegExp .isSelected ()));
548
+ keywordGroupRegExp .isSelected ()));
536
549
} catch (PatternSyntaxException e ) {
537
550
okEnabled = false ;
538
551
setDescription (formatRegExException (s2 , e ));
539
552
}
540
553
} else {
541
554
setDescription (GroupDescriptions .getDescriptionForPreview (s1 , s2 , keywordGroupCaseSensitive .isSelected (),
542
- keywordGroupRegExp .isSelected ()));
555
+ keywordGroupRegExp .isSelected ()));
543
556
}
544
557
} else {
545
558
setDescription (Localization .lang (
546
- "Please enter the field to search (e.g. <b>keywords</b>) and the keyword to search it for (e.g. <b>electrical</b>)." ));
559
+ "Please enter the field to search (e.g. <b>keywords</b>) and the keyword to search it for (e.g. <b>electrical</b>)." ));
547
560
}
548
561
setNameFontItalic (true );
549
562
} else if (searchRadioButton .isSelected ()) {
550
563
s1 = searchGroupSearchExpression .getText ().trim ();
551
564
okEnabled = okEnabled & !s1 .isEmpty ();
552
565
if (okEnabled ) {
553
566
setDescription (fromTextFlowToHTMLString (SearchDescribers .getSearchDescriberFor (
554
- new SearchQuery (s1 , isCaseSensitive (), isRegex ()))
555
- .getDescription ()));
567
+ new SearchQuery (s1 , isCaseSensitive (), isRegex ()))
568
+ .getDescription ()));
556
569
557
570
if (isRegex ()) {
558
571
try {
@@ -564,17 +577,17 @@ private void updateComponents() {
564
577
}
565
578
} else {
566
579
setDescription (Localization
567
- .lang ("Please enter a search term. For example, to search all fields for <b>Smith</b>, enter:<p>"
568
- + "<tt>smith</tt><p>"
569
- + "To search the field <b>Author</b> for <b>Smith</b> and the field <b>Title</b> for <b>electrical</b>, enter:<p>"
570
- + "<tt>author=smith and title=electrical</tt>" ));
580
+ .lang ("Please enter a search term. For example, to search all fields for <b>Smith</b>, enter:<p>"
581
+ + "<tt>smith</tt><p>"
582
+ + "To search the field <b>Author</b> for <b>Smith</b> and the field <b>Title</b> for <b>electrical</b>, enter:<p>"
583
+ + "<tt>author=smith and title=electrical</tt>" ));
571
584
}
572
585
setNameFontItalic (true );
573
586
} else if (explicitRadioButton .isSelected ()) {
574
587
setDescription (GroupDescriptions .getDescriptionForPreview ());
575
588
setNameFontItalic (false );
576
589
}
577
- //TODO: okButton .setDisable(!okEnabled);
590
+ getDialogPane (). lookupButton ( ButtonType . OK ) .setDisable (!okEnabled );
578
591
}
579
592
580
593
private String fromTextFlowToHTMLString (TextFlow textFlow ) {
@@ -596,7 +609,45 @@ private boolean isCaseSensitive() {
596
609
}
597
610
598
611
private void setDescription (String description ) {
599
- descriptionWebView .getEngine ().loadContent ("<html>" + description + "</html>" );
612
+ descriptionTextFlow .getChildren ().setAll (createFormattedDescription (description ));
613
+ }
614
+
615
+ private ArrayList <Node > createFormattedDescription (String description ) {
616
+ ArrayList <Node > nodes = new ArrayList <>();
617
+
618
+ description = description .replaceAll ("<p>|<br>" , "\n " );
619
+
620
+ String [] boldSplit = description .split ("(?=<b>)|(?<=</b>)|(?=<i>)|(?<=</i>)|(?=<tt>)|(?<=</tt>)|(?=<kbd>)|(?<=</kbd>)" );
621
+
622
+ for (String bs : boldSplit ) {
623
+
624
+ if (bs .matches ("<b>[^<>]*</b>" )) {
625
+
626
+ bs = bs .replaceAll ("<b>|</b>" , "" );
627
+ Text textElement = new Text (bs );
628
+ textElement .setStyle ("-fx-font-weight: bold" );
629
+ nodes .add (textElement );
630
+
631
+ } else if (bs .matches ("<i>[^<>]*</i>" )) {
632
+
633
+ bs = bs .replaceAll ("<i>|</i>" , "" );
634
+ Text textElement = new Text (bs );
635
+ textElement .setStyle ("-fx-font-style: italic" );
636
+ nodes .add (textElement );
637
+
638
+ } else if (bs .matches ("<tt>[^<>]*</tt>|<kbd>[^<>]*</kbd>" )) {
639
+
640
+ bs = bs .replaceAll ("<tt>|</tt>|<kbd>|</kbd>" , "" );
641
+ Text textElement = new Text (bs );
642
+ textElement .setStyle ("-fx-font-family: 'Courier New', Courier, monospace" );
643
+ nodes .add (textElement );
644
+
645
+ } else {
646
+ nodes .add (new Text (bs ));
647
+ }
648
+ }
649
+
650
+ return nodes ;
600
651
}
601
652
602
653
/**
0 commit comments