|
1 | 1 | /*
|
| 2 | + * ***************************************************************************** |
| 3 | + * Copyright (C) 2014-2025 Dennis Sheirer |
2 | 4 | *
|
3 |
| - * * ****************************************************************************** |
4 |
| - * * Copyright (C) 2014-2020 Dennis Sheirer |
5 |
| - * * |
6 |
| - * * This program is free software: you can redistribute it and/or modify |
7 |
| - * * it under the terms of the GNU General Public License as published by |
8 |
| - * * the Free Software Foundation, either version 3 of the License, or |
9 |
| - * * (at your option) any later version. |
10 |
| - * * |
11 |
| - * * This program is distributed in the hope that it will be useful, |
12 |
| - * * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
| - * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
| - * * GNU General Public License for more details. |
15 |
| - * * |
16 |
| - * * You should have received a copy of the GNU General Public License |
17 |
| - * * along with this program. If not, see <http://www.gnu.org/licenses/> |
18 |
| - * * ***************************************************************************** |
| 5 | + * This program is free software: you can redistribute it and/or modify |
| 6 | + * it under the terms of the GNU General Public License as published by |
| 7 | + * the Free Software Foundation, either version 3 of the License, or |
| 8 | + * (at your option) any later version. |
19 | 9 | *
|
| 10 | + * This program is distributed in the hope that it will be useful, |
| 11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | + * GNU General Public License for more details. |
20 | 14 | *
|
| 15 | + * You should have received a copy of the GNU General Public License |
| 16 | + * along with this program. If not, see <http://www.gnu.org/licenses/> |
| 17 | + * **************************************************************************** |
21 | 18 | */
|
22 | 19 |
|
23 | 20 | package io.github.dsheirer.gui.playlist.manager;
|
|
30 | 27 | import io.github.dsheirer.playlist.PlaylistManager;
|
31 | 28 | import io.github.dsheirer.preference.PreferenceType;
|
32 | 29 | import io.github.dsheirer.preference.UserPreferences;
|
| 30 | +import java.io.File; |
| 31 | +import java.io.IOException; |
| 32 | +import java.nio.file.Path; |
| 33 | +import java.nio.file.Paths; |
| 34 | +import java.util.List; |
| 35 | +import java.util.Optional; |
33 | 36 | import javafx.application.Platform;
|
34 | 37 | import javafx.geometry.Insets;
|
35 | 38 | import javafx.geometry.Pos;
|
|
42 | 45 | import javafx.scene.control.TableColumn;
|
43 | 46 | import javafx.scene.control.TableView;
|
44 | 47 | import javafx.scene.control.Tooltip;
|
| 48 | +import javafx.scene.input.MouseButton; |
45 | 49 | import javafx.scene.layout.HBox;
|
46 | 50 | import javafx.scene.layout.Priority;
|
47 | 51 | import javafx.scene.layout.VBox;
|
|
53 | 57 | import org.slf4j.Logger;
|
54 | 58 | import org.slf4j.LoggerFactory;
|
55 | 59 |
|
56 |
| -import java.io.File; |
57 |
| -import java.io.IOException; |
58 |
| -import java.nio.file.Path; |
59 |
| -import java.nio.file.Paths; |
60 |
| -import java.util.List; |
61 |
| -import java.util.Optional; |
62 |
| - |
63 | 60 | /**
|
64 | 61 | * Editor for managing playlists via the playlist manager
|
65 | 62 | */
|
@@ -198,6 +195,15 @@ protected void updateItem(String item, boolean empty)
|
198 | 195 |
|
199 | 196 | mPlaylistTableView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> updateButtons());
|
200 | 197 |
|
| 198 | + //User double-clicks on an entry - make that entry the selected playlist. |
| 199 | + mPlaylistTableView.setOnMouseClicked(event -> |
| 200 | + { |
| 201 | + if(event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) |
| 202 | + { |
| 203 | + selectPlayist(getPlaylistTableView().getSelectionModel().getSelectedItem()); |
| 204 | + } |
| 205 | + }); |
| 206 | + |
201 | 207 | List<Path> playlistPaths = mUserPreferences.getPlaylistPreference().getPlaylistList();
|
202 | 208 |
|
203 | 209 | mPlaylistTableView.getItems().addAll(playlistPaths);
|
@@ -237,81 +243,87 @@ private VBox getButtonBox()
|
237 | 243 | return mButtonBox;
|
238 | 244 | }
|
239 | 245 |
|
240 |
| - private Button getSelectButton() |
| 246 | + /** |
| 247 | + * Selects the specified playlist and makes it the current playlist. |
| 248 | + * @param selected playlist. |
| 249 | + */ |
| 250 | + private void selectPlayist(Path selected) |
241 | 251 | {
|
242 |
| - if(mSelectButton == null) |
| 252 | + if(selected != null) |
243 | 253 | {
|
244 |
| - mSelectButton = new Button("Select"); |
245 |
| - mSelectButton.setTooltip(new Tooltip("Sets the selected playlist as the current playlist")); |
246 |
| - mSelectButton.setMaxWidth(Double.MAX_VALUE); |
247 |
| - mSelectButton.setOnAction(event -> { |
248 |
| - Path current = mUserPreferences.getPlaylistPreference().getPlaylist(); |
249 |
| - Path selected = getPlaylistTableView().getSelectionModel().getSelectedItem(); |
| 254 | + Path current = mUserPreferences.getPlaylistPreference().getPlaylist(); |
250 | 255 |
|
251 |
| - if(selected != null) |
| 256 | + try |
| 257 | + { |
| 258 | + mPlaylistManager.setPlaylist(selected); |
| 259 | + } |
| 260 | + catch(IOException ioe) |
| 261 | + { |
| 262 | + mLog.error("Error loading playlist [" + (selected != null ? selected.toString() : "null") + "]"); |
| 263 | + |
| 264 | + new Alert(Alert.AlertType.ERROR, "Unable to load selected playlist. " + |
| 265 | + "Reverting to previous playlist", ButtonType.OK).show(); |
| 266 | + |
| 267 | + try |
252 | 268 | {
|
253 |
| - try |
254 |
| - { |
255 |
| - mPlaylistManager.setPlaylist(selected); |
256 |
| - } |
257 |
| - catch(IOException ioe) |
258 |
| - { |
259 |
| - mLog.error("Error loading playlist [" + (selected != null ? selected.toString() : "null") + "]"); |
| 269 | + mPlaylistManager.setPlaylist(current); |
| 270 | + } |
| 271 | + catch(IOException ioe2) |
| 272 | + { |
| 273 | + mLog.error("Error reverting to previous playlist [" + |
| 274 | + (current != null ? current.toString() : "null") + "]"); |
| 275 | + } |
| 276 | + } |
260 | 277 |
|
261 |
| - new Alert(Alert.AlertType.ERROR, "Unable to load selected playlist. " + |
262 |
| - "Reverting to previous playlist", ButtonType.OK).show(); |
| 278 | + final List<Channel> autoStartChannels = mPlaylistManager.getChannelModel().getAutoStartChannels(); |
263 | 279 |
|
264 |
| - try |
| 280 | + if(autoStartChannels.size() > 0) |
| 281 | + { |
| 282 | + Alert alert = new Alert(Alert.AlertType.CONFIRMATION, |
| 283 | + "Would you like to auto-start your channels?", ButtonType.YES, ButtonType.NO); |
| 284 | + alert.setTitle("Auto-Start Channels"); |
| 285 | + alert.setHeaderText("Discovered [" + autoStartChannels.size() + "] auto-start channel" + |
| 286 | + (autoStartChannels.size() > 1 ? "s" : "")); |
| 287 | + alert.showAndWait().ifPresent(buttonType -> { |
| 288 | + if(buttonType == ButtonType.YES) |
| 289 | + { |
| 290 | + boolean error = false; |
| 291 | + |
| 292 | + for(Channel channel: autoStartChannels) |
265 | 293 | {
|
266 |
| - mPlaylistManager.setPlaylist(current); |
| 294 | + try |
| 295 | + { |
| 296 | + mPlaylistManager.getChannelProcessingManager().start(channel); |
| 297 | + } |
| 298 | + catch(ChannelException ce) |
| 299 | + { |
| 300 | + error = true; |
| 301 | + } |
267 | 302 | }
|
268 |
| - catch(IOException ioe2) |
| 303 | + |
| 304 | + if(error) |
269 | 305 | {
|
270 |
| - mLog.error("Error reverting to previous playlist [" + |
271 |
| - (current != null ? current.toString() : "null") + "]"); |
| 306 | + Alert errorAlert = new Alert(Alert.AlertType.ERROR, |
| 307 | + "Unable to start some or all of the auto-start channels", |
| 308 | + ButtonType.OK); |
| 309 | + errorAlert.setTitle("Channel Auto-Start Error(s)"); |
| 310 | + errorAlert.setHeaderText("Auto-Start Error"); |
| 311 | + errorAlert.showAndWait(); |
272 | 312 | }
|
273 | 313 | }
|
| 314 | + }); |
| 315 | + } |
| 316 | + } |
| 317 | + } |
274 | 318 |
|
275 |
| - final List<Channel> autoStartChannels = mPlaylistManager.getChannelModel().getAutoStartChannels(); |
276 |
| - |
277 |
| - if(autoStartChannels.size() > 0) |
278 |
| - { |
279 |
| - Alert alert = new Alert(Alert.AlertType.CONFIRMATION, |
280 |
| - "Would you like to auto-start your channels?", ButtonType.YES, ButtonType.NO); |
281 |
| - alert.setTitle("Auto-Start Channels"); |
282 |
| - alert.setHeaderText("Discovered [" + autoStartChannels.size() + "] auto-start channel" + |
283 |
| - (autoStartChannels.size() > 1 ? "s" : "")); |
284 |
| - alert.showAndWait().ifPresent(buttonType -> { |
285 |
| - if(buttonType == ButtonType.YES) |
286 |
| - { |
287 |
| - boolean error = false; |
288 |
| - |
289 |
| - for(Channel channel: autoStartChannels) |
290 |
| - { |
291 |
| - try |
292 |
| - { |
293 |
| - mPlaylistManager.getChannelProcessingManager().start(channel); |
294 |
| - } |
295 |
| - catch(ChannelException ce) |
296 |
| - { |
297 |
| - error = true; |
298 |
| - } |
299 |
| - } |
300 |
| - |
301 |
| - if(error) |
302 |
| - { |
303 |
| - Alert errorAlert = new Alert(Alert.AlertType.ERROR, |
304 |
| - "Unable to start some or all of the auto-start channels", |
305 |
| - ButtonType.OK); |
306 |
| - errorAlert.setTitle("Channel Auto-Start Error(s)"); |
307 |
| - errorAlert.setHeaderText("Auto-Start Error"); |
308 |
| - errorAlert.showAndWait(); |
309 |
| - } |
310 |
| - } |
311 |
| - }); |
312 |
| - } |
313 |
| - } |
314 |
| - }); |
| 319 | + private Button getSelectButton() |
| 320 | + { |
| 321 | + if(mSelectButton == null) |
| 322 | + { |
| 323 | + mSelectButton = new Button("Select"); |
| 324 | + mSelectButton.setTooltip(new Tooltip("Sets the selected playlist as the current playlist")); |
| 325 | + mSelectButton.setMaxWidth(Double.MAX_VALUE); |
| 326 | + mSelectButton.setOnAction(event -> {selectPlayist(getPlaylistTableView().getSelectionModel().getSelectedItem());}); |
315 | 327 | }
|
316 | 328 |
|
317 | 329 | return mSelectButton;
|
|
0 commit comments