Statistics
| Revision:

root / trunk / org.gvsig.toolbox / org.gvsig.toolbox.gui / src / es / unex / sextante / gui / core / SextanteGUI.java @ 12

History | View | Annotate | Download (34.4 KB)

1

    
2

    
3
package es.unex.sextante.gui.core;
4

    
5
import java.awt.Color;
6
import java.awt.Frame;
7
import java.io.BufferedReader;
8
import java.io.BufferedWriter;
9
import java.io.File;
10
import java.io.FileNotFoundException;
11
import java.io.FileReader;
12
import java.io.FileWriter;
13
import java.io.IOException;
14
import java.io.Writer;
15
import java.net.URL;
16
import java.util.ArrayList;
17
import java.util.HashMap;
18
import java.util.Iterator;
19
import java.util.Set;
20

    
21
import javax.swing.ImageIcon;
22
import javax.swing.JDialog;
23
import javax.swing.JOptionPane;
24

    
25
import es.unex.sextante.core.GeoAlgorithm;
26
import es.unex.sextante.core.IInputFactory;
27
import es.unex.sextante.core.OutputFactory;
28
import es.unex.sextante.core.Sextante;
29
import es.unex.sextante.gui.cmd.ScriptAlgorithmProvider;
30
import es.unex.sextante.gui.help.HelpIO;
31
import es.unex.sextante.gui.modeler.ModelerAlgorithmProvider;
32
import es.unex.sextante.gui.r.RAlgorithmProvider;
33
import es.unex.sextante.gui.settings.Setting;
34
import es.unex.sextante.gui.settings.SextanteGeneralSettings;
35
import es.unex.sextante.gui.settings.SextanteRSettings;
36
import es.unex.sextante.gui.settings.SextanteGrassSettings;
37
import es.unex.sextante.gui.settings.SextanteSagaSettings;
38
import es.unex.sextante.gui.settings.SextanteModelerSettings;
39
import es.unex.sextante.gui.settings.SextanteScriptsSettings;
40

    
41

    
42
/**
43
 * This class centralizes most actions related to the SextanteGUI, containing methods to show dialogs and retrieve basic values
44
 * used by GUI elements
45
 */
46
public class SextanteGUI {
47

    
48
   public static final int                            HISTORY                     = 0;
49
   public static final int                            COMMANDLINE                 = 1;
50

    
51
   private static IInputFactory                       m_InputFactory;
52
   private static OutputFactory                       m_OutputFactory;
53
   private static IGUIFactory                         m_GUIFactory                = new DefaultGUIFactory();
54

    
55
   private static IPostProcessTaskFactory             m_PostProcessTaskFactory;
56

    
57
   private static JDialog                             m_LastCommandOriginParentPanel;
58
   private static int                                 m_iLastCommandOrigin;
59
   private static Frame                               m_MainFrame;
60

    
61
   private static boolean                             m_bShowOnlyActiveAlgorithms = false;
62
   private static String                              m_sOutputFolder;
63
   private static String                              m_sSextantePath;
64
   private static HashMap<String, String>             m_Settings                  = new HashMap<String, String>();
65
   private static HashMap<String, String>             m_DefaultSettings           = new HashMap<String, String>();
66
   private static IDataRenderer                       m_Renderer;
67

    
68

    
69
   private final static HashMap<String, Class>        m_ParametersPanel           = new HashMap<String, Class>();
70
   private final static HashMap<String, Class>        m_ModelerParametersPanel    = new HashMap<String, Class>();
71

    
72
   private final static ArrayList<IAlgorithmProvider> m_AlgorithmProviders        = new ArrayList<IAlgorithmProvider>();
73

    
74
   public final static ImageIcon                      SEXTANTE_ICON               = new ImageIcon(
75
                                                                                           SextanteGUI.class.getClassLoader().getResource(
76
                                                                                                    "images/module2.png"));
77

    
78
   public final static Color COLOR_WHITE = new Color(255, 255, 255, 255);
79
   public final static Color COLOR_GREY = new Color(128, 128, 128, 255);
80
   public final static Color COLOR_BLACK = new Color(0, 0, 0, 255);
81
   public final static Color COLOR_RED = new Color (255, 51, 51, 255);
82
   public final static Color COLOR_ORANGE = new Color(255, 103, 51, 255);
83
   public final static Color COLOR_YELLOW = new Color(255, 255, 51, 255);
84
   public final static Color COLOR_GREEN_LIGHT = new Color(51, 255, 51, 255);
85
   public final static Color COLOR_GREEN_DARK = new Color(0, 184, 0, 255);
86
   public final static Color COLOR_BLUE_LIGHT = new Color (102, 179, 255, 255);
87
   public final static Color COLOR_BLUE_DARK = new Color (0, 102, 204, 255);
88
   public final static Color COLOR_PINK = new Color(255, 153, 255, 255);
89
   public final static Color COLOR_PURPLE = new Color(163, 71, 255, 255);
90
   public final static Color COLOR_BROWN_LIGHT = new Color(255, 168, 82, 255);
91
   public final static Color COLOR_BROWN_DARK = new Color(204, 102, 0, 255);
92
   
93
   
94
   static {          
95
           
96
      m_AlgorithmProviders.add(new ScriptAlgorithmProvider());
97
      m_AlgorithmProviders.add(new ModelerAlgorithmProvider());
98

    
99
   }
100

    
101

    
102
   /**
103
    * Sets a new main frame. This will be used as the parent frame by SEXTANTE GUI elements
104
    * 
105
    * @param frame
106
    *                The main frame
107
    */
108
   public static void setMainFrame(final Frame frame) {
109

    
110
      m_MainFrame = frame;
111

    
112
   }
113

    
114

    
115
   /**
116
    * Returns the current main frame
117
    * 
118
    * @return the current main frame
119
    */
120
   public static Frame getMainFrame() {
121

    
122
      return m_MainFrame;
123

    
124
   }
125

    
126

    
127
   /** ************************************************************ */
128

    
129
   /**
130
    * Returns the current input factory
131
    * 
132
    * @see IInputFactory.
133
    * @return the current input factory
134
    */
135
   public static IInputFactory getInputFactory() {
136

    
137
      return m_InputFactory;
138

    
139
   }
140

    
141

    
142
   /**
143
    * Sets a new input factory as the current one
144
    * 
145
    * @param inputFactory
146
    *                the new input factory
147
    */
148
   public static void setInputFactory(final IInputFactory inputFactory) {
149

    
150
      m_InputFactory = inputFactory;
151

    
152
   }
153

    
154

    
155
   /**
156
    * Returns the current OutputFactory
157
    * 
158
    * @return the current OutputFactory
159
    */
160
   public static OutputFactory getOutputFactory() {
161

    
162
      return m_OutputFactory;
163

    
164
   }
165

    
166

    
167
   /**
168
    * sets a new output factory
169
    * 
170
    * @param outputFactory
171
    *                the new output factory
172
    */
173
   public static void setOutputFactory(final OutputFactory outputFactory) {
174

    
175
      m_OutputFactory = outputFactory;
176
      m_OutputFactory.setDefaultNoDataValue(getDefaultNoDataValue());
177

    
178
   }
179

    
180

    
181
   /**
182
    * Returns the current GUIFactory
183
    * 
184
    * @return the current GUIFactory
185
    */
186
   public static IGUIFactory getGUIFactory() {
187

    
188
      return m_GUIFactory;
189

    
190
   }
191

    
192

    
193
   /**
194
    * sets a new GUI factory
195
    * 
196
    * @param guiFactory
197
    *                the new GUI factory
198
    */
199
   public static void setGUIFactory(final IGUIFactory guiFactory) {
200

    
201
      m_GUIFactory = guiFactory;
202

    
203
   }
204

    
205

    
206
   /**
207
    * Returns the task to post-process the algorithm outputs, usually to add them to the GUI of the GIS app.
208
    * 
209
    * @param alg
210
    *                the algorithm to postprocess. Since this task will mainly deal with output results, the algorithm should have
211
    *                been previously executed, so it contains non-null output values
212
    * @param bShowResultsDialog
213
    *                if this parameter is true, the task will show the results dialog if the algorithm has produced some kind of
214
    *                output other than layers or tables. If it is false, those results will be added to the set of current
215
    *                results, but the results dialog will not be shown
216
    * 
217
    * @return a task to postprocess the given algorithm
218
    */
219
   public static Runnable getPostProcessTask(final GeoAlgorithm alg,
220
                                             final boolean bShowResultsDialog) {
221

    
222
      return m_PostProcessTaskFactory.getPostProcessTask(alg, bShowResultsDialog);
223

    
224
   }
225

    
226

    
227
   /**
228
    * Sets the current post process task factory
229
    * 
230
    * @param factory
231
    *                the new post-process task factory
232
    */
233
   public static void setPostProcessTaskFactory(final IPostProcessTaskFactory factory) {
234

    
235
      m_PostProcessTaskFactory = factory;
236

    
237
   }
238

    
239

    
240
   /** ******************************************* */
241

    
242
   /**
243
    * Adds an algorithm provider. This has to be done before calling initialize(), so the providers can be initialized as well.
244
    * 
245
    * @param provider
246
    *                the algorithm provider to add
247
    */
248
   public static void addAlgorithmProvider(final IAlgorithmProvider provider) {
249

    
250
      //providers are added at the beginning of the array, because models and scripts might depend on them
251
      m_AlgorithmProviders.add(0, provider);
252

    
253
   }
254

    
255

    
256
   /**
257
    * Checks if a portable directory exists and has the required access privileges.
258
    * Non-existing directories will be created if possible.
259
    * Displays a GUI warning message if there are problems, and exits with a corresponding error code. 
260
    * 
261
    * @param dir String with name of folder/directory to be checked. Use only a relative path here.
262
    * @param read_only set to "true" if only read access is required
263
    * @param provider name of the algorithm provider for which this folder is being checked.
264
    * @return "0" if all is OK, "1" if directory does not exist and could not be created, "2" if access is forbidden, "3" if a _file_ with that name already exists
265
    */
266
   public static int checkDir ( String dir, boolean read_only, String provider ) {
267
           
268
          final File f = new File ( SextanteGUI.getSextantePath() + File.separator + dir ); 
269
           
270
          if ( f.exists() ) {
271
                  if ( f.isFile() ) {
272
                          JOptionPane.showMessageDialog(null, 
273
                                          Sextante.getText("portable_dir_error") + " " + f.getAbsolutePath() + ".\n" + 
274
                                          Sextante.getText("portable_dir_is_file") + "\n" +
275
                                          Sextante.getText("portable_provider_not_usable") + " <html></i>" + provider + "+</i>+</html>."
276
                                          , "Inane warning", JOptionPane.WARNING_MESSAGE);
277
                          return ( 3 );
278
                  }
279
                  if ( read_only ) {
280
                          if ( f.canRead() ) {
281
                                  return ( 0 );
282
                          }                                  
283
                  }
284
                  if ( f.canWrite() ) {
285
                          return ( 0 );
286
                  }
287
                  if ( read_only ) {
288
                          JOptionPane.showMessageDialog(null, 
289
                                          Sextante.getText("portable_dir_error") + " " + f.getAbsolutePath() +
290
                                          Sextante.getText("portable_dir_error_ro") + "\n" + ":" +
291
                                          Sextante.getText("portable_dir_no_access") + "\n" +
292
                                          Sextante.getText("portable_provider_not_usable") + " <html></i>" + provider + "+</i>+</html>."
293
                                          , "Inane warning", JOptionPane.WARNING_MESSAGE);
294
                  } else {
295
                          JOptionPane.showMessageDialog(null, 
296
                                          Sextante.getText("portable_dir_error") + " " + f.getAbsolutePath() +
297
                                          Sextante.getText("portable_dir_error_rw") + "\n" + ":" +
298
                                          Sextante.getText("portable_dir_no_access") + "\n" +
299
                                          Sextante.getText("portable_provider_not_usable") + " <html></i>" + provider + "+</i>+</html>."
300
                                          , "Inane warning", JOptionPane.WARNING_MESSAGE);                          
301
                  }
302
                  return ( 2 );                  
303
          }
304
          
305
          /* directory does not exist: attempt to create it */
306
          if ( f.mkdir() == false ) {
307
                  JOptionPane.showMessageDialog(null, 
308
                                  Sextante.getText("portable_dir_error") + " " + f.getAbsolutePath() + ".\n" + 
309
                                  Sextante.getText("portable_dir_no_create") + "\n" +
310
                                  Sextante.getText("portable_provider_not_usable") + " <html></i>" + provider + "+</i>+</html>."
311
                                  , "Inane warning", JOptionPane.WARNING_MESSAGE);                  
312
                  return ( 1 );
313
          }
314
          
315
          return ( 0 );
316
   }
317
   
318
   
319
   /**
320
    * Checks if a file exists in one of the portable folders, and if it has the required access privileges.
321
    * Displays a GUI warning message if there are problems, and exits with a corresponding error code. 
322
    * 
323
    * @param file String with name of file to be checked. Use only a relative path here.
324
    * @param read_only set to "true" if only read access is required
325
    * @param provider name of the algorithm provider for which this file is being checked.
326
    * @return "0" if all is OK, "1" if file does not exist, "2" if access is forbidden, "3" if a _directory_ with that name already exists
327
    */
328
   public static int checkFile ( String file, boolean read_only, String provider ) {
329
           
330
          final File f = new File ( SextanteGUI.getSextantePath() + File.separator + file ); 
331
           
332
          if ( f.exists() ) {
333
                  if ( f.isDirectory() ) {
334
                          JOptionPane.showMessageDialog(null, 
335
                                          Sextante.getText("portable_file_error") + " " + f.getAbsolutePath() + ".\n" + 
336
                                          Sextante.getText("portable_file_is_dir") + "\n" +
337
                                          Sextante.getText("portable_provider_not_usable") + " <html></i>" + provider + "+</i>+</html>."
338
                                          , "Inane warning", JOptionPane.WARNING_MESSAGE);
339
                          return ( 3 );
340
                  }
341
                  if ( read_only ) {
342
                          if ( f.canRead() ) {
343
                                  return ( 0 );
344
                          }                                  
345
                  }
346
                  if ( f.canWrite() ) {
347
                          return ( 0 );
348
                  }
349
                  if ( read_only ) {
350
                          JOptionPane.showMessageDialog(null, 
351
                                          Sextante.getText("portable_file_error") + " " + f.getAbsolutePath() +
352
                                          Sextante.getText("portable_file_error_ro") + "\n" + ":" +
353
                                          Sextante.getText("portable_file_no_access") + "\n" +
354
                                          Sextante.getText("portable_provider_not_usable") + " <html></i>" + provider + "+</i>+</html>."
355
                                          , "Inane warning", JOptionPane.WARNING_MESSAGE);
356
                  } else {
357
                          JOptionPane.showMessageDialog(null, 
358
                                          Sextante.getText("portable_file_error") + " " + f.getAbsolutePath() +
359
                                          Sextante.getText("portable_file_error_rw") + "\n" + ":" +
360
                                          Sextante.getText("portable_file_no_access") + "\n" +
361
                                          Sextante.getText("portable_provider_not_usable") + " <html></i>" + provider + "+</i>+</html>."
362
                                          , "Inane warning", JOptionPane.WARNING_MESSAGE);                          
363
                  }
364
                  return ( 2 );                  
365
          }
366
          
367
          return ( 1 );
368
   }   
369
   
370
   
371
   /**
372
    * Portable SEXTANTE requires that external providers' (e.g. GRASS) algorithms
373
    * and user-editable scripts are stored in folders within the SEXTANTE extension
374
    * folder. In some case, read access to these folders is fine, in others r/w is required.
375
    * This method checks whether an algorithm provider has been set to be portable and
376
    * if so, it makes sure that the required folder(s) is/are present with the required
377
    * access rights. It will attempt to create any missing folders and will display a
378
    * warning if anythign goes wrong.
379
    */
380
   public static void checkPortableFolders () {
381
           
382
           String sPath;
383
           int result;
384
           
385
           
386
           sPath = new String ("");
387

    
388
           if ( Boolean.parseBoolean(SextanteGUI.getSettingParameterValue(SextanteRSettings.R_PORTABLE)) == true ) {
389
                   /* set R binaries folder */
390
                   result = checkDir ( Sextante.PORTABLE_R_FOLDER, true, "R" );
391
                   sPath = SextanteGUI.getSextantePath() + File.separator + Sextante.PORTABLE_R_FOLDER;             
392
                   SextanteGUI.setSettingParameterValue(SextanteRSettings.R_FOLDER, sPath);                   
393
                   
394
                   /* set R user scripts folder */
395
                   result = checkDir ( Sextante.PORTABLE_R_SCRIPTS_FOLDER, false, "R user scripts" );
396
                   sPath = SextanteGUI.getSextantePath() + File.separator + Sextante.PORTABLE_R_SCRIPTS_FOLDER;
397
                   SextanteGUI.setSettingParameterValue(SextanteRSettings.R_SCRIPTS_FOLDER, sPath);
398
           }
399
           if ( Boolean.parseBoolean(SextanteGUI.getSettingParameterValue(SextanteGrassSettings.GRASS_PORTABLE)) == true ) {
400
                   /* set GRASS binaries folder */
401
                   result = checkDir ( Sextante.PORTABLE_GRASS_FOLDER, true, "GRASS GIS" );
402
                   sPath = SextanteGUI.getSextantePath() + File.separator + Sextante.PORTABLE_GRASS_FOLDER;             
403
                   SextanteGUI.setSettingParameterValue(SextanteGrassSettings.GRASS_FOLDER, sPath);
404
                   /* set GRASS shell support (MSYS) binaries folder (Windows only) */
405
                   if ( Sextante.isWindows() ) {
406
                           result = checkFile ( Sextante.PORTABLE_MSYS_FILE, true, "GRASS GIS shell scripts" );
407
                           sPath = SextanteGUI.getSextantePath() + File.separator + Sextante.PORTABLE_MSYS_FILE;             
408
                           SextanteGUI.setSettingParameterValue(SextanteGrassSettings.GRASS_WIN_SHELL, sPath);
409
                   }
410
           }
411
           if ( Boolean.parseBoolean(SextanteGUI.getSettingParameterValue(SextanteSagaSettings.SAGA_PORTABLE)) == true ) {
412
                   /* set SAGA binaries folder */
413
                   result = checkDir ( Sextante.PORTABLE_SAGA_FOLDER, true, "SAGA GIS" );
414
                   sPath = SextanteGUI.getSextantePath() + File.separator + Sextante.PORTABLE_SAGA_FOLDER;             
415
                   SextanteGUI.setSettingParameterValue(SextanteSagaSettings.SAGA_FOLDER, sPath);
416
           }
417
           if ( Boolean.parseBoolean(SextanteGUI.getSettingParameterValue(SextanteScriptsSettings.SCRIPTS_PORTABLE)) == true ) {
418
                   /* set user scripts folder */
419
                   result = checkDir ( Sextante.PORTABLE_SCRIPTS_FOLDER, true, "SEXTANTE user scripts" );
420
                   sPath = SextanteGUI.getSextantePath() + File.separator + Sextante.PORTABLE_SCRIPTS_FOLDER;             
421
                   SextanteGUI.setSettingParameterValue(SextanteScriptsSettings.SCRIPTS_FOLDER, sPath);
422
           }
423
           if ( Boolean.parseBoolean(SextanteGUI.getSettingParameterValue(SextanteModelerSettings.MODELS_PORTABLE)) == true ) {
424
                   /* set user models folder */
425
                   result = checkDir ( Sextante.PORTABLE_MODELS_FOLDER, true, "SEXTANTE user models" );
426
                   sPath = SextanteGUI.getSextantePath() + File.separator + Sextante.PORTABLE_MODELS_FOLDER;             
427
                   SextanteGUI.setSettingParameterValue(SextanteModelerSettings.MODELS_FOLDER, sPath);
428
           }           
429
   }
430
   
431
   
432
   /**
433
    * Initializes the GUI parameters and resources. It takes GUI resources (custom panels, etc.) from classpath jars. Should be
434
    * called before setting parameters using other methods from this class, except for the setSextantePath() and
435
    * setCustomDefaultSettings() methods.
436
    */
437
   public static void initialize() {
438

    
439
      GUIResources.addResourcesFromClasspath();
440
      _initialize();
441

    
442
   }
443

    
444

    
445
   /**
446
    * Initializes the GUI parameters and resources. It takes GUI resources (custom panels, etc.) from the specified urls. Should
447
    * be called before setting parameters using other methods from this class, except for the setSextantePath() method.
448
    * 
449
    * @param jars
450
    *                the urls of the jar files with custom GUI resources
451
    */
452
   public static void initialize(final URL[] jars) {
453

    
454
      GUIResources.addResourcesFromURLs(jars);
455
      _initialize();
456

    
457
   }
458

    
459

    
460
   /**
461
    * Initializes the GUI parameters and resources. It takes GUI resources (custom panels, etc.) from the specified folder. Should
462
    * be called before setting parameters using other methods from this class, except for the setSextantePath() method.
463
    * 
464
    * @param sFolder
465
    *                the folder with jars with custom GUI resources
466
    */
467
   public static void initialize(final String sFolder) {
468

    
469
      GUIResources.addResourcesFromFolder(sFolder);
470
      _initialize();
471

    
472

    
473
   }
474

    
475

    
476
   private static void _initialize() {
477

    
478
      setDefaultSettings();
479
      readConfigFile();
480

    
481
      checkPortableFolders();
482
      
483
      //this loads built-in SEXTANTE algorithms and resources
484
      loadResources();
485

    
486
      //and this loads additional algorithms from algorithm providers
487
      for (int i = 0; i < m_AlgorithmProviders.size(); i++) {
488
         final IAlgorithmProvider provider = m_AlgorithmProviders.get(i);
489
         provider.initialize();
490
         if (provider.getAlgorithms().size() > 0) {
491
            Sextante.addAlgorithmsFromProvider(provider.getName(), provider.getAlgorithms());
492
            addCustomModelerParametersPanel(provider.getCustomModelerParameterPanels());
493
            addCustomParametersPanel(provider.getCustomParameterPanels());
494
         }
495
      }
496
      
497
   }
498

    
499

    
500
   private static void setDefaultSettings() {
501

    
502
      final Setting[] baseSettings = new Setting[] { new SextanteGeneralSettings() };
503
      final ArrayList<IAlgorithmProvider> providers = SextanteGUI.getAlgorithmProviders();
504
      final Setting[] settings = new Setting[baseSettings.length + providers.size()];
505
      System.arraycopy(baseSettings, 0, settings, 0, baseSettings.length);
506
      for (int i = 0; i < providers.size(); i++) {
507
         settings[i + baseSettings.length] = providers.get(i).getSettings();
508
      }
509

    
510
      for (int i = 0; i < settings.length; i++) {
511
         final HashMap<String, String> map = settings[i].getInitValues();
512
         m_Settings.putAll(map);
513
      }
514

    
515
      if (m_DefaultSettings != null) {
516
         m_Settings.putAll(m_DefaultSettings);
517
      }
518

    
519
   }
520

    
521

    
522
   /**
523
    * This methods sets default setting values different from the hard-coded ones. It should be called right before initializing
524
    * this class
525
    * 
526
    * @param map
527
    *                the map with new default settings
528
    */
529
   public static void setCustomDefaultSettings(final HashMap<String, String> map) {
530

    
531
      m_DefaultSettings = map;
532

    
533
   }
534

    
535

    
536
   private static void loadResources() {
537

    
538
      final String[] sPanelClassName = GUIResources.getParameterPanelClassNames();
539
      for (final String element : sPanelClassName) {
540
         try {
541
            final Class panelClass = Class.forName(element);
542
            final String sAlgClassName = element.substring(0, element.indexOf("ParametersPanel")) + "Algorithm";
543
            final Class algClass = Class.forName(sAlgClassName);
544
            final GeoAlgorithm alg = (GeoAlgorithm) algClass.newInstance();
545
            m_ParametersPanel.put(alg.getCommandLineName(), panelClass);
546
         }
547
         catch (final Exception e) {/*ignore it if there are problems*/
548
         }
549
      }
550

    
551
      final String[] sModelerPanelClassName = GUIResources.getModelerParameterPanelClassNames();
552
      for (final String element : sModelerPanelClassName) {
553
         try {
554
            final Class panelClass = Class.forName(element);
555
            final String sAlgClassName = element.substring(0, element.indexOf("ModelerParametersPanel")) + "Algorithm";
556
            final Class algClass = Class.forName(sAlgClassName);
557
            final GeoAlgorithm alg = (GeoAlgorithm) algClass.newInstance();
558
            m_ModelerParametersPanel.put(alg.getCommandLineName(), panelClass);
559
         }
560
         catch (final Exception e) {/*ignore it if there are problems*/
561
         }
562
      }
563

    
564

    
565
   }
566

    
567

    
568
   /**
569
    * Returns the path to help files
570
    * 
571
    * @return the path to help files
572
    */
573
   public static String getHelpPath() {
574

    
575
      return m_sSextantePath + File.separator + "help";
576

    
577
   }
578

    
579

    
580
   /**
581
    * Sets the current path to sextante folder. This is the folder where help files and additional software should be located.
582
    * This should be done before initializing this class, since this folder is used by some algorithm providers
583
    * 
584
    * @param sPath
585
    *                the path to sextante help and additional programs
586
    */
587
   public static void setSextantePath(final String sPath) {
588

    
589
      m_sSextantePath = sPath;
590

    
591
   }
592

    
593

    
594
   /**
595
    * Returns the path to sextante help and additional programs
596
    * 
597
    * @return the path to sextante help and additional programs
598
    */
599
   public static String getSextantePath() {
600

    
601
      return m_sSextantePath;
602

    
603
   }
604

    
605

    
606
   /**
607
    * Returns the default folder for output data.
608
    * 
609
    * @return the default folder for output data.
610
    */
611
   public static String getOutputFolder() {
612

    
613
      if ((m_sOutputFolder == null) || m_sOutputFolder.trim().equals("")) {
614
         return System.getProperty("user.home");
615
      }
616
      else {
617
         return m_sOutputFolder;
618
      }
619

    
620
   }
621

    
622

    
623
   /**
624
    * Returns the default value to represent "No Data" (null) raster cells.
625
    * 
626
    * @return the current "No Data" value.
627
    */
628
   private static Double getDefaultNoDataValue() {
629

    
630
      try {
631
         final double dNoDataValue = Double.parseDouble(SextanteGUI.getSettingParameterValue(SextanteGeneralSettings.DEFAULT_NO_DATA_VALUE));
632
         return dNoDataValue;
633
      }
634
      catch (final Exception e) {
635
         return new Double(-99999d);
636
      }
637

    
638
   }
639

    
640

    
641
   /**
642
    * Loads configuration parameters from the config file
643
    */
644
   private static void readConfigFile() {
645

    
646
      BufferedReader input = null;
647
      try {
648
         input = new BufferedReader(new FileReader(getConfigFile()));
649
         String sLine = null;
650
         while ((sLine = input.readLine()) != null) {
651
            final String[] sTokens = sLine.split("=");
652
            if (sTokens.length == 2) {
653
               m_Settings.put(sTokens[0], sTokens[1]);
654
            }
655
         }
656
      }
657
      catch (final FileNotFoundException e) {
658
      }
659
      catch (final IOException e) {
660
      }
661
      finally {
662
         try {
663
            if (input != null) {
664
               input.close();
665
            }
666
         }
667
         catch (final IOException e) {
668
            Sextante.addErrorToLog(e);
669
         }
670
      }
671

    
672
   }
673

    
674

    
675
   /**
676
    * Saves current settings to the config file
677
    */
678
   public static void saveSettings() {
679

    
680
      Writer output = null;
681
      try {
682
         output = new BufferedWriter(new FileWriter(getConfigFile()));
683
         final Set<String> set = m_Settings.keySet();
684
         final Iterator<String> iter = set.iterator();
685
         while (iter.hasNext()) {
686
            final String sKey = iter.next();
687
            final String sValue = m_Settings.get(sKey);
688
            output.write(sKey + "=" + sValue + "\n");
689
         }
690
      }
691
      catch (final IOException e) {
692
         Sextante.addErrorToLog(e);
693
      }
694
      finally {
695
         if (output != null) {
696
            try {
697
               output.close();
698
            }
699
            catch (final IOException e) {
700
               Sextante.addErrorToLog(e);
701
            }
702
         }
703
      }
704

    
705
   }
706

    
707

    
708
   /**
709
    * Returns the path to the SEXTANTE config file.
710
    * 
711
    * @return A string with the full the path and name of the SEXTANTE config file.
712
    */
713
   private static String getConfigFile() {
714

    
715
      final String sPath = getUserFolder();
716

    
717
      return sPath + File.separator + "sextante.settings";
718

    
719
   }
720

    
721

    
722
   /**
723
    * Returns the folder in which the SEXTANTE config file is stored.
724
    * By default, this is the folder "sextante" in the user's home folder.
725
    * But it is also possible to set a different folder through the
726
    * Java property "SEXTANTE.confDir" when launching the VM:
727
    * 
728
    *   java -DSEXTANTE.confDir=<path>
729
    * 
730
    * @return A string with the full path and name of the config folder.
731
    */
732
   public static String getUserFolder() {
733

    
734
      String sPath;
735
      String sConfDir;
736

    
737
      
738
      // default is to use system's home folder setting
739
      sPath = System.getProperty("user.home") + File.separator + "sextante"; 
740
      
741
      // check if SEXTANTE.confDir has been set
742
      sConfDir = System.getProperty("SEXTANTE.confDir");            
743
      if ( sConfDir != null ) {
744
              sConfDir = sConfDir.trim();
745
                      if ( sConfDir.length() > 0 ) {
746
                              // check if we have to append a separator char
747
                              if ( sConfDir.endsWith(File.separator) ) {
748
                                      sPath = sConfDir;
749
                              } else {
750
                                      sPath = sConfDir + File.separator;
751
                                }
752
                        }
753
      }
754

    
755
      final File sextanteFolder = new File(sPath);
756
      if (!sextanteFolder.exists()) {
757
              sextanteFolder.mkdir();
758
      }
759
      return sPath;
760

    
761
   }
762

    
763

    
764
   /**
765
    * Returns the type of the last element from which a command-line command was executed
766
    * 
767
    * @return the type of the element from which a command-line command was executed. SextanteGUI.HISTORY if the last component
768
    *         was the history panel; SextanteGUI.COMMANDLINE if it was the regular SEXTANTE console
769
    */
770
   public static int getLastCommandOrigin() {
771

    
772
      return m_iLastCommandOrigin;
773

    
774
   }
775

    
776

    
777
   /**
778
    * Sets the type of the last element from which a command-line command was executed. This has to be called from any component
779
    * that allows execution of commands
780
    * 
781
    * @param iLast
782
    *                one of the following constants: SextanteGUI.HISTORY if the last component was the history panel;
783
    *                SextanteGUI.COMMANDLINE if it was the regular SEXTANTE console
784
    */
785
   public static void setLastCommandOrigin(final int iLast) {
786

    
787
      m_iLastCommandOrigin = iLast;
788

    
789
   }
790

    
791

    
792
   /**
793
    * Gets the dialog from which the last command--line command was executed. This will be used as the parent dialog for task
794
    * monitors or message dialogs generated by the execution of that command.
795
    * 
796
    * @return the dialog from which the last command--line command was executed
797
    */
798
   public static JDialog getLastCommandOriginParentDialog() {
799

    
800
      return m_LastCommandOriginParentPanel;
801

    
802
   }
803

    
804

    
805
   /**
806
    * Sets the dialog (if any) that contains the element from which the last command--line command was executed
807
    * 
808
    * @param parent
809
    *                the dialog (if any) that contains the element from which the last command--line command was executed
810
    */
811
   public static void setLastCommandOriginParentDialog(final JDialog parent) {
812

    
813
      m_LastCommandOriginParentPanel = parent;
814

    
815
   }
816

    
817

    
818
   /**
819
    * Returns true if only active algorithms (those that can be executed with the current data objects) should be shown in the
820
    * toolbox
821
    * 
822
    * @return true if only active algorithms (those that can be executed with the current data objects) should be shown in the
823
    *         toolbox
824
    */
825
   public static boolean getShowOnlyActiveAlgorithms() {
826

    
827
      return m_bShowOnlyActiveAlgorithms;
828

    
829
   }
830

    
831

    
832
   /**
833
    * Sets whether only active algorithms (those that can be executed with the current data objects) should be shown in the
834
    * toolbox
835
    * 
836
    * @param showOnlyActiveAlgorithms
837
    *                must be true if only active algorithms (those that can be executed with the current data objects) should be
838
    *                shown in the toolbox
839
    */
840
   public static void setShowOnlyActiveAlgorithms(final boolean showOnlyActiveAlgorithms) {
841

    
842
      m_bShowOnlyActiveAlgorithms = showOnlyActiveAlgorithms;
843

    
844
   }
845

    
846

    
847
   /**
848
    * puts a collection of settings into the settings map
849
    * 
850
    * @param settings
851
    *                the map with settings values.
852
    */
853
   public static void setSettings(final HashMap<String, String> settings) {
854

    
855
      m_Settings.putAll(settings);
856

    
857
   }
858

    
859

    
860
   /**
861
    * Modifies the passed string, so it can be used as a safe data object name (without special characters)
862
    * 
863
    * @param sName
864
    *                the name to modify
865
    * @return the modified safe name (with no special characters)
866
    */
867
   public static String modifyResultName(String sName) {
868

    
869
      sName = sName.replaceAll("\\.", "_");
870
      sName = sName.replaceAll(" ", "_");
871
      sName = sName.replaceAll("\\[", "_");
872
      sName = sName.replaceAll("\\]", "_");
873
      sName = sName.replaceAll("\\(", "_");
874
      sName = sName.replaceAll("\\)", "_");
875
      sName = sName.replaceAll("á", "a");
876
      sName = sName.replaceAll("é", "e");
877
      sName = sName.replaceAll("í", "i");
878
      sName = sName.replaceAll("ó", "o");
879
      sName = sName.replaceAll("ú", "u");
880
      sName = sName.replaceAll("ñ", "n");
881

    
882
      return sName;
883

    
884
   }
885

    
886

    
887
   private static void addCustomParametersPanel(final HashMap<String, Class> map) {
888

    
889
      m_ParametersPanel.putAll(map);
890

    
891
   }
892

    
893

    
894
   private static void addCustomModelerParametersPanel(final HashMap<String, Class> map) {
895

    
896
      m_ModelerParametersPanel.putAll(map);
897

    
898
   }
899

    
900

    
901
   public static Class getModelerParametersPanel(final String sName) {
902

    
903
      return m_ModelerParametersPanel.get(sName);
904

    
905
   }
906

    
907

    
908
   public static Class getParametersPanel(final String sName) {
909

    
910
      return m_ParametersPanel.get(sName);
911

    
912
   }
913

    
914

    
915
   public static ImageIcon getAlgorithmIcon(final GeoAlgorithm alg) {
916

    
917
      final String sName = Sextante.getAlgorithmProviderName(alg);
918
      for (int i = 0; i < m_AlgorithmProviders.size(); i++) {
919
         if (m_AlgorithmProviders.get(i).getName().equals(sName)) {
920
            return m_AlgorithmProviders.get(i).getIcon();
921
         }
922
      }
923
      return SEXTANTE_ICON;
924

    
925
   }
926

    
927

    
928
   public static ArrayList<IAlgorithmProvider> getAlgorithmProviders() {
929

    
930
      return m_AlgorithmProviders;
931

    
932
   }
933

    
934

    
935
   public static String getSettingParameterValue(final String sParameterName) {
936

    
937
      return m_Settings.get(sParameterName);
938

    
939
   }
940

    
941

    
942
   public static String setSettingParameterValue(final String sParameterName,
943
                                                 final String sValue) {
944

    
945
      return m_Settings.put(sParameterName, sValue);
946

    
947
   }
948

    
949

    
950
   public static void updateAlgorithmProvider(final Class providerClass) {
951

    
952
      for (int i = 0; i < m_AlgorithmProviders.size(); i++) {
953
         final IAlgorithmProvider provider = m_AlgorithmProviders.get(i);
954
         if (providerClass.isInstance(provider)) {
955
            provider.update();
956
            Sextante.addAlgorithmsFromProvider(provider.getName(), provider.getAlgorithms());
957
         }
958
      }
959

    
960
   }
961

    
962

    
963
   public static Object getAlgorithmHelp(final GeoAlgorithm alg) {
964

    
965
      final String sName = Sextante.getAlgorithmProviderName(alg);
966
      for (int i = 0; i < m_AlgorithmProviders.size(); i++) {
967
         if (m_AlgorithmProviders.get(i).getName().equals(sName)) {
968
            return m_AlgorithmProviders.get(i).getAlgorithmHelp(alg);
969
         }
970
      }
971
      String sFilename;
972
      String sPath;
973
      if (sName.equals("SEXTANTE")) {
974
         sFilename = alg.getCommandLineName() + ".xml";
975
         sPath = HelpIO.getHelpPath(alg, false);
976
         return HelpIO.getHelpAsHTMLCode(alg, sPath + File.separator + sFilename);
977
      }
978
      else {
979
         return ""; //TODO:create default help page
980
      }
981

    
982
   }
983

    
984

    
985
   public static String getAlgorithmHelpFilename(final GeoAlgorithm alg,
986
                                                 final boolean bForceCurrentLocale) {
987

    
988
      final String sName = Sextante.getAlgorithmProviderName(alg);
989
      for (int i = 0; i < m_AlgorithmProviders.size(); i++) {
990
         if (m_AlgorithmProviders.get(i).getName().equals(sName)) {
991
            return m_AlgorithmProviders.get(i).getAlgorithmHelpFilename(alg, bForceCurrentLocale);
992
         }
993
      }
994
      String sFilename;
995
      String sPath;
996
      if (sName.equals("SEXTANTE")) {
997
         sFilename = alg.getCommandLineName() + ".xml";
998
         sPath = HelpIO.getHelpPath(alg, false);
999
         return sPath + File.separator + sFilename;
1000
      }
1001
      else {
1002
         return ""; //TODO:create default help page
1003
      }
1004

    
1005
   }
1006

    
1007

    
1008
   public static HashMap<NameAndIcon, ArrayList<ToolboxAction>> getToolboxActions() {
1009

    
1010

    
1011
      final HashMap<NameAndIcon, ArrayList<ToolboxAction>> map = new HashMap<NameAndIcon, ArrayList<ToolboxAction>>();
1012
      for (int i = 0; i < m_AlgorithmProviders.size(); i++) {
1013
         final IAlgorithmProvider provider = m_AlgorithmProviders.get(i);
1014
         map.putAll(provider.getToolboxActions());
1015
      }
1016
      map.putAll(SextanteGUI.getGUIFactory().getToolboxActions());
1017
      return map;
1018
   }
1019

    
1020

    
1021
   public static IToolboxRightButtonAction[] getToolboxRightButtonActions() {
1022

    
1023
           final ArrayList<IToolboxRightButtonAction> list = new ArrayList<IToolboxRightButtonAction>();
1024
           for (int i = 0; i < m_AlgorithmProviders.size(); i++) {
1025
                   final IAlgorithmProvider provider = m_AlgorithmProviders.get(i);
1026
                   final IToolboxRightButtonAction[] actions = provider.getToolboxRightButtonActions();
1027
                   for (int j = 0; j < actions.length; j++) {
1028
                           list.add(actions[j]);
1029
                   }
1030
           }
1031
      return list.toArray(new IToolboxRightButtonAction[0]);
1032

    
1033
   }
1034

    
1035

    
1036
   /**
1037
    * Returns the renderer to use for layers created by SEXTANTE algorithms
1038
    * 
1039
    */
1040
   public static IDataRenderer getDataRenderer() {
1041

    
1042
      return m_Renderer;
1043

    
1044
   }
1045

    
1046

    
1047
   public static void setDataRenderer(final IDataRenderer renderer) {
1048

    
1049
      m_Renderer = renderer;
1050

    
1051
   }
1052
}