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