1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 package com.sun.star.wizards.web;
28 
29 //import com.sun.star.awt.ItemEvent;
30 //import com.sun.star.awt.XItemListener;
31 import java.io.FileNotFoundException;
32 import java.util.Comparator;
33 import java.util.List;
34 import java.util.Vector;
35 
36 import com.sun.star.awt.VclWindowPeerAttribute;
37 import com.sun.star.awt.XControl;
38 import com.sun.star.awt.XItemListener;
39 import com.sun.star.awt.XWindow;
40 import com.sun.star.awt.XWindowPeer;
41 import com.sun.star.frame.XDesktop;
42 import com.sun.star.frame.XFrame;
43 import com.sun.star.frame.XModel;
44 import com.sun.star.lang.EventObject;
45 import com.sun.star.lang.XMultiServiceFactory;
46 import com.sun.star.uno.UnoRuntime;
47 import com.sun.star.wizards.common.ConfigSet;
48 import com.sun.star.wizards.common.Configuration;
49 import com.sun.star.wizards.common.Desktop;
50 import com.sun.star.wizards.common.FileAccess;
51 import com.sun.star.wizards.common.Helper;
52 import com.sun.star.wizards.common.JavaTools;
53 import com.sun.star.wizards.common.PropertyNames;
54 import com.sun.star.wizards.common.SystemDialog;
55 import com.sun.star.wizards.document.OfficeDocument;
56 import com.sun.star.wizards.ui.DocumentPreview;
57 import com.sun.star.wizards.ui.event.DataAware;
58 import com.sun.star.wizards.ui.event.ListModelBinder;
59 import com.sun.star.wizards.ui.event.RadioDataAware;
60 import com.sun.star.wizards.ui.event.SimpleDataAware;
61 import com.sun.star.wizards.ui.event.Task;
62 import com.sun.star.wizards.ui.event.UnoDataAware;
63 import com.sun.star.wizards.web.data.CGContent;
64 import com.sun.star.wizards.web.data.CGDocument;
65 import com.sun.star.wizards.web.data.CGIconSet;
66 import com.sun.star.wizards.web.data.CGPublish;
67 import com.sun.star.wizards.web.data.CGSession;
68 import com.sun.star.wizards.web.data.CGSessionName;
69 import com.sun.star.wizards.web.data.CGSettings;
70 import com.sun.star.wizards.web.data.CGStyle;
71 
72 /**
73  * Web Wizard Dialog implementation : Startup.
74  * This class contains the startup implementation and session mounting methods.<p/>
75  * <h2> Data Aware Concept </h2>
76  * <p> I use DataAware objects, which synchronize
77  * UI and Data. A DataAware object a kind of interface
78  * between a Value and a UI element.
79  * </P>
80  * <p>
81  * A Value is either a JavaBean property with
82  * a Getter and a Setter or a public class Memeber.
83  * </P>
84  * When the UI Control changes, the Value changes correspondingly.
85  * This depends on settings a Listener which calls the updateData()
86  * method od the DataAware object.
87  * When the Value changes, the UI Control changes respopndingly.
88  * This also depends on settings a Listener which calls the updateUI()
89  * method of the DataAware object.
90  * </P>
91  * <P>
92  * here I use only UI Listeners, and keep calling
93  * the updateUI() method whenever I change the Value.
94  * </P>
95  * To contain the Data, I use the Configuration Data Objects
96  * which read themselfs out of the Configuration. they are all located under
97  * the data package.
98  * <p/>
99  * Different groups of DataAware objects are grouped into vectors.
100  * Each group (all elements of a vector) uses the same DataObject,
101  * so when I change the underlying dataObject, I change the whole vector's DataObject,
102  * thus actualizing UI.<br/>
103  * This is what happends when a session loads: I Load the session into
104  * a tree of DataObjects, and change the DataAware's DataObject. <br/>
105  * One could also look at this as a kind of "View-Model" relationship.
106  * The controls are the View, The DataObjects are the Model, containing the
107  * Data rad directly from the configuration, and the DataAware objects
108  * are the controller inbetween.
109  *
110  * @author rpiterman
111  *
112  */
113 public abstract class WWD_Startup extends WWD_General
114 {
115 
116     SimpleDataAware sda = null;
117     /**
118      * This is currently not used.
119      * It should have been a Listener which invoces
120      * an Update to the Preview-Document, only
121      * We did not implement the live-preview document,
122      * so this became obsolete.
123      */
124     protected DataAware.Listener refresh;
125     /**
126      * Is called whenever a field is changed which
127      * could affect the "create" button enable state,
128      * like publishing-checkboxes, save-session check- and textbox.
129      */
130     protected DataAware.Listener checkPublish = new CheckPublish();
131     /**
132      * The Vector containing DataAware objects
133      * which relay on the selected document
134      * as DataObject (or Model).
135      */
136     protected List docAware = new Vector();
137     /**
138      * The Vector containing DataAware objects
139      * which relay on the session's generalInfo
140      * Object (CGSession.cp_GeneralInfo) as
141      * DataObject (or model).
142      */
143     protected List genAware = new Vector();
144     /**
145      * The vector containing DataAware objectscm25npd ..
146      * which relay on the session's Design Object
147      * (CGSession.cp_Design) as DataObject
148      * (or model).
149      *
150      */
151     protected List designAware = new Vector();
152     /**
153      * A Vector containig the DataAware objects
154      * which relay on Publishing Objects.
155      * Differently from other Vectors, each
156      * DataAware object in this Vector relays
157      * on a <b>different</b> CGPublish object,
158      * So they are handled with more care.
159      */
160     protected List pubAware = new Vector(3);
161     /**
162      * The DataAware object which handles
163      * the documents-list events.
164      * This will call the set/getDocument() method
165      * implemented in WWD_General.
166      */
167     protected UnoDataAware docListDA;
168     /**
169      * DataAware object which synchronizes the session
170      * name in step 7 with the CGSession.cp_Name
171      */
172     protected UnoDataAware sessionNameDA;
173     /**
174      * Binds a ListModel to the UnoControlListBox.
175      */
176     protected ListModelBinder docsBinder;
177     /**
178      *  a DocumentPreview object is
179      * the UI OO Document preview
180      * in the Dialog
181      */
182     protected DocumentPreview dpStylePreview;
183     /**
184      * An Object that implements the
185      * File-copy and refresh of the
186      * style preview
187      */
188     protected StylePreview stylePreview;
189     /**
190      * the currently selected document.
191      */
192     protected short[] selectedDoc = new short[0];
193     /**
194      * If ftp proxies are on, ftp is disabled, and
195      * the true/false of the FTP publisher is set to false.
196      * In order to save it correctly when saving the session
197      * at the end, the original loaded value is saved to this variable;
198      */
199     boolean __ftp;
200     /**
201      * When the wizard starts, a new document opens.
202      * The backgroundDoc memeber contains the TextDocument
203      * instance used for that purpose.
204      */
205     protected XFrame myFrame;
206 
207 
208     /* ******************************************
209      *  ****************************************
210      *             General Methods
211      *  ****************************************
212      * ******************************************  */
213 
214     /*
215      * GENERAL Initialization  methods
216      */
217     /**
218      * He - my constructor !
219      * I call/do here in this order: <br/>
220      * Check if ftp http proxy is set, and warn user he can not use
221      * ftp if  it is.<br/>
222      * draw NaviBar and steps 1 to 7, incl. Step X,
223      * which is the Layouts ImageList on step 3.<br/>
224      * load the settings from the configuration. <br/>
225      * set the default save session name to the first
226      * available one (sessionX or something like that). <br/>
227      * set the Layouts ImageList ListModel, and call
228      * its "create()" method. <br/>
229      * check the content (documents) specified in the default session.<br/>
230      * fill the list boxes (saved sessions, styles, combobox save session). <br/>
231      * make data aware. <br/>
232      * updateUI (refreshes the display to crrespond to the data in
233      * the default session.)<br/>
234      * fill the documents listbox. <br/>
235      * if proxies are set, disable the ftp controls in step 7.
236      */
237     public WWD_Startup(XMultiServiceFactory xmsf) throws Exception
238     {
239         super(xmsf);
240 
241         proxies = getOOProxies();
242 
243         String soTemplateDir = FileAccess.getOfficePath(xmsf, "Template", "share", "/wizard");
244 
245         String exclamationURL = FileAccess.connectURLs(soTemplateDir, "../wizard/bitmap/caution_16.png");
246         this.drawNaviBar();
247         this.buildStep1();
248         this.buildStep2();
249         this.buildStep3();
250 
251         this.buildStep4();
252         this.buildStep5();
253         this.buildStep6();
254         this.buildStep7(proxies, exclamationURL);
255         buildStepX();
256 
257         this.xMSF = xmsf;
258         XDesktop xDesktop = Desktop.getDesktop(xMSF);
259         myFrame = OfficeDocument.createNewFrame(xMSF, this);
260         Object doc = OfficeDocument.createNewDocument(myFrame, "swriter", false, true);
261 
262         loadSettings(doc);
263         setSaveSessionName(settings.cp_DefaultSession);
264 
265         ilLayouts.setListModel(settings.cp_Layouts);
266         ilLayouts.create(this);
267 
268         checkContent(settings.cp_DefaultSession.cp_Content, new Task(PropertyNames.EMPTY_STRING, PropertyNames.EMPTY_STRING, 99999), this.xControl);
269 
270         //saved sessions, styles, combobox save session.
271         // also set the chosen saved session...
272         fillLists();
273         makeDataAware();
274         // change the display to correspond to the current session.
275         updateUI();
276         // fill the documents listbox.
277         mount(settings.cp_DefaultSession.cp_Content);
278 
279 
280         if (proxies)
281         {
282             setEnabled(btnFTP, false);
283             setEnabled(chkFTP, false);
284         }
285     }
286 
287     /**
288      * return true if http proxies or other proxies
289      * which do not enable ftp to function correctly are set.
290      * @return true if (http) proxies are on.
291      * @throws Exception
292      */
293     private boolean getOOProxies() throws Exception
294     {
295         Object node = Configuration.getConfigurationRoot(xMSF, "org.openoffice.Inet/Settings", false);
296         int i = Configuration.getInt("ooInetProxyType", node);
297         //System.out.println("WWD:Startup:getOOProxies:" + i);
298         switch (i)
299         {
300             case 0: //no proxies
301                 return false;
302             case 2: //http proxies
303                 return true;
304             default:
305                 return true;
306         }
307     }
308 
309     /**
310      * calculates the first available session name,
311      * and sets the current session name to it.
312      * The combobox text in step 7 will be updated
313      * automatically when updateUI() is called.
314      */
315     protected void setSaveSessionName(CGSession session)
316     {
317         int max = 0;
318         int len = resources.resSessionName.length();
319         // traverse between the sessions and find the one that
320         // has the biggest number.
321         for (int i = 0; i < settings.cp_SavedSessions.getSize(); i++)
322         {
323             String sessionName = ((CGSessionName) settings.cp_SavedSessions.getElementAt(i)).cp_Name;
324             if (sessionName.startsWith(resources.resSessionName))
325             {
326                 max = max(max, Integer.valueOf(sessionName.substring(len)).intValue());
327             }
328         }
329 
330         session.cp_Name = resources.resSessionName + ++max;
331 
332     }
333 
334     private int max(int i1, int i2)
335     {
336         if (i1 > i2)
337         {
338             return i1;
339         }
340         else
341         {
342             return i2;
343         }
344     }
345 
346     /**
347      * fills the road map, and sets the necessary properties,
348      * like MaxStep, Complete, Interactive-
349      * Disables the finbihButton.
350      */
351     private void addRoadMapItems()
352     {
353         insertRoadMapItems(new String[]
354                 {
355                     resources.resStep1, resources.resStep2, resources.resStep3, resources.resStep4, resources.resStep5, resources.resStep6, resources.resStep7
356                 }, new int[]
357                 {
358                     1, 2, 3, 4, 5, 6, 7
359                 }, new boolean[]
360                 {
361                     true, true, false, false, false, false, false
362                 });
363 
364         setRoadmapInteractive(true);
365         setRoadmapComplete(true);
366         setCurrentRoadmapItemID((short) 1);
367         setMaxStep(7);
368         enableFinishButton(false);
369 
370     }
371 
372     /**
373      * This method goes through all
374      * the DataAware vectors and objects and
375      * calls their updateUI() method.
376      * In response, the UI is synchronized to
377      * the state of the corresponding data objects.
378      *
379      */
380     private void updateUI()
381     {
382         DataAware.updateUI(designAware);
383         DataAware.updateUI(genAware);
384         DataAware.updateUI(pubAware);
385         sessionNameDA.updateUI();
386         checkPublish();
387     }
388 
389     private XFrame getFrame(Object model)
390     {
391         XModel xmodel = UnoRuntime.queryInterface(XModel.class, model);
392         return xmodel.getCurrentController().getFrame();
393     }
394 
395     /**
396      * create the peer, add roadmap,
397      * add roadmap items, add style-preview,
398      * disable the steps 3 to 7 if no documents are
399      * on the list, and... show the dialog!
400      */
401     public void show()
402     {
403         try
404         {
405 
406 
407             /* myFrame.initialize(docWindow);
408              * */
409 
410             //desktopFrame = Desktop.findAFrame(xMSF, myFrame, desktopFrame);
411 
412             //XWindow xContainerWindow = myFrame.getContainerWindow();
413 
414             XWindow xContainerWindow = myFrame.getComponentWindow();
415             XWindowPeer xWindowPeer = UnoRuntime.queryInterface(XWindowPeer.class, xContainerWindow);
416 
417             createWindowPeer(xWindowPeer);
418 
419             addRoadmap();
420             addRoadMapItems();
421             addStylePreview();
422             checkSteps();
423 
424             executeDialog(myFrame);
425             removeTerminateListener();
426 
427         }
428         catch (java.lang.Exception jexception)
429         {
430             jexception.printStackTrace(System.out);
431         }
432     }
433 
434     /**
435      * initializes the style preview.
436      */
437     private void addStylePreview()
438     {
439         try
440         {
441             dpStylePreview = new DocumentPreview(xMSF, imgPreview);
442             stylePreview = new StylePreview(xMSF, settings.workPath);
443             stylePreview.refresh(settings.cp_DefaultSession.getStyle(), settings.cp_DefaultSession.cp_Design.cp_BackgroundImage);
444             dpStylePreview.setDocument(stylePreview.htmlFilename, DocumentPreview.PREVIEW_MODE);
445 
446         }
447         catch (Exception ex)
448         {
449             ex.printStackTrace();
450         }
451     }
452 
453     /**
454      * Loads the web wizard settings from the registry.
455      */
456     private void loadSettings(Object document)
457     {
458         try
459         {
460             // instanciate
461             String[] settingsResources = new String[]
462             {
463                 resources.resPages,
464                 resources.resSlides,
465                 resources.resCreatedTemplate,
466                 resources.resUpdatedTemplate,
467                 resources.resSizeTemplate
468             };
469 
470             settings = new CGSettings(xMSF, settingsResources, document);
471 
472             // get configuration view
473             Object confRoot = Configuration.getConfigurationRoot(xMSF, CONFIG_PATH, false);
474             // read
475             settings.readConfiguration(confRoot, CONFIG_READ_PARAM);
476 
477             ConfigSet set = settings.cp_DefaultSession.cp_Publishing;
478 
479             // now if path variables are used in publisher pathes, they
480             // are getting replaced here...
481             for (int i = 0; i < set.getSize(); i++)
482             {
483                 CGPublish p = (CGPublish) set.getElementAt(i);
484                 p.cp_URL = substitute(p.cp_URL);
485             }
486 
487             // initialize the settings.
488             settings.configure(xMSF);
489 
490             // set resource needed for web page.
491 
492             // sort the styles alphabetically
493             settings.cp_Styles.sort(new StylesComparator());
494 
495             prepareSessionLists();
496 
497             if (proxies)
498             {
499                 __ftp = getPublisher(FTP_PUBLISHER).cp_Publish;
500                 getPublisher(FTP_PUBLISHER).cp_Publish = false;
501 
502             }
503 
504         }
505         catch (Exception ex)
506         {
507             ex.printStackTrace();
508         }
509     }
510 
511     protected void prepareSessionLists()
512     {
513         // now copy the sessions list...
514         Object[] sessions = settings.cp_SavedSessions.items();
515         settings.savedSessions.clear();
516         for (int i = 0; i < sessions.length; i++)
517         {
518             settings.savedSessions.add(i, sessions[i]);        // add an empty session to the saved session list which apears in step 1
519         }
520         CGSessionName sn = new CGSessionName();
521         sn.cp_Name = resources.resSessionNameNone;
522         settings.cp_SavedSessions.add(0, sn);
523     }
524 
525     /**
526      * fills the saved session list, the styles list,
527      * and save session combo box.
528      * Also set the selected "load" session to the last session
529      * which was saved.
530      */
531     private void fillLists()
532     {
533         // fill the saved session list.
534         ListModelBinder.fillList(lstLoadSettings, settings.cp_SavedSessions.items(), null);
535 
536         // set the selected session to load. (step 1)
537         selectSession();
538 
539         // fill the styles list.
540         ListModelBinder.fillList(lstStyles, settings.cp_Styles.items(), null);
541 
542         // fill the save session combobox (step 7)
543         ListModelBinder.fillComboBox(cbSaveSettings, settings.savedSessions.items(), null);
544 
545 
546     }
547 
548     protected void selectSession()
549     {
550         int selectedSession = 0;
551         if (settings.cp_LastSavedSession != null && !settings.cp_LastSavedSession.equals(PropertyNames.EMPTY_STRING))
552         {
553 
554             Object ses = settings.cp_SavedSessions.getElement(settings.cp_LastSavedSession);
555             if (ses != null)
556             {
557                 selectedSession = settings.cp_SavedSessions.getIndexOf(ses);
558             }
559         }
560         Helper.setUnoPropertyValue(getModel(lstLoadSettings), PropertyNames.SELECTED_ITEMS, new short[]
561                 {
562                     (short) selectedSession
563                 });
564 
565     }
566 
567     public class SimpleDataawareUpdater implements XItemListener
568     {
569         /* (non-Javadoc)
570          * @see com.sun.star.lang.XEventListener#disposing(com.sun.star.lang.EventObject)
571          */
572 
573         public void disposing(EventObject arg0)
574         {
575             // TODO Auto-generated method stub
576         }
577 
578         public void itemStateChanged(com.sun.star.awt.ItemEvent itemEvent)
579         {
580             sda.updateData();
581         //TODO xf uncomment
582         //refresh.eventPerformed(ie);
583         }
584     }
585 
586     /**
587      * attaches to each ui-data-control (like checkbox, groupbox or
588      * textbox, no buttons though), a DataObject's JavaBean Property,
589      * or class member.
590      */
591     private void makeDataAware()
592     {
593         //page 1
594         new ListModelBinder(lstLoadSettings, settings.cp_SavedSessions);
595 
596         //page 2 : document properties
597 
598         docListDA = UnoDataAware.attachListBox(this, "SelectedDoc", lstDocuments, null, false);
599         docListDA.disableControls(new Object[]
600                 {
601                     /*btnDocDown, btnDocUp, */
602                     lnDocsInfo, btnRemoveDoc, lblDocTitle, txtDocTitle, lblDocInfo, txtDocInfo, lblDocAuthor, txtDocAuthor, lblDocExportFormat, lstDocTargetType
603                 });
604         docListDA.updateUI();
605 
606         CGDocument doc = new CGDocument(); //dummy
607 
608         docsBinder = new ListModelBinder(lstDocuments, settings.cp_DefaultSession.cp_Content.cp_Documents);
609 
610         docAware.add(UnoDataAware.attachEditControl(doc, "cp_Title", txtDocTitle, refresh, true));
611         docAware.add(UnoDataAware.attachEditControl(doc, "cp_Description", txtDocInfo, refresh, true));
612         docAware.add(UnoDataAware.attachEditControl(doc, "cp_Author", txtDocAuthor, refresh, true));
613         docAware.add(UnoDataAware.attachListBox(doc, "Exporter", lstDocTargetType, refresh, false));
614 
615         //page 3 : Layout
616         Object design = settings.cp_DefaultSession.cp_Design;
617         sda = new SimpleDataAware(design, new DataAware.PropertyValue("Layout", design), ilLayouts, new DataAware.PropertyValue("Selected", ilLayouts));
618         ilLayouts.addItemListener(new SimpleDataawareUpdater());
619         designAware.add(sda);
620 
621         //page 4 : layout 2
622         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayDescription", chbDocDesc, refresh, true));
623         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayAuthor", chbDocAuthor, refresh, true));
624         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayCreateDate", chkDocCreated, refresh, true));
625         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayUpdateDate", chkDocChanged, refresh, true));
626         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayFilename", chkDocFilename, refresh, true));
627         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayFileFormat", chkDocFormat, refresh, true));
628         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayFormatIcon", chkDocFormatIcon, refresh, true));
629         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplayPages", chkDocPages, refresh, true));
630         designAware.add(UnoDataAware.attachCheckBox(design, "cp_DisplaySize", chkDocSize, refresh, true));
631         designAware.add(RadioDataAware.attachRadioButtons(settings.cp_DefaultSession.cp_Design, "cp_OptimizeDisplaySize", new Object[]
632                 {
633                     optOptimize640x480, optOptimize800x600, optOptimize1024x768
634                 }, refresh, true));
635 
636 
637         //page 5 : Style
638         /*
639          * note : on style change, i do not call here refresh ,but rather on
640          * a special method which will perform some display, background and Iconsets changes.
641          */
642         designAware.add(UnoDataAware.attachListBox(settings.cp_DefaultSession.cp_Design, "Style", lstStyles, null, false));
643 
644         //page 6 : site general props
645         genAware.add(UnoDataAware.attachEditControl(settings.cp_DefaultSession.cp_GeneralInfo, "cp_Title", txtSiteTitle, refresh, true));
646         genAware.add(UnoDataAware.attachEditControl(settings.cp_DefaultSession.cp_GeneralInfo, "cp_Description", txtSiteDesc, refresh, true));
647 
648         genAware.add(UnoDataAware.attachDateControl(settings.cp_DefaultSession.cp_GeneralInfo, "CreationDate", dateSiteCreated, refresh, false));
649         genAware.add(UnoDataAware.attachDateControl(settings.cp_DefaultSession.cp_GeneralInfo, "UpdateDate", dateSiteUpdate, refresh, false));
650         genAware.add(UnoDataAware.attachEditControl(settings.cp_DefaultSession.cp_GeneralInfo, "cp_Email", txtEmail, refresh, true));
651         genAware.add(UnoDataAware.attachEditControl(settings.cp_DefaultSession.cp_GeneralInfo, "cp_Copyright", txtCopyright, refresh, true));
652 
653         //page 7 : publishing
654 
655         pubAware(LOCAL_PUBLISHER, chkLocalDir, txtLocalDir, false);
656         pubAware(FTP_PUBLISHER, chkFTP, lblFTP, true);
657         pubAware(ZIP_PUBLISHER, chkZip, txtZip, false);
658 
659         sessionNameDA = UnoDataAware.attachEditControl(settings.cp_DefaultSession, "cp_Name", cbSaveSettings, null, true);
660 
661     //cleanup when exiting wizard.
662     //guiEventListener.add("WebWizardDialog",EventNames.EVENT_WINDOW_HIDDEN, "cleanup", this);
663     //xWindow.addWindowListener((XWindowListener)guiEventListener);
664     }
665 
666     /**
667      * A help method to attach a Checkbox and a TextBox to
668      * a CGPublish object properties/class members,
669      * @param publish
670      * @param checkbox
671      * @param textbox
672      */
673     private void pubAware(String publish, Object checkbox, Object textbox, boolean isLabel)
674     {
675         Object p = settings.cp_DefaultSession.cp_Publishing.getElement(publish);
676         UnoDataAware uda = UnoDataAware.attachCheckBox(p, "cp_Publish", checkbox, checkPublish, true);
677         uda.setInverse(true);
678 
679         uda.disableControls(new Object[]
680                 {
681                     textbox
682                 });
683         pubAware.add(uda);
684         pubAware.add(
685                 isLabel ? UnoDataAware.attachLabel(p, PropertyNames.URL, textbox, checkPublish, false)
686                 : UnoDataAware.attachEditControl(p, PropertyNames.URL, textbox, checkPublish, false));
687 
688     }
689 
690     /*
691      * Session load methods
692      * (are used both on the start of the wizard and
693      * when the user loads a session)
694      */
695     /**
696      * Is called when a new session/settings is
697      * loaded. <br/>
698      * Checks the documents (validate), fills the
699      * documents listbox, and changes the
700      * DataAware data objects to the
701      * new session's objects.<br/>
702      * Task advances 4 times in the mount method,
703      * and ??? times for each document in the session.
704      *
705      */
706     protected void mount(CGSession session, Task task, boolean refreshStyle, XControl xC)
707     {
708         /* This checks the documents. If the user
709          * chooses to cancel, the session is not loaded.
710          */
711         checkContent(session.cp_Content, task, xC);
712 
713         settings.cp_DefaultSession = session;
714 
715         mount(session.cp_Content);
716 
717         task.advance(true);
718 
719         mount(session.cp_Design, designAware);
720         mount(session.cp_GeneralInfo, genAware);
721 
722         task.advance(true);
723 
724         mount(session.cp_Publishing.getElement(LOCAL_PUBLISHER), 0);
725         mount(session.cp_Publishing.getElement(FTP_PUBLISHER), 1);
726         mount(session.cp_Publishing.getElement(ZIP_PUBLISHER), 2);
727 
728         task.advance(true);
729 
730         sessionNameDA.setDataObject(session, true);
731         Helper.setUnoPropertyValue(getModel(chkSaveSettings), PropertyNames.PROPERTY_STATE, new Short((short) 1));
732         docListDA.updateUI();
733 
734         task.advance(true);
735 
736         if (refreshStyle)
737         {
738             refreshStylePreview();
739             updateIconsetText();
740         }
741 
742     //updateUI();
743     }
744 
745     /**
746      * used to mount the publishing objects. This is somehow cryptic -
747      * there are 6 DataAware objects, 2 for each Publishing Object (CGPublish).
748      * All 6 reside on one Vector (pubAware).
749      * Since, otherwise than other DataAware objects, different
750      * Objects on the same Vector need different DataObjectBinding,
751      * I use this method...
752      * @param data the CGPublish object
753      * @param i the number of the object (0 = local, 1 = ftp, 2 = zip)
754      */
755     private void mount(Object data, int i)
756     {
757         ((DataAware) pubAware.get(i * 2)).setDataObject(data, true);
758         ((DataAware) pubAware.get(i * 2 + 1)).setDataObject(data, true);
759     }
760 
761     /**
762      * Fills the documents listbox.
763      * @param root the CGContent object
764      * that contains the documents (a ListModel)
765      */
766     private void mount(CGContent root)
767     {
768         ListModelBinder.fillList(lstDocuments, root.cp_Documents.items(), null);
769         docsBinder.setListModel(root.cp_Documents);
770         disableDocUpDown();
771 
772     }
773 
774     /**
775      * changes the DataAwares Objects' (in
776      * the gioen list) DataObject to the
777      * @param data
778      * @param list
779      */
780     protected void mount(Object data, List list)
781     {
782         for (int i = 0; i < list.size(); i++)
783         {
784             ((DataAware) list.get(i)).setDataObject(data, true);
785         }
786     }
787 
788     /**
789      * Checks if the document specified by the given CGDocument
790      * object (cp_URL) exists. Calls also the validate(...) method
791      * of this document.
792      * If the document does not exist, it asks the user whether
793      * to specify a new URL, or forget about this document.
794      * @param doc the document to check.
795      * @param task while loading a session, a status is
796      * displayed, using the Task object to monitor progress.
797      * @return true if the document is ok (a file exists in the given url).
798      */
799     protected boolean checkDocument(CGDocument doc, Task task, XControl xC)
800     {
801         try
802         {
803             doc.validate(xMSF, task);
804             return true;
805         }
806         catch (FileNotFoundException ex)
807         {
808 
809             int relocate = SystemDialog.showMessageBox(xMSF, xC.getPeer(), "WarningBox", VclWindowPeerAttribute.YES_NO + VclWindowPeerAttribute.DEF_NO, getFileAccess().getPath(doc.cp_URL, PropertyNames.EMPTY_STRING) + "\n\n" + resources.resSpecifyNewFileLocation);
810 
811             if (relocate == 2)
812             {
813                 String[] file = getDocAddDialog().callOpenDialog(false, FileAccess.getParentDir(doc.cp_URL));
814                 if (file == null)
815                 {
816                     return false;
817                 }
818                 else
819                 {
820                     doc.cp_URL = file[0];
821                     return checkDocument(doc, task, xC);
822                 }
823             }
824             else
825             {
826                 return false;
827             }
828         }
829         catch (IllegalArgumentException iaex)
830         {
831             //file is a directory
832             AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(),
833                     JavaTools.replaceSubString(resources.resErrIsDirectory,
834                     getFileAccess().getPath(doc.cp_URL, PropertyNames.EMPTY_STRING),
835                     "%FILENAME"),
836                     ErrorHandler.ERROR_PROCESS_FATAL);
837             return false;
838         }
839         catch (Exception exp)
840         {
841             //something went wrong.
842             exp.printStackTrace();
843             AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(),
844                     JavaTools.replaceSubString(resources.resErrDocValidate,
845                     getFileAccess().getPath(doc.cp_URL, PropertyNames.EMPTY_STRING),
846                     "%FILENAME"), ErrorHandler.ERROR_PROCESS_FATAL);
847             return false;
848         }
849 
850     }
851 
852     /**
853      * Checks the documents contained in this content.
854      * @param content
855      * @param task
856      */
857     private void checkContent(CGContent content, Task task, XControl xC)
858     {
859         for (int i = 0; i < content.cp_Documents.getSize(); i++)
860         {
861             if (!checkDocument((CGDocument) content.cp_Documents.getElementAt(i), task, xC))
862             // I use here 'i--' since, when the document is removed
863             // an index change accures
864             {
865                 content.cp_Documents.remove(i--);
866             /*for (Iterator i = content.cp_Contents.childrenMap.values().iterator(); i.hasNext();)
867             checkContent((CGContent)i.next(),task);*/
868             }
869         }
870     }
871 
872     /**
873      * A Listener which is called whenever
874      * a Publish checkbox/textbox state changes, and
875      * changes the "create" button enable state accordingly.
876      * @author rpiterman
877      */
878     private class CheckPublish implements DataAware.Listener
879     {
880 
881         public void eventPerformed(Object event)
882         {
883             checkPublish();
884         }
885     }
886 
887     /**
888      * Disables/enables the docUpDown buttons (step 2)
889      * according to the currently selected document
890      * (no doc selected - both disbaled, last doc selected,
891      * down disabled and so on...)
892      *
893      */
894     protected void disableDocUpDown()
895     {
896         try
897         {
898             setEnabled(btnDocUp, selectedDoc.length == 0 ? Boolean.FALSE : (selectedDoc[0] == 0 ? Boolean.FALSE : Boolean.TRUE));
899             setEnabled(btnDocDown, selectedDoc.length == 0 ? Boolean.FALSE : (selectedDoc[0] + 1 < settings.cp_DefaultSession.cp_Content.cp_Documents.getSize() ? Boolean.TRUE : Boolean.FALSE));
900         }
901         catch (Exception e)
902         {
903             e.printStackTrace();
904         }
905     }
906 
907     void updateBackgroundText()
908     {
909         String bg = settings.cp_DefaultSession.cp_Design.cp_BackgroundImage;
910         if (bg == null || bg.equals(PropertyNames.EMPTY_STRING))
911         {
912             bg = resources.resBackgroundNone;
913         }
914         else
915         {
916             bg = FileAccess.getPathFilename(getFileAccess().getPath(bg, null));
917         }
918         Helper.setUnoPropertyValue(getModel(txtBackground), PropertyNames.PROPERTY_LABEL, bg);
919     }
920 
921     void updateIconsetText()
922     {
923         String iconset = settings.cp_DefaultSession.cp_Design.cp_IconSet;
924         String iconsetName;
925         if (iconset == null || iconset.equals(PropertyNames.EMPTY_STRING))
926         {
927             iconsetName = resources.resIconsetNone;
928         }
929         else
930         {
931             CGIconSet is = (CGIconSet) settings.cp_IconSets.getElement(iconset);
932             if (is == null)
933             {
934                 iconsetName = resources.resIconsetNone;
935             }
936             else
937             {
938                 iconsetName = is.cp_Name;
939             }
940         }
941 
942         Helper.setUnoPropertyValue(getModel(txtIconset), PropertyNames.PROPERTY_LABEL, iconsetName);
943     }
944 
945     /**
946      * refreshes the style preview.
947      * I also call here "updateBackgroundtext", because always
948      * when the background is changed, this method
949      * has to be called, so I am walking on the safe side here...
950      */
951     public void refreshStylePreview()
952     {
953         try
954         {
955             updateBackgroundText();
956             stylePreview.refresh(settings.cp_DefaultSession.getStyle(), settings.cp_DefaultSession.cp_Design.cp_BackgroundImage);
957             dpStylePreview.reload(xMSF);
958         }
959         catch (Exception ex)
960         {
961             ex.printStackTrace();
962         }
963     }
964 
965     private class StylesComparator implements Comparator
966     {
967 
968         /* (non-Javadoc)
969          * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
970          */
971         public int compare(Object o1, Object o2)
972         {
973             // TODO Auto-generated method stub
974             if (o1 instanceof CGStyle && o2 instanceof CGStyle)
975             {
976                 return ((CGStyle) o1).cp_Name.compareTo(
977                         ((CGStyle) o2).cp_Name);
978             }
979             else
980             {
981                 throw new IllegalArgumentException("Cannot compare objects which are not CGStyle.");
982             }
983         }
984     }
985 }
986