source: trunk/gli/src/org/greenstone/gatherer/Configuration.java@ 4318

Last change on this file since 4318 was 4302, checked in by jmt12, 21 years ago

bug fix

  • Property svn:keywords set to Author Date Id Revision
File size: 26.5 KB
Line 
1package org.greenstone.gatherer;
2/**
3 *#########################################################################
4 *
5 * A component of the Gatherer application, part of the Greenstone digital
6 * library suite from the New Zealand Digital Library Project at the
7 * University of Waikato, New Zealand.
8 *
9 * <BR><BR>
10 *
11 * Author: John Thompson, Greenstone Digital Library, University of Waikato
12 *
13 * <BR><BR>
14 *
15 * Copyright (C) 1999 New Zealand Digital Library Project
16 *
17 * <BR><BR>
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * <BR><BR>
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * <BR><BR>
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 *########################################################################
37 */
38import java.awt.*;
39import java.io.*;
40import java.lang.ref.*;
41import java.net.*;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.plaf.*;
45import org.greenstone.gatherer.Message;
46import org.greenstone.gatherer.gui.Coloring;
47import org.greenstone.gatherer.msm.MSMUtils;
48import org.greenstone.gatherer.util.GURL;
49import org.greenstone.gatherer.util.Utility;
50import org.w3c.dom.*;
51/** This class stores the various configurable settings inside the Gatherer, both during a session, and between sessions in the form of XML. However not all data members are retained during xml serialization. To further improve efficiency, the property-name -> DOM Element pairs are stored in a SoftReferenced Hashtable.
52 * @author John Thompson, Greenstone Digital Library, University of Waikato
53 * @version 2.3
54 */
55public class Configuration
56 extends Hashtable {
57 public File exec_file;
58 /** The path (or url) to the webserver which is serving the Greenstone collection. */
59 public String exec_path = null;
60 /** The path to the Greenstone Suite installation directory. */
61 public String gsdl_path = "";
62 /** The path to the PERL executable, up to and including Perl.exe. */
63 public String perl_path = "";
64 /** The password for the proxy server indicated above. */
65 public String proxy_pass = null;
66 /** The username for the proxy server indicated above. */
67 public String proxy_user = null;
68 /** The screen size of the desktop the Gatherer will be displayed on. */
69 public Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
70 /** Collection level configuration (which in some cases overrides general configuration. */
71 private Document collection_config;
72 /** The general configuration settings. */
73 private Document general_config;
74 private int cache_hit = 0;
75 private int cache_miss = 0;
76 public URL exec_address = null;
77 /** The string identifying an argument's name attribute. */
78 static final private String ARGUMENT_NAME = "name";
79 /** The name of the general Gatherer configuration file. */
80 static final private String CONFIG_XML = "config.xml";
81 /** The name of the root element of the subtree containing gatherer configuration options. This is required as the document itself may contain several other subtrees of settings (such as in the case of a '.col' file). */
82 static final private String GATHERER_CONFIG = "GathererConfig";
83 /** The string identifying an argument element. */
84 static final private String GATHERER_CONFIG_ARGUMENT = "Argument";
85 /** The name of a Name Element. */
86 static final private String NAME = "Name";
87 /** The name of the other arguments element. */
88 static final private String OTHER = "Other";
89 /** The name of an information Element within the Other subtree. */
90 static final private String OTHER_INFO = "Info";
91 /** The name of the general Gatherer configuration template. */
92 static final private String TEMPLATE_CONFIG_XML = "xml/config.xml";
93 /** The first of two patterns used during tokenization, this pattern handles a comma separated list. */
94 static final private String TOKENIZER_PATTERN1 = " ,\n\t";
95 /** The second of two patterns used during tokenization, this pattern handles an underscore separated list. */
96 static final private String TOKENIZER_PATTERN2 = "_\n\t";
97 /** Constructor.
98 * @param gsdl_path The path to the Greenstone directory as a <strong>String</strong>.
99 * @param exec_path A <strong>String</strong> containing the path or url to the webserver serving the greenstone collections.
100 * @param perl_path The path to the PERL executable, as a <strong>String</strong>.
101 */
102 public Configuration(String gsdl_path, String exec_path, String perl_path) {
103 super();
104 this.gsdl_path = gsdl_path;
105 this.exec_path = exec_path;
106 // The exec_path may contain an url address, in which case we blindly use that and leave it up to the user to worry about settings and resetting.
107 System.err.println("EXEC_PATH = " + exec_path);
108 if(exec_path != null && exec_path.length() > 0) {
109 try {
110 // If its missing the protocol add it now.
111 if(exec_path.indexOf("://") != -1) {
112 exec_address = new URL(exec_path);
113 }
114 else {
115 exec_address = new URL("http://" + exec_path);
116 }
117 }
118 catch (MalformedURLException error) {
119 System.err.println("Not an address.");
120 }
121 }
122 // If the above failed, then its up to us to try and figure out what to do.
123 if(exec_address == null) {
124 // Try building a file from the given exec_path
125 try {
126 File local_file = new File(exec_path);
127 if(local_file.exists()) {
128 // All good. I hope.
129 exec_file = local_file;
130 }
131 }
132 // All sorts of errors might be thrown by a bogus file path.
133 catch (Exception error) {
134 System.err.println("Not a valid file.");
135 }
136 // We can generate the path to where the local library should be and use that if it is there.
137 if(exec_file == null) {
138 File server_exe = new File(gsdl_path + Utility.SERVER_EXE);
139 if(server_exe.exists()) {
140 exec_file = server_exe;
141 }
142 else {
143 System.err.println("No local library.");
144 }
145 }
146 // If we get to here with no exec_address nor an exec_file its just plain not going to work.
147 }
148 this.perl_path = perl_path;
149 // Ensure the perl path includes exe under windoze
150 if(Utility.isWindows() && !perl_path.toLowerCase().endsWith(".exe")) {
151 if(!perl_path.endsWith(File.separator)) {
152 perl_path = perl_path + File.separator;
153 }
154 perl_path = perl_path + "perl.exe";
155 }
156 // Try to reload the configuration.
157 File config_xml = new File(CONFIG_XML);
158 if(config_xml.exists()) {
159 general_config = Utility.parse(CONFIG_XML, false);
160 }
161 // If that fails retrieve the default configuration file from our xml library, which I'll personally guarantee to work.
162 if(general_config == null) {
163 general_config = Utility.parse(TEMPLATE_CONFIG_XML, true);
164 Gatherer.println("Loaded default Gatherer configuration template.");
165 }
166 else {
167 Gatherer.println("Loaded current Gatherer configuration.");
168 }
169 // Re-establish the color settings.
170 updateUI();
171 }
172
173 /** The default get action retrieves the named property from the desired configuration, and returns a true or false. */
174 public boolean get(String property, boolean general) {
175 String raw = getString(property, general);
176 return (raw != null && raw.equalsIgnoreCase("true"));
177 }
178
179 /** Retrieve all of the configuration preferences which match a certain string. They are returned as a hash map of property names to String objects. */
180 public HashMap getAll(String property_pattern, boolean general) {
181 HashMap properties = new HashMap();
182 try {
183 // Locate the appropriate element
184 Element document_element = null;
185 if(general) {
186 document_element = general_config.getDocumentElement();
187 }
188 else if(collection_config != null) {
189 document_element = collection_config.getDocumentElement();
190 }
191 if(document_element != null) {
192 // Retrieve the Gatherer element
193 Element gatherer_element = (Element) MSMUtils.getNodeFromNamed(document_element, GATHERER_CONFIG);
194 NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
195 for(int i = 0; i < arguments.getLength(); i++) {
196 Element argument_element = (Element) arguments.item(i);
197 if(argument_element.getAttribute(ARGUMENT_NAME).matches(property_pattern)) {
198 String result = MSMUtils.getValue(argument_element);
199 // Store a mapping in the cache. Sometimes we will overwrite an existing value (say for collection and general level workflow options) but the processing overhead of detecting these clashes far exceeds any savings.
200 put(argument_element.getAttribute(ARGUMENT_NAME) + general, new SoftReference(argument_element));
201 // Add mapping to the properties we're going to return
202 properties.put(argument_element.getAttribute(ARGUMENT_NAME), result);
203 }
204 }
205 }
206 }
207 catch(Exception error) {
208 }
209 return properties;
210 }
211
212 /** Retrieve the information subtree containing the arguments for the desired external program. If the program has marked superclasses append their arguments as well. */
213 public Element getArguments(String filename) {
214 Element argument_element = null;
215 try {
216 // Retrieve the other information subtree.
217 Element document_element = general_config.getDocumentElement();
218 Element other_element = (Element) MSMUtils.getNodeFromNamed(document_element, OTHER);
219 NodeList argument_elements = other_element.getElementsByTagName(OTHER_INFO);
220 for(int i = 0; argument_element == null && i < argument_elements.getLength(); i++) {
221 Element possible_element = (Element) argument_elements.item(i);
222 Element possible_name_element = (Element) MSMUtils.getNodeFromNamed(possible_element, NAME);
223 String possible_name = MSMUtils.getValue(possible_name_element);
224 ///ystem.err.println("Does " + possible_name + " equal " + filename);
225 if(possible_name.equalsIgnoreCase(filename)) {
226 argument_element = possible_element;
227 }
228 possible_name = null;
229 possible_name_element = null;
230 possible_element = null;
231 }
232 argument_elements = null;
233 other_element = null;
234 document_element = null;
235 }
236 catch(Exception error) {
237 }
238 return argument_element;
239 }
240
241 /** Retrieve the value of the named property as a Color. */
242 public Color getColor(String property, boolean general) {
243 Color result = Color.white; // Default
244 try {
245 String raw = getString(property, general);
246 // Color is a RGB triplet list, comma separated (also remove whitespace)
247 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
248 int red = Integer.parseInt(tokenizer.nextToken());
249 int green = Integer.parseInt(tokenizer.nextToken());
250 int blue = Integer.parseInt(tokenizer.nextToken());
251 result = new Color(red, green, blue);
252 }
253 catch(Exception error) {
254 Gatherer.printStackTrace(error);
255 }
256 return result;
257 }
258
259 /** Retrieve the value of the named property as a Dimension. */
260 public Dimension getDimension(String property, boolean general) {
261 Dimension result = new Dimension(100, 100); // Default
262 try {
263 String raw = getString(property, general);
264 // Dimension is a width by height pair, comma separated (also remove whitespace)
265 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
266 int width = Integer.parseInt(tokenizer.nextToken());
267 int height = Integer.parseInt(tokenizer.nextToken());
268 result = new Dimension(width, height);
269 }
270 catch(Exception error) {
271 Gatherer.printStackTrace(error);
272 }
273 return result;
274 }
275
276 /** Retrieve the value of the named property as a FontUIResource. */
277 public FontUIResource getFont(String property, boolean general) {
278 FontUIResource result = new FontUIResource("Times New Roman", Font.PLAIN, 10);
279 try {
280 String raw = getString(property, general);
281 // Font is a face, style, size triplet.
282 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN1);
283 String face = tokenizer.nextToken();
284 int style = Font.PLAIN;
285 String temp = tokenizer.nextToken().toUpperCase();
286 if(temp.equals("BOLD")) {
287 style = Font.BOLD;
288 }
289 else if(temp.equals("ITALIC")) {
290 style = Font.ITALIC;
291 }
292 int size = Integer.parseInt(tokenizer.nextToken());
293 result = new FontUIResource(face, style, size);
294 }
295 catch(Exception error) {
296 Gatherer.printStackTrace(error);
297 }
298 return result;
299 }
300
301 /** Retrieve the value of the named property as an integer. */
302 public int getInt(String property, boolean general) {
303 int result = -1;
304 try {
305 String raw = getString(property, general);
306 result = Integer.parseInt(raw);
307 }
308 catch(Exception error) {
309 Gatherer.printStackTrace(error);
310 }
311 return result;
312 }
313
314 /** Retrieve the value of the named property as a Locale. */
315 public Locale getLocale(String property, boolean general) {
316 Locale result = Locale.getDefault();
317 try {
318 String raw = getString(property, general);
319 // Locale is a underscore separated code.
320 StringTokenizer tokenizer = new StringTokenizer(raw, TOKENIZER_PATTERN2);
321 String language = tokenizer.nextToken();
322 String country = tokenizer.nextToken();
323 result = new Locale(language, country);
324 }
325 catch(Exception error) {
326 Gatherer.printStackTrace(error);
327 }
328 return result;
329 }
330
331 /** Retrieve the value of the named property, and noting whether we consult the general or collection specific configuration. */
332 public String getString(String property, boolean general) {
333 // Its up to this method to find the appropriate node and retrieve the data itself.
334 String result = "";
335 try {
336 // First of all we look in the cache to see if we have a match.
337 SoftReference reference = (SoftReference) get(property + general);
338 if(reference != null) {
339 Element argument_element = (Element) reference.get();
340 if(argument_element != null) {
341 cache_hit++;
342 result = MSMUtils.getValue(argument_element);
343 }
344 }
345 // We may have missed in the cache, or the reference may have been consumed.
346 if(result.length() == 0) {
347 cache_miss++;
348 // Locate the appropriate element
349 Element document_element = null;
350 if(general) {
351 document_element = general_config.getDocumentElement();
352 }
353 else if(collection_config != null) {
354 document_element = collection_config.getDocumentElement();
355 }
356 if(document_element != null) {
357 // Retrieve the Gatherer element
358 Element gatherer_element = (Element) MSMUtils.getNodeFromNamed(document_element, GATHERER_CONFIG);
359 NodeList arguments = gatherer_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
360 for(int i = 0; result.length() == 0 && i < arguments.getLength(); i++) {
361 Element argument_element = (Element) arguments.item(i);
362 if(argument_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) {
363 result = MSMUtils.getValue(argument_element);
364 // Store a mapping in the cache. Sometimes we will overwrite an existing value (say for collection and general level workflow options) but the processing overhead of detecting these clashes far exceeds any savings.
365 put(property + general, new SoftReference(argument_element));
366 }
367 }
368 }
369 }
370 }
371 catch (Exception error) {
372 Gatherer.printStackTrace(error);
373 }
374 // If we still have no result, and the search was made in the collection configuration, retrieve the general one instead.
375 if(result.length() == 0 && !general) {
376 result = getString(property, true);
377 }
378 return result;
379 }
380
381 /** Retrieve the path to the PERL scripts within the Greenstone directory.
382 * @return A <strong>String</strong> containing the path.
383 */
384 public String getScriptPath() {
385 return gsdl_path + "bin" + File.separator + "script" + File.separator;
386 }
387
388 /** Export the general configuration to file. */
389 public void save() {
390 ///ystem.err.println("Hits " + cache_hit + " vs Misses " + cache_miss);
391 Utility.export(general_config, Utility.BASE_DIR + CONFIG_XML);
392 }
393
394 /** Set the named property, from the specified configuration, using the given boolean value. */
395 public void set(String property, boolean general, boolean value) {
396 setString(property, general, (value ? "true" : "false"));
397 }
398
399 /** Add a subtree of argument information to the other arguments part of the general configuration. This overwrites any such existing subtree. */
400 public void setArguments(Element arguments_element) {
401 try {
402 Element document_element = general_config.getDocumentElement();
403 Element other_element = (Element) MSMUtils.getNodeFromNamed(document_element, OTHER);
404 // Retrieve the name of the information
405 Element arguments_name_element = (Element)MSMUtils.getNodeFromNamed(arguments_element, NAME);
406 String filename = MSMUtils.getValue(arguments_element);
407 // Find any argument information subtree starting with the same name
408 Element obsolete_arguments_element = getArguments(filename);
409 // Create a copy of the arguments_element within our tree (import).
410 Element our_arguments_element = (Element) general_config.importNode(arguments_element, true);
411 // Now we insert this new node into the tree. If a previous node exists we replace it instead.
412 if(obsolete_arguments_element == null) {
413 other_element.appendChild(our_arguments_element);
414 }
415 else {
416 other_element.replaceChild(our_arguments_element, obsolete_arguments_element);
417 }
418 our_arguments_element = null;
419 obsolete_arguments_element = null;
420 filename = null;
421 arguments_name_element = null;
422 other_element = null;
423 document_element = null;
424 }
425 catch (Exception error) {
426 Gatherer.println("Error in Configuration.setArguments(): " + error);
427 Gatherer.printStackTrace(error);
428 }
429 }
430
431 /** Set the collection configuration. */
432 public void setCollectionConfiguration(Document collection_config) {
433 this.collection_config = collection_config;
434 updateUI();
435 ///atherer.println("Collection configuration set.");
436 }
437
438 /** Set the named property, from the specified configuration, using the given Color value. */
439 public void setColor(String property, boolean general, Color value) {
440 StringBuffer text = new StringBuffer("");
441 text.append(value.getRed());
442 text.append(", ");
443 text.append(value.getGreen());
444 text.append(", ");
445 text.append(value.getBlue());
446 setString(property, general, text.toString());
447 }
448
449 /** Set the named property, from the specified configuration, using the given Dimension value. */
450 public void setDimension(String property, boolean general, Dimension value) {
451 StringBuffer text = new StringBuffer("");
452 text.append(value.width);
453 text.append(", ");
454 text.append(value.height);
455 setString(property, general, text.toString());
456 }
457
458 /** Set the named property, from the specified configuration, using the given Font value. */
459 public void setFont(String property, boolean general, Font value) {
460 StringBuffer text = new StringBuffer("");
461 text.append(value.getName());
462 text.append(", ");
463 switch(value.getStyle()) {
464 case Font.BOLD:
465 text.append("BOLD");
466 break;
467 case Font.ITALIC:
468 text.append("ITALIC");
469 break;
470 default:
471 text.append("PLAIN");
472 }
473 text.append(", ");
474 text.append(value.getSize());
475 setString(property, general, text.toString());
476 }
477
478 /** Set the named property, from the specified configuration, using the given integer value. */
479 public void setInt(String property, boolean general, int value) {
480 setString(property, general, String.valueOf(value));
481 }
482
483 /** Set the named property, from the specified configuration, using the given Locale value. */
484 public void setLocale(String property, boolean general, Locale value) {
485 StringBuffer text = new StringBuffer("");
486 text.append(value.getLanguage());
487 text.append("_");
488 text.append(value.getCountry());
489 setString(property, general, text.toString());
490 }
491
492 /** Sets the value of the named property argument using the given string. */
493 public void setString(String property, boolean general, String value) {
494 ///atherer.println("Set configuration property: " + property + " = " + value + (general ? "" : " [Collection]"));
495 try {
496 Document document = null;
497 if(general) {
498 document = general_config;
499 }
500 else if(collection_config != null) {
501 document = collection_config;
502 }
503 if(document != null) {
504 Element argument_element = null;
505 // Try to retrieve from cache
506 SoftReference reference = (SoftReference) get(property + general);
507 if(reference != null) {
508 argument_element = (Element) reference.get();
509 }
510 if(argument_element == null) {
511 Element document_element = document.getDocumentElement();
512 Element gatherer_element = (Element) MSMUtils.getNodeFromNamed(document_element, GATHERER_CONFIG);
513 NodeList arguments = document_element.getElementsByTagName(GATHERER_CONFIG_ARGUMENT);
514 boolean found = false;
515 for(int i = 0; argument_element == null && i < arguments.getLength(); i++) {
516 Element possible_element = (Element) arguments.item(i);
517 if(possible_element.getAttribute(ARGUMENT_NAME).equalsIgnoreCase(property)) {
518 argument_element = possible_element;
519 }
520 }
521 // If argument element is still null, create it in the target document.
522 if(argument_element == null) {
523 argument_element = document.createElement(GATHERER_CONFIG_ARGUMENT);
524 argument_element.setAttribute(ARGUMENT_NAME, property);
525 gatherer_element.appendChild(argument_element);
526 }
527 // Update cache
528 put(property + general, new SoftReference(argument_element));
529
530 }
531 if(value == null) {
532 value = "";
533 }
534 // Now remove any current text node children.
535 NodeList children = argument_element.getChildNodes();
536 for(int i = 0; i < children.getLength(); i++) {
537 argument_element.removeChild(children.item(i));
538 }
539 // Add a new text node child with the new value
540 argument_element.appendChild(document.createTextNode(value));
541 }
542 }
543 catch (Exception error) {
544 }
545 }
546
547 private void updateUI() {
548 // Buttons
549 UIManager.put("Button.select", new ColorUIResource(getColor("coloring.button_selected_background", false)));
550 UIManager.put("Button.background", new ColorUIResource(getColor("coloring.button_background", false)));
551 UIManager.put("Button.foreground", new ColorUIResource(getColor("coloring.button_foreground", false)));
552 UIManager.put("ToggleButton.background", new ColorUIResource(getColor("coloring.button_background", false)));
553 UIManager.put("ToggleButton.foreground", new ColorUIResource(getColor("coloring.button_foreground", false)));
554 UIManager.put("ToggleButton.select", new ColorUIResource(getColor("coloring.button_selected_background", false)));
555
556 // All the things with a lovely Collection green background
557 UIManager.put("OptionPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
558 UIManager.put("Panel.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
559 UIManager.put("Label.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
560 UIManager.put("TabbedPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
561 UIManager.put("SplitPane.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
562 UIManager.put("CheckBox.background", new ColorUIResource(getColor("coloring.collection_heading_background", false)));
563
564 // Editable coloring
565 UIManager.put("ComboBox.background", new ColorUIResource(getColor("coloring.button_background", false))); // Indicate clickable
566 UIManager.put("Tree.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
567 UIManager.put("Tree.textBackground", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
568 UIManager.put("ProgressBar.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
569 UIManager.put("TextArea.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
570 UIManager.put("TextField.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
571 UIManager.put("Table.background", new ColorUIResource(getColor("coloring.collection_tree_background", false)));
572
573 // Selection color
574 UIManager.put("TabbedPane.selected", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
575 UIManager.put("Tree.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
576 UIManager.put("ComboBox.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
577 UIManager.put("ProgressBar.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
578 UIManager.put("TextArea.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
579 UIManager.put("TextField.selectionBackground", new ColorUIResource(getColor("coloring.collection_selection_background", false)));
580
581 // Scroll bar stuff
582 UIManager.put("ScrollBar.background", new ColorUIResource(getColor("coloring.scrollbar_background", false)));
583 UIManager.put("ScrollBar.thumb", new ColorUIResource(getColor("coloring.scrollbar_foreground", false)));
584 if(Gatherer.g_man != null) {
585 JPanel pane = (JPanel) Gatherer.g_man.getContentPane();
586 pane.updateUI();
587 // Also update all of the tabs according to workflow.
588 Gatherer.g_man.workflowUpdate("Browser", get("workflow.browse", false));
589 Gatherer.g_man.workflowUpdate("Mirroring", get("workflow.mirror", false));
590 Gatherer.g_man.workflowUpdate("Collection", get("workflow.gather", false));
591 Gatherer.g_man.workflowUpdate("MetaEdit", get("workflow.enrich", false));
592 Gatherer.g_man.workflowUpdate("Build", get("workflow.design", false));
593 Gatherer.g_man.workflowUpdate("Export", get("workflow.export", false));
594 Gatherer.g_man.workflowUpdate("Create", get("workflow.create", false));
595 Gatherer.g_man.workflowUpdate("Preview", get("workflow.preview", false));
596 }
597 }
598}
Note: See TracBrowser for help on using the repository browser.