1 package de.spiritscorp.datasync.gui;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.io.File;
24 import java.nio.file.Path;
25 import java.nio.file.Paths;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import javafx.collections.FXCollections;
30 import javafx.collections.ObservableList;
31 import javafx.scene.control.Button;
32 import javafx.scene.control.Label;
33 import javafx.scene.control.ListView;
34 import javafx.scene.control.Separator;
35 import javafx.scene.control.TextField;
36 import javafx.scene.layout.GridPane;
37 import javafx.scene.layout.HBox;
38 import javafx.scene.layout.VBox;
39 import javafx.stage.DirectoryChooser;
40 import javafx.stage.Stage;
41
42 import org.kordamp.ikonli.materialdesign2.MaterialDesignD;
43 import org.kordamp.ikonli.materialdesign2.MaterialDesignP;
44
45 import de.spiritscorp.datasync.ScanType;
46 import de.spiritscorp.datasync.io.Preference;
47 import de.spiritscorp.datasync.io.PreferenceManager;
48
49
50
51
52
53
54
55
56
57
58
59
60
61 class ContextPathRenderer {
62
63
64
65
66 private static final int H_GAP = 12;
67
68
69
70 private static final int V_GAP = 10;
71
72
73
74 private static final int LABEL_WIDTH = 170;
75
76
77
78 private static final int TEXT_FIELD_WIDTH = 400;
79
80
81
82 private static final int PATH_LIST_WIDTH = 600;
83
84
85
86 private static final int PATH_LIST_HEIGHT = 140;
87
88
89
90 private static final Path DEFAULT_PATH = PreferenceManager.getInstance().getRootPath();
91
92
93
94
95
96
97
98
99
100 void renderContextPaths( final VBox container, final Preference pref, final Stage primaryStage ) {
101 final ScanType type = pref.getScanMode();
102
103 container.getChildren().clear();
104
105 final GridPane pathsGrid = new GridPane();
106 pathsGrid.setHgap( H_GAP );
107 pathsGrid.setVgap( V_GAP );
108
109
110 final Label dirTitleLabel = new Label( "Verzeichnis-Konfiguration (" + type.getDescription() + ")" );
111 dirTitleLabel.getStyleClass().addAll( "dir-title-label" );
112 container.getChildren().add( dirTitleLabel );
113
114
115 if( ScanType.SYNCHRONIZE == type ) {
116 pathsGrid.add( getSourceBox( pref, primaryStage ), 0, 0, 2, 1 );
117 }else if( ScanType.FLAT_SCAN == type || ScanType.DEEP_SCAN == type || ScanType.DUBLICATE_SCAN == type ) {
118 pathsGrid.add( getSourceList( type, pref, primaryStage ), 0, 0, 2, 1 );
119 }
120
121
122 if( ScanType.FLAT_SCAN == type || ScanType.DEEP_SCAN == type || ScanType.SYNCHRONIZE == type ) {
123 pathsGrid.add( getDestBox( pref, primaryStage ), 0, 1, 2, 1 );
124 }
125
126 container.getChildren().add( pathsGrid );
127 }
128
129
130
131
132
133
134
135
136 private VBox getSourceBox( final Preference pref, final Stage primaryStage ) {
137 final GridPane destGrid = new GridPane();
138 destGrid.setHgap( H_GAP );
139 final String initialString = getInitialPath( pref.getSourcePaths() ).toString();
140 final TextField srcTextField = new TextField( initialString );
141 srcTextField.setPrefWidth( TEXT_FIELD_WIDTH );
142 final Button srcBtn = new Button( "Durchsuchen..." );
143 srcBtn.setOnAction( _ -> {
144 final File initialSrc = getInitialPath( pref.getSourcePaths() );
145 final File dirPath = chooseDirectory( initialSrc, "Arbeitsverzeichnis A für " + pref.getScanMode().getDescription(), primaryStage );
146 if( dirPath != null ) {
147 srcTextField.setText( dirPath.getAbsolutePath() );
148 pref.setSourcePaths( new ArrayList<>( List.of( dirPath.toPath() ) ) );
149 }
150 } );
151 final Label label = new Label( "Arbeitsverzeichnis A:" );
152 label.setPrefWidth( LABEL_WIDTH );
153 destGrid.add( label, 0, 0 );
154 destGrid.add( new HBox( 8, srcTextField, srcBtn ), 1, 0 );
155 return new VBox( V_GAP, destGrid );
156 }
157
158
159
160
161
162
163
164
165
166
167 private VBox getSourceList( final ScanType type, final Preference pref, final Stage primaryStage ) {
168
169 final String label = ScanType.DUBLICATE_SCAN == type ? "Scanverzeichnisse:" : "Quellverzeichnisse (Multi-Source Pathing):";
170 final String chooserTitle = String.format( ScanType.DUBLICATE_SCAN == type ? "Scanverzeichnis für %s" : "Quellverzeichnis für %s", pref.getScanMode().getDescription() );
171
172 final VBox multiSrcBox = new VBox( 6 );
173 final Label multiSrcLabel = new Label( label );
174 multiSrcLabel.getStyleClass().addAll( "multi-src-label" );
175
176
177 final ObservableList<String> actualSourcePaths = FXCollections.observableArrayList();
178 for( final Path path : pref.getSourcePaths() ) {
179 actualSourcePaths.add( path.toString() );
180 }
181
182 final ListView<String> pathsListView = new ListView<>( actualSourcePaths );
183 pathsListView.getStyleClass().addAll( "multi-src-list" );
184 pathsListView.setPrefHeight( PATH_LIST_HEIGHT );
185 pathsListView.setPrefWidth( PATH_LIST_WIDTH );
186
187
188 final Button add = new Button( "Verzeichnis hinzufügen", Gui.createIcon( MaterialDesignP.PLUS ) );
189 add.setOnAction( _ -> {
190 final File dirPath = chooseDirectory( getInitialPath( pref.getSourcePaths() ), chooserTitle, primaryStage );
191 if( dirPath != null && !actualSourcePaths.contains( dirPath.getAbsolutePath() ) ) {
192 actualSourcePaths.add( dirPath.getAbsolutePath() );
193 pref.setSourcePath( dirPath.toPath() );
194 }
195 } );
196
197
198 final Button remove = new Button( "Entfernen", Gui.createIcon( MaterialDesignD.DELETE ) );
199 remove.setOnAction( _ -> {
200 final String selectedPath = pathsListView.getSelectionModel().getSelectedItem();
201 if( selectedPath != null ) {
202 actualSourcePaths.remove( selectedPath );
203 pref.removeSourcePath( Paths.get( selectedPath ) );
204 }
205 } );
206
207 multiSrcBox.getChildren().addAll( multiSrcLabel, pathsListView, new HBox( 8, add, remove ) );
208 return multiSrcBox;
209 }
210
211
212
213
214
215
216
217
218 private VBox getDestBox( final Preference pref, final Stage primaryStage ) {
219 final String directoryName = pref.getScanMode() == ScanType.SYNCHRONIZE ? "Arbeitsverzeichnis B" : "Zielverzeichnis";
220 final GridPane destGrid = new GridPane();
221 destGrid.setHgap( H_GAP );
222 final String initialString = getInitialPath( pref.getDestPaths() ).toString();
223 final TextField destField = new TextField( initialString );
224 destField.setPrefWidth( TEXT_FIELD_WIDTH );
225 final Button destBtn = new Button( "Durchsuchen..." );
226 destBtn.setOnAction( _ -> {
227 final File initialDest = getInitialPath( pref.getDestPaths() );
228 final File dirPath = chooseDirectory( initialDest, directoryName + " für " + pref.getScanMode().getDescription(), primaryStage );
229 if( dirPath != null ) {
230 destField.setText( dirPath.getAbsolutePath() );
231 pref.setDestPaths( new ArrayList<>( List.of( dirPath.toPath() ) ) );
232 }
233 } );
234 final Label label = new Label( directoryName + ":" );
235 label.setPrefWidth( LABEL_WIDTH );
236 destGrid.add( label, 0, 0 );
237 destGrid.add( new HBox( 8, destField, destBtn ), 1, 0 );
238 return new VBox( V_GAP, new Separator(), destGrid );
239 }
240
241
242
243
244
245
246
247
248
249 private File chooseDirectory( final File initialDir, final String title, final Stage primaryStage ) {
250 final DirectoryChooser chooser = new DirectoryChooser();
251 if( initialDir != null && initialDir.exists() ) chooser.setInitialDirectory( initialDir );
252 chooser.setTitle( title );
253 return chooser.showDialog( primaryStage );
254 }
255
256
257
258
259
260
261
262
263
264
265
266 private File getInitialPath( final List<Path> paths ) {
267 return ( paths != null && !paths.isEmpty() ) ? paths.get( paths.size() - 1 ).toFile() : DEFAULT_PATH.toFile();
268 }
269 }