View Javadoc
1   /*
2    * Copyright 2013-2023 Medical Information Systems Research Group (https://medical.zcu.cz),
3    * Department of Computer Science and Engineering, University of West Bohemia.
4    * Address: Univerzitni 8, 306 14 Plzen, Czech Republic.
5    *
6    * This file is part of Sparkle project.
7    *
8    * Sparkle is free software: you can redistribute it and/or modify
9    * it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License.
11   *
12   * Sparkle is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with Sparkle. If not, see <http://www.gnu.org/licenses/>.
19   */
20  package cz.zcu.mre.sparkle.gui.mainForm.mainMenu;
21  
22  import cz.zcu.mre.sparkle.Messages;
23  import cz.zcu.mre.sparkle.data.DataAgent;
24  import cz.zcu.mre.sparkle.data.resourceStorage.ResourcesStorage;
25  import cz.zcu.mre.sparkle.gui.dialogs.ConnectionDialog;
26  import cz.zcu.mre.sparkle.gui.dialogs.HelpDialog;
27  import cz.zcu.mre.sparkle.gui.dialogs.SettingDialog;
28  import cz.zcu.mre.sparkle.gui.dialogs.SparqlEndpointsDialog;
29  import cz.zcu.mre.sparkle.gui.dialogs.other.ErrorDialog;
30  import cz.zcu.mre.sparkle.gui.dialogs.other.ProgressDialog;
31  import cz.zcu.mre.sparkle.gui.dialogs.storage.DataTypesDialog;
32  import cz.zcu.mre.sparkle.gui.dialogs.storage.FunctionsDialog;
33  import cz.zcu.mre.sparkle.gui.dialogs.storage.PrefixesDialog;
34  import cz.zcu.mre.sparkle.gui.dialogs.storage.ResourcesDialog;
35  import cz.zcu.mre.sparkle.gui.evaluation.EvaluatorTab;
36  import cz.zcu.mre.sparkle.gui.mainForm.MainForm;
37  import cz.zcu.mre.sparkle.gui.mainForm.mainMenu.menuItems.MenuItemsQuery;
38  import cz.zcu.mre.sparkle.gui.mainForm.mainMenu.menuItems.MenuItemsStorage;
39  import cz.zcu.mre.sparkle.gui.mainForm.mainTabPane.MainTabPane;
40  import cz.zcu.mre.sparkle.gui.query.QueryFormPane;
41  import cz.zcu.mre.sparkle.gui.query.QueryTabPane;
42  import cz.zcu.mre.sparkle.gui.query.other.ExporterTab;
43  import cz.zcu.mre.sparkle.gui.query.other.SaverTab;
44  import cz.zcu.mre.sparkle.gui.query.queryTypes.subselect.SubSelectQueryTab;
45  import cz.zcu.mre.sparkle.tools.IO;
46  import java.awt.Desktop;
47  import javafx.application.Platform;
48  import javafx.beans.property.ReadOnlyObjectProperty;
49  import javafx.concurrent.Task;
50  import javafx.scene.control.MenuItem;
51  import javafx.scene.control.Tab;
52  import javafx.scene.control.TabPane;
53  import javafx.stage.Stage;
54  import org.apache.jena.atlas.logging.Log;
55  import java.io.File;
56  import java.io.IOException;
57  import java.net.URI;
58  import java.net.URISyntaxException;
59  import java.sql.SQLException;
60  import java.util.List;
61  import java.util.concurrent.ExecutionException;
62  import java.util.logging.Level;
63  import java.util.logging.Logger;
64  
65  /**
66   * Hlavni menu a toolbar - definice akci.
67   *
68   * @author Jan Smucr
69   * @author Petr Vcelak (vcelak@kiv.zcu.cz)
70   */
71  public class MainMenuAction {
72  
73      private static final Logger LOG = Logger.getLogger(MainForm.class.getName());
74  
75      /**
76       * Import souboru s daty.
77       *
78       * @param mainForm okno (hlavni formular)
79       */
80      static void onImportFileMenuItemClick(MainForm mainForm) {
81          final List<File> files
82                  = IO.openRDFFile(mainForm.getStage(), Messages.getString("IMPORT_FILES"), true); //$NON-NLS-1$
83          if (files == null) {
84              return;
85          }
86  
87          importFiles(mainForm, files);
88          updateResources(mainForm, files);
89      }
90  
91      /**
92       * Aktualizuje seznam zdroju daty z nahravanych souboru.
93       *
94       * @param mainForm okno (hlavni formular)
95       * @param files seznam importovanych souboru
96       */
97      private static void updateResources(MainForm mainForm, List<File> files) {
98          //TODO: query resources
99          Platform.runLater(() -> mainForm.getAppResourcesStorage()
100                 .updateResourceStorage(mainForm.getStage(), files,
101                         mainForm.getAppPrefixesStorage().getIriToPrefixReadOnly().keySet()
102                 ));
103     }
104 
105     /**
106      * Zpracuje importovane soubory.
107      *
108      * @param mainForm okno (hlavni formular)
109      * @param files seznam importovanych souboru
110      */
111     private static void importFiles(MainForm mainForm, List<File> files) {
112         final Task<Boolean> task = new Task<Boolean>() {
113             @Override
114             protected Boolean call() throws Exception {
115 
116                 if (files.size() == 1) {
117                     // Import jediného souboru
118                     updateProgress(-1, -1);
119                     final File file = files.get(0);
120                     updateMessage(String.format(Messages.getString("IMPORTING_X"),
121                             file.getName())); //$NON-NLS-1$ //$NON-NLS-2$
122                     mainForm.getDataAgent().addToModel(file);
123 
124                 } else {
125                     // Import více souborů najednou
126                     updateProgress(0, files.size());
127                     for (int index = 0; index < files.size(); index++) {
128                         if (isCancelled()) {
129                             return true;
130                         }
131                         final File file = files.get(index);
132                         updateMessage(String.format(Messages.getString("IMPORTING_X"), file.getName()));
133                         mainForm.getDataAgent().addToModel(file);
134                         List<String> importedFiles = mainForm.getDataAgent().getImportedFiles();
135                         if (importedFiles != null) {
136                             importedFiles.add(file.getPath());
137                         }
138 
139                         updateProgress(index + 1, files.size());
140                     }
141                 }
142 
143                 updateProgress(-1, -1);
144 
145                 return true;
146             }
147         };
148 
149         try {
150             ProgressDialog.performTask(mainForm.getStage(), task);
151 
152         } catch (final OutOfMemoryError e) {
153             ErrorDialog.open(mainForm.getStage(), Messages.getString("ERROR"),
154                     Messages.getString("OUT_OF_MEMORY_FILE_LARGE"), e);
155 
156         } catch (InterruptedException | ExecutionException | Error e) {
157             LOG.log(Level.SEVERE, "Exception: ", e); //$NON-NLS-2$
158             ErrorDialog.open(mainForm.getStage(), Messages.getString("ERROR"),
159                     Messages.getString("IMPORT_FAILED"), e);
160         }
161     }
162 
163     /**
164      * Nastaveni prirazeni property pro menu, toolbar.
165      *
166      * @param mainForm okno (hlavni formular).
167      */
168     static void setupBinding(MainForm mainForm) {
169         ReadOnlyObjectProperty<Tab> tabReadOnlyObjectProperty
170                 = mainForm.getMainTabPane().getSelectionModel().selectedItemProperty();
171 
172         MainMenuBar mainMenuBar = mainForm.getMainMenuBar();
173         List<MenuItem> menuItemsQuery = mainMenuBar.getMenuItemsQuery();
174         List<MenuItem> menuItemsStorage = mainMenuBar.getMenuItemsStorage();
175 
176         menuItemsQuery.get(MenuItemsQuery.getManageQueryPrefixesOrdinal())
177                 .disableProperty().bind(tabReadOnlyObjectProperty.isNull());
178         menuItemsQuery.get(MenuItemsQuery.getManageQueryResourcesOrdinal()).disableProperty()
179                 .bind(tabReadOnlyObjectProperty.isNull());
180         menuItemsQuery.get(MenuItemsQuery.getManageQueryFunctionsOrdinal()).disableProperty()
181                 .bind(tabReadOnlyObjectProperty.isNull());
182         menuItemsQuery.get(MenuItemsQuery.getManageQueryDataTypesOrdinal()).disableProperty()
183                 .bind(tabReadOnlyObjectProperty.isNull());
184 
185         menuItemsQuery.get(MenuItemsQuery.getSaveAllOrdinal()).disableProperty()
186                 .bind(mainForm.unsavedTabsPropertyProperty().isEqualTo(0));
187 
188         menuItemsStorage.get(MenuItemsStorage.getClearOrdinal()).disableProperty()
189                 .bindBidirectional(mainForm.getDataAgent().isNullProperty());
190         menuItemsStorage.get(MenuItemsStorage.getImportFileOrdinal()).disableProperty()
191                 .bindBidirectional(mainForm.getDataAgent().isNullProperty());
192 
193         MainToolBar mainToolBar = mainForm.getMainToolBar();
194         mainToolBar.getOpenButton().disableProperty()
195                 .bindBidirectional(menuItemsQuery.get(MenuItemsQuery.getOpenOrdinal()).disableProperty());
196         mainToolBar.getSaveButton().disableProperty()
197                 .bindBidirectional(menuItemsQuery.get(MenuItemsQuery.getSaveOrdinal()).disableProperty());
198         mainToolBar.getSaveAllButton().disableProperty()
199                 .bindBidirectional(menuItemsQuery.get(MenuItemsQuery.getSaveAllOrdinal()).disableProperty());
200         mainToolBar.getEvaluateButton().disableProperty()
201                 .bindBidirectional(menuItemsQuery.get(MenuItemsQuery.getEvaluateOrdinal()).disableProperty());
202         mainToolBar.getStopButton().disableProperty()
203                 .bindBidirectional(menuItemsQuery.get(MenuItemsQuery.getStopEvaluationOrdinal()).disableProperty());
204 
205         mainToolBar.getSwitchStorageButton().disableProperty()
206                 .bindBidirectional(
207                         menuItemsStorage.get(MenuItemsStorage.getSwitchStorageOrdinal()).disableProperty());
208 
209     }
210 
211     /**
212      * Aktualizace property po prepnuti uloziste
213      *
214      * @param mainForm okno (hlavni formular)
215      */
216     public static void reInitBinding(MainForm mainForm) {
217         MainMenuBar mainMenuBar = mainForm.getMainMenuBar();
218         List<MenuItem> menuItemsQuery = mainMenuBar.getMenuItemsQuery();
219         List<MenuItem> menuItemsStorage = mainMenuBar.getMenuItemsStorage();
220 
221         menuItemsQuery.get(MenuItemsQuery.getStopEvaluationOrdinal()).disableProperty().unbind();
222 
223         menuItemsStorage.get(MenuItemsStorage.getClearOrdinal()).disableProperty()
224                 .setValue(mainForm.getDataAgent().isNullProperty().getValue());
225         menuItemsStorage.get(MenuItemsStorage.getImportFileOrdinal()).disableProperty()
226                 .setValue(mainForm.getDataAgent().isNullProperty().getValue());
227 
228         if (mainForm.getCurrentQueryTab() != null) {
229             menuItemsQuery.get(MenuItemsQuery.getStopEvaluationOrdinal()).disableProperty()
230                     .bind(mainForm.getCurrentQueryTab().evaluatingProperty().not()
231                             .or(mainForm.getDataAgent().isNullProperty()));
232         }
233 
234     }
235 
236     /*====================
237      * Akce polozek menu
238      *====================
239      */
240     /**
241      * Zobrazi dialog pro spravu globalnich prefixu
242      *
243      * @param mainForm okno (hlavni formular)
244      */
245     static void manageLocalPrefixesOnAction(MainForm mainForm) {
246         PrefixesDialog.open(mainForm.getStage(), mainForm.getAppPrefixesStorage());
247     }
248 
249     /**
250      * Zobrazi dialog pro spravu prefixu dotazu
251      *
252      * @param mainForm okno (hlavni formular)
253      */
254     static void manageQueryPrefixesOnAction(MainForm mainForm) {
255         final QueryFormPane<?> pane = ((MainTabPane) mainForm.getMainTabPane()).getCurrentQueryPane();
256         if (pane != null) {
257             PrefixesDialog.open(mainForm.getStage(), pane.getQueryPrefixesStorage(), pane.getPrefixesUsed(false));
258         }
259     }
260 
261     /**
262      * Zobrazi dialog pro spravu globalnich zdroju
263      *
264      * @param mainForm okno (hlavni formular)
265      */
266     static void manageLocalResourcesOnAction(MainForm mainForm) {
267         ResourcesDialog.open(mainForm.getStage(), mainForm.getAppResourcesStorage(), mainForm.getDataAgent());
268     }
269 
270     /**
271      * Zobrazi dialog pro spravu zdroju dotazu
272      *
273      * @param mainForm okno (hlavni formular)
274      */
275     static void manageQueryResourcesOnAction(MainForm mainForm) {
276         final QueryFormPane<?> pane = ((MainTabPane) mainForm.getMainTabPane()).getCurrentQueryPane();
277         if (pane != null) {
278             ResourcesDialog.open(mainForm.getStage(), pane.getQueryResourcesStorage(), mainForm.getDataAgent());
279         }
280     }
281 
282     /**
283      * Zobrazi dialog pro spravu globalnich fuknci
284      *
285      * @param mainForm okno (hlavni formular)
286      */
287     static void manageLocalFunctionsOnAction(MainForm mainForm) {
288         FunctionsDialog.open(mainForm.getStage(), mainForm.getAppFunctionsStorage());
289     }
290 
291     /**
292      * Zobrazi dialog pro spravu fuknci dotazu
293      *
294      * @param mainForm okno (hlavni formular)
295      */
296     static void manageQueryFunctionsOnAction(MainForm mainForm) {
297         final QueryFormPane<?> pane = ((MainTabPane) mainForm.getMainTabPane()).getCurrentQueryPane();
298         if (pane != null) {
299             FunctionsDialog.open(mainForm.getStage(), pane.getQueryFunctionsStorage());
300         }
301     }
302 
303     /**
304      * Zobrazi dialog pro spravu globalnich datovych typu
305      *
306      * @param mainForm okno (hlavni formular)
307      */
308     static void manageLocalDataTypesOnAction(MainForm mainForm) {
309         DataTypesDialog.open(mainForm.getStage(), mainForm.getAppDataTypesStorage());
310     }
311 
312     /**
313      * Zobrazi dialog pro spravu datovych typu dotazu
314      *
315      * @param mainForm okno (hlavni formular)
316      */
317     static void manageQueryDataTypesOnAction(MainForm mainForm) {
318         final QueryFormPane<?> pane = ((MainTabPane) mainForm.getMainTabPane()).getCurrentQueryPane();
319         if (pane != null) {
320             DataTypesDialog.open(mainForm.getStage(), pane.getQueryDataTypesStorage());
321         }
322     }
323 
324     /**
325      * Zobrazi dialog pro spravu adres Sparql endpointu
326      *
327      * @param mainForm okno (hlavni formular)
328      */
329     static void manageSparqlEndpointsOnAction(MainForm mainForm) {
330         SparqlEndpointsDialog.open(mainForm.getStage());
331     }
332 
333     /**
334      * Vycisti lokalni uloziste
335      *
336      * @param mainForm okno (hlavni formular)
337      */
338     static void clearStorage(MainForm mainForm) {
339         DataStorageAction.clearStorage(mainForm);
340     }
341 
342     /**
343      * Provede vyhodnoceni dotazu
344      *
345      * @param mainTabPane kontejner zalozek s dotazy
346      * @param dataAgent
347      */
348     static void evaluate(TabPane mainTabPane, DataAgent dataAgent) {
349         final Tab tab = ((MainTabPane) mainTabPane).getCurrentTab();
350         if (tab instanceof EvaluatorTab) {
351             ((EvaluatorTab) tab).evaluate(dataAgent);
352         }
353     }
354 
355     /**
356      * Zastavi vyhodnocovani
357      *
358      * @param mainTabPane kontejner zalozek s dotazy
359      */
360     static void stopEvaluation(TabPane mainTabPane) {
361         final Tab tab = ((MainTabPane) mainTabPane).getCurrentTab();
362         if (tab instanceof EvaluatorTab) {
363             ((EvaluatorTab) tab).stopEvaluating();
364         }
365     }
366 
367     /**
368      * Ulozi obsah zalozky do souboru
369      *
370      * @param mainTabPane kontejner zalozek s dotazy
371      */
372     static void save(TabPane mainTabPane) {
373         final Tab tab = ((MainTabPane) mainTabPane).getCurrentTab();
374         if (tab instanceof SaverTab) {
375             ((SaverTab) tab).save();
376         }
377     }
378 
379     /**
380      * Ulozi obsah zalozky do souboru s vyberem nazvu
381      *
382      * @param mainTabPane kontejner zalozek s dotazy
383      */
384     static void saveAs(TabPane mainTabPane) {
385         final Tab tab = ((MainTabPane) mainTabPane).getCurrentTab();
386         if (tab instanceof SaverTab && !(tab instanceof SubSelectQueryTab)) {
387             QueryTabPane.selectFormTab(tab);
388             ((SaverTab) tab).saveAs();
389         }
390     }
391 
392     /**
393      * Ulozi obsah vsech zalozek do souboru
394      *
395      * @param mainTabPane kontejner zalozek s dotazy
396      */
397     static void saveAll(TabPane mainTabPane) {
398         for (final Tab tab : mainTabPane.getTabs()) {
399             if (tab instanceof SaverTab && !(tab instanceof SubSelectQueryTab)) {
400                 QueryTabPane.selectFormTab(tab);
401 
402                 if (!((SaverTab) tab).save()) {
403                     return;
404                 }
405             }
406         }
407     }
408 
409     /**
410      * Export do formatu .rq
411      *
412      * @param mainTabPane kontejner zalozek s dotazy
413      */
414     static void export(TabPane mainTabPane) {
415         final Tab tab = ((MainTabPane) mainTabPane).getCurrentTab();
416         if (tab instanceof ExporterTab) {
417             ((ExporterTab) tab).export();
418         }
419     }
420 
421     /**
422      * Nacteni dotazu ze souboru
423      *
424      * @param mainForm okno (hlavni formular)
425      */
426     public static void open(MainForm mainForm) {
427         final List<File> files
428                 = IO.openQueryFile(mainForm.getStage(), Messages.getString("OPEN_QUERY"), true);
429         if (files == null) {
430             return;
431         }
432         files.stream().forEach((file) -> MainTabPane.open(file, mainForm));
433     }
434 
435     /**
436      * Zmena uloziste
437      *
438      * @param mainForm okno (hlavni formular)
439      */
440     public static void switchStorage(MainForm mainForm) {
441         final DataAgent dataAgent = ConnectionDialog.open(mainForm.getStage());
442         if (dataAgent != null) {
443             try {
444                 mainForm.disconnect();
445             } catch (SQLException e) {
446                 LOG.log(Level.SEVERE, "Exception: ", e); //$NON-NLS-2$
447             }
448 
449             mainForm.setDataAgent(dataAgent);
450             dataAgent.notifyChanged();
451         }
452     }
453 
454     /**
455      * Otevre url v prohlizeci
456      *
457      * @param url url
458      * @param stage rodicovska scena (okno)
459      */
460     public static void openUrlInBrowser(String url, Stage stage) {
461 
462         /*
463         // On 2019-01-07 use and dependency of BrowserLauncher was removed.
464         //import edu.stanford.ejalbert.BrowserLauncher;
465         //import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
466         //import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
467         //try {
468         //  new BrowserLauncher().openURLinBrowser(url);
469         //
470         //} catch (BrowserLaunchingInitializingException e) {
471         //  Log.warn(MainMenuBar.class, e.getLocalizedMessage());
472         //  ErrorDialog.open(stage, Messages.getString("WARNING"),
473         //      Messages.getString("BROWSER_LAUNCHING_ERROR"), e.getCause());
474         //} catch (UnsupportedOperatingSystemException e) {
475         //  ErrorDialog.open(stage, Messages.getString("WARNING"),
476         //      Messages.getString("UNSUPPORTED_OS"), e.getCause());
477         //}
478         */
479 
480         if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
481             try {
482                 Desktop.getDesktop().browse(new URI(url));
483             } catch (IOException ex) {
484                 Logger.getLogger(MainMenuAction.class.getName()).log(Level.SEVERE, null, ex);
485                 Log.warn(MainMenuBar.class, ex.getLocalizedMessage());
486                 ErrorDialog.open(stage, Messages.getString("WARNING"),
487                         Messages.getString("BROWSER_LAUNCHING_ERROR"), ex.getCause());
488             } catch (URISyntaxException ex) {
489                 Log.warn(MainMenuBar.class, ex.getLocalizedMessage());
490                 ErrorDialog.open(stage, Messages.getString("WARNING"),
491                         Messages.getString("BROWSER_LAUNCHING_ERROR"), ex.getCause());
492             }
493         }
494     }
495 
496     /**
497      * Zobrazi dialog "Documentation"
498      *
499      * @param stage rodicovska scena (okno)
500      */
501     public static void showDocumentationDialog(Stage stage) {
502         showHelpDialog(stage, "DOCUMENTATION_TEXT", "DOCUMENTATION");
503     }
504 
505     /**
506      * Zobrazi dialog "Credits"
507      *
508      * @param stage rodicovska scena (okno)
509      */
510     public static void showCreditsDialog(Stage stage) {
511         showHelpDialog(stage, "CREDITS_TEXT", "CREDITS");
512     }
513 
514     /**
515      * Zobrazi dialog "About"
516      *
517      * @param stage rodicovska scena (okno)
518      */
519     public static void showAboutDialog(Stage stage) {
520         showHelpDialog(stage,
521                 "ABOUT_TEXT", "ABOUT");
522     }
523 
524     /**
525      * Zobrazi dialog se zadanym textem, formatovani pomoci HTML
526      *
527      * @param stage rodicovska scena (okno)
528      * @param content obsah - delsi text
529      * @param title titulek dialogu
530      */
531     private static void showHelpDialog(Stage stage, String content, String title) {
532         String text
533                 = "<html style=\"background-color: #0000000c; font-family: monospaced; font-size:14\">";//$NON-NLS-2$
534         text += Messages.getString(content, Messages.DIALOGS_BUNDLE_NAME);
535         text += "</html>";//$NON-NLS-2$
536         HelpDialog.open(stage, Messages.getString(title), text, false);
537     }
538 
539     /**
540      * Zobrazi dialog s nastavenim aplikace
541      *
542      * @param mainForm okno (hlavni formular)
543      */
544     public static void showSettingDialog(MainForm mainForm) {
545         ResourcesStorage queryResourcesStorage
546                 = mainForm.getCurrentQueryTab() != null
547                 ? mainForm.getCurrentQueryTab().getQueryFormPane().getQueryResourcesStorage()
548                 : null;
549         SettingDialog.open(mainForm.getStage(), mainForm.getAppResourcesStorage(),
550                 queryResourcesStorage);
551     }
552 }