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 javax.swing.ListModel;
30 
31 import com.sun.star.awt.KeyEvent;
32 import com.sun.star.awt.XControl;
33 import com.sun.star.awt.XKeyListener;
34 import com.sun.star.awt.XWindow;
35 import com.sun.star.container.NoSuchElementException;
36 import com.sun.star.lang.EventObject;
37 import com.sun.star.lang.XMultiServiceFactory;
38 import com.sun.star.uno.UnoRuntime;
39 import com.sun.star.util.XCloseable;
40 import com.sun.star.wizards.common.Configuration;
41 import com.sun.star.wizards.common.FileAccess;
42 import com.sun.star.wizards.common.Helper;
43 import com.sun.star.wizards.common.JavaTools;
44 import com.sun.star.wizards.common.SystemDialog;
45 import com.sun.star.wizards.common.PropertyNames;
46 import com.sun.star.wizards.ui.UnoDialog;
47 import com.sun.star.wizards.ui.event.DataAware;
48 import com.sun.star.wizards.ui.event.ListModelBinder;
49 import com.sun.star.wizards.ui.event.Task;
50 import com.sun.star.wizards.web.data.CGDocument;
51 import com.sun.star.wizards.web.data.CGPublish;
52 import com.sun.star.wizards.web.data.CGSession;
53 import com.sun.star.wizards.web.data.CGSessionName;
54 
55 /**
56  * This class implements the ui-events of the
57  * web wizard.
58  * it is therfore sorted to steps.
59  * not much application-logic here - just plain
60  * methods which react to events.
61  * The only exception are the finish methods with the save
62  * session methods.
63  */
64 public abstract class WWD_Events extends WWD_Startup
65 {
66 
67     private static final short[] EMPTY_SHORT_ARRAY = new short[0];
68     /**
69      * Tracks the current loaded session.
70      * If PropertyNames.EMPTY_STRING - it means the current session is the default one (empty)
71      * If a session is loaded, this will be the name of the loaded session.
72      */
73     protected String currentSession = PropertyNames.EMPTY_STRING;
74 
75     /**
76      * He - my constructor !
77      * I add a window listener, which, when
78      * the window closes, deltes the temp directory.
79      */
80     public WWD_Events(XMultiServiceFactory xmsf) throws Exception
81     {
82         super(xmsf);
83         Create c = new Create();
84         XWindow xWindow = UnoRuntime.queryInterface(XWindow.class, chkFTP);
85         xWindow.addKeyListener(c);
86         xWindow = UnoRuntime.queryInterface(XWindow.class, chkLocalDir);
87         xWindow.addKeyListener(c);
88         xWindow = UnoRuntime.queryInterface(XWindow.class, chkZip);
89         xWindow.addKeyListener(c);
90     }
91 
92     /* *********************************************************
93      *  *******************************************************
94      *          EVENT and UI METHODS
95      *  *******************************************************
96      * *********************************************************/
97     protected void leaveStep(int nOldStep, int nNewStep)
98     {
99         if (nOldStep == 1 && nNewStep == 2)
100         {
101             // 1. check if the selected session is the same as the current one.
102         }
103     }
104 
105     protected void enterStep(int old, int newStep)
106     {
107         if ((old == 1))
108         {
109             String sessionToLoad = PropertyNames.EMPTY_STRING;
110             short[] s = (short[]) Helper.getUnoPropertyValue(getModel(lstLoadSettings), PropertyNames.SELECTED_ITEMS);
111             if (s.length == 0 || s[0] == 0)
112             {
113                 sessionToLoad = PropertyNames.EMPTY_STRING;
114             }
115             else
116             {
117                 sessionToLoad = ((CGSessionName) settings.cp_SavedSessions.getElementAt(s[0])).cp_Name;
118             }
119             if (!sessionToLoad.equals(currentSession))
120             {
121                 loadSession(sessionToLoad);
122             }
123         }
124         if (newStep == 5)
125         {
126         }
127     }
128 
129     /* *********************************
130      *  STEP 1
131      */
132     /**
133      * Called from the Uno event dispatcher when the
134      * user selects a saved session.
135      */
136     public void sessionSelected()
137     {
138         short[] s = (short[]) Helper.getUnoPropertyValue(getModel(lstLoadSettings), PropertyNames.SELECTED_ITEMS);
139         setEnabled(btnDelSession, s.length > 0 && s[0] > 0);
140     }
141 
142     /**
143      * Ha ! the session should be loaded :-)
144      */
145     public void loadSession(final String sessionToLoad)
146     {
147         try
148         {
149             final StatusDialog sd = getStatusDialog();
150 
151             final Task task = new Task("LoadDocs", PropertyNames.EMPTY_STRING, 10);
152 
153             sd.execute(this, task, resources.resLoadingSession);
154             task.start();
155 
156             setSelectedDoc(EMPTY_SHORT_ARRAY);
157             Helper.setUnoPropertyValue(getModel(lstDocuments), PropertyNames.SELECTED_ITEMS, EMPTY_SHORT_ARRAY);
158             Helper.setUnoPropertyValue(getModel(lstDocuments), PropertyNames.STRING_ITEM_LIST, EMPTY_STRING_ARRAY);
159 
160             Object view = null;
161 
162             if (sessionToLoad.equals(PropertyNames.EMPTY_STRING))
163             {
164                 view = Configuration.getConfigurationRoot(xMSF, CONFIG_PATH + "/DefaultSession", false);
165             }
166             else
167             {
168                 view = Configuration.getConfigurationRoot(xMSF, CONFIG_PATH + "/SavedSessions", false);
169                 view = Configuration.getNode(sessionToLoad, view);
170             }
171 
172             CGSession session = new CGSession();
173             session.setRoot(settings);
174             session.readConfiguration(view, CONFIG_READ_PARAM);
175             task.setMax(session.cp_Content.cp_Documents.getSize() * 5 + 7);
176             task.advance(true);
177 
178             if (sessionToLoad.equals(PropertyNames.EMPTY_STRING))
179             {
180                 setSaveSessionName(session);
181             }
182             mount(session, task, false, sd.xControl);
183 
184             checkSteps();
185             currentSession = sessionToLoad;
186 
187             while (task.getStatus() <= task.getMax())
188             {
189                 task.advance(false);
190             }
191             task.removeTaskListener(sd);
192         }
193         catch (Exception ex)
194         {
195             unexpectedError(ex);
196         }
197 
198         try
199         {
200             refreshStylePreview();
201             updateIconsetText();
202         }
203         catch (Exception e)
204         {
205             // TODO Auto-generated catch block
206             e.printStackTrace();
207         }
208     }
209 
210     /**
211      * hmm. the user clicked the delete button.
212      */
213     public void delSession()
214     {
215         short[] selected = (short[]) Helper.getUnoPropertyValue(getModel(lstLoadSettings), PropertyNames.SELECTED_ITEMS);
216         if (selected.length == 0)
217         {
218             return;
219         }
220         if (selected[0] == 0)
221         {
222             return;
223         }
224         boolean confirm = AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), resources.resDelSessionConfirm, ErrorHandler.ERROR_QUESTION_NO);
225         if (confirm)
226         {
227             try
228             {
229                 String name = (String) settings.cp_SavedSessions.getKey(selected[0]);
230                 // first delete the session from the registry/configuration.
231 
232                 Configuration.removeNode(xMSF, CONFIG_PATH + "/SavedSessions", name);
233 
234                 // then delete the session from the java-set (settings.cp_SavedSessions)
235                 settings.cp_SavedSessions.remove(selected[0]);
236                 settings.savedSessions.remove(selected[0] - 1);
237 
238                 short[] nextSelected = new short[]
239                 {
240                     (short) 0
241                 };
242                 // We try to select the same item index again, if possible
243                 if (settings.cp_SavedSessions.getSize() > selected[0])
244                 {
245                     nextSelected[0] = selected[0];
246                 }
247                 else
248                 // this will always be available because
249                 // the user can not remove item 0.
250                 {
251                     nextSelected[0] = (short) (selected[0] - 1);                // if the <none> session will be selected, disable the remove button...
252                 }
253                 if (nextSelected[0] == 0)
254                 {
255                     Helper.setUnoPropertyValue(getModel(btnDelSession), PropertyNames.PROPERTY_ENABLED, Boolean.FALSE);                // select...
256                 }
257                 Helper.setUnoPropertyValue(getModel(lstLoadSettings), PropertyNames.SELECTED_ITEMS, nextSelected);
258 
259             //ListModelBinder.fillComboBox(cbSaveSettings, settings.savedSessions.items(), null);
260 
261 
262             }
263             catch (Exception ex)
264             {
265                 ex.printStackTrace();
266                 unexpectedError(ex);
267             }
268         }
269     }
270 
271     /* ********************************
272      * STEP 2
273      */
274     /**
275      * A method used by the UnoDataAware attached
276      * to the Documents listbox.
277      * See the concept of the DataAware objects to undestand
278      * why it is there...
279      */
280     public short[] getSelectedDoc()
281     {
282         return selectedDoc;
283     }
284     private static String[] EMPTY_STRING_ARRAY = new String[0];
285 
286     /*  public void loadSessionSelected() {
287     UIHelper.setEnabled(btnLoadSession,true);
288     UIHelper.setEnabled(btnDelSession,true);
289     }
290      */
291     /**
292      * when the user clicks another document
293      * in the listbox, this method is called,
294      * and couses the display in
295      * the textboxes title,description, author and export format
296      * to change
297      */
298     public void setSelectedDoc(short[] s)
299     {
300         CGDocument oldDoc = getDoc(selectedDoc);
301         CGDocument doc = getDoc(s);
302 
303         if (doc == null)
304         {
305             fillExportList(EMPTY_STRING_ARRAY);
306         //I try to avoid refreshing the export list if
307         //the same type of document is chosen.
308         }
309         else if (oldDoc == null || (!oldDoc.appType.equals(doc.appType)))
310         {
311             fillExportList(settings.getExporters(doc.appType));
312         }
313 
314 
315         selectedDoc = s;
316 
317         mount(doc, docAware);
318         disableDocUpDown();
319     }
320 
321     /**
322      * The user clicks the "Add" button.
323      * This will open a "FileOpen" dialog,
324      * and, if the user chooses more than one file,
325      * will open a status dialog, when validating each document.
326      */
327     public void addDocument()
328     {
329 
330         final String[] files = getDocAddDialog().callOpenDialog(true, settings.cp_DefaultSession.cp_InDirectory);
331         if (files == null)
332         {
333             return;
334         }
335         final Task task = new Task(PropertyNames.EMPTY_STRING, PropertyNames.EMPTY_STRING, files.length * 5);
336 
337         /*
338          * If more than a certain number
339          * of documents have been added,
340          * open the status dialog.
341          */
342         if (files.length > MIN_ADD_FILES_FOR_DIALOG)
343         {
344             StatusDialog sd = getStatusDialog();
345             sd.setLabel(resources.resValidatingDocuments);
346             sd.execute(this, task, resources.prodName); // new LoadDocs( sd.xControl, files, task )
347             LoadDocs oLoadDocs = new LoadDocs(this.xControl, files, task);
348             oLoadDocs.loadDocuments();
349             task.removeTaskListener(sd);
350         }
351         /*
352          * When adding a single document, do not use a
353          * status dialog...
354          */
355         else
356         {
357             LoadDocs oLoadDocs = new LoadDocs(this.xControl, files, task);
358             oLoadDocs.loadDocuments();
359         }
360 
361     }
362 
363     /**
364      * The user clicked delete.
365      */
366     public void removeDocument()
367     {
368         if (selectedDoc.length == 0)
369         {
370             return;
371         }
372         settings.cp_DefaultSession.cp_Content.cp_Documents.remove(selectedDoc[0]);
373 
374         // update the selected document
375         while (selectedDoc[0] >= getDocsCount())
376         {
377             selectedDoc[0]--;        // if there are no documents...
378         }
379         if (selectedDoc[0] == -1)
380         {
381             selectedDoc = EMPTY_SHORT_ARRAY;        // update the list to show the right selection.
382         }
383         docListDA.updateUI();
384         // disables all the next steps, if the list of docuemnts
385         // is empty.
386         checkSteps();
387     }
388 
389     /**
390      * doc up.
391      */
392     public void docUp()
393     {
394         Object doc = settings.cp_DefaultSession.cp_Content.cp_Documents.getElementAt(selectedDoc[0]);
395         settings.cp_DefaultSession.cp_Content.cp_Documents.remove(selectedDoc[0]);
396         settings.cp_DefaultSession.cp_Content.cp_Documents.add(--selectedDoc[0], doc);
397         docListDA.updateUI();
398         disableDocUpDown();
399     }
400 
401     /**
402      * doc down
403      */
404     public void docDown()
405     {
406         Object doc = settings.cp_DefaultSession.cp_Content.cp_Documents.getElementAt(selectedDoc[0]);
407         settings.cp_DefaultSession.cp_Content.cp_Documents.remove(selectedDoc[0]);
408         settings.cp_DefaultSession.cp_Content.cp_Documents.add(++selectedDoc[0], doc);
409         docListDA.updateUI();
410         disableDocUpDown();
411     }
412 
413     /* ******************************
414      * STEP 5
415      */
416     /**
417      * invoked when the user clicks "Choose backgrounds" button.
418      */
419     private ImageListDialog bgDialog;
420 
421     /**
422      * the user clicked the "backgrounds" button
423      */
424     public void chooseBackground()
425     {
426         try
427         {
428             setEnabled(btnBackgrounds, false);
429             if (bgDialog == null)
430             {
431                 bgDialog = new BackgroundsDialog(xMSF, settings.cp_BackgroundImages, resources);
432                 bgDialog.createWindowPeer(xControl.getPeer());
433             }
434             bgDialog.setSelected(settings.cp_DefaultSession.cp_Design.cp_BackgroundImage);
435             short i = bgDialog.executeDialog((UnoDialog) WWD_Events.this);
436             if (i == 1) //ok
437             {
438                 setBackground(bgDialog.getSelected());
439             }
440         }
441         catch (Exception ex)
442         {
443             ex.printStackTrace();
444         }
445         finally
446         {
447             setEnabled(btnBackgrounds, true);
448         }
449     }
450 
451     /**
452      * invoked when the BackgorundsDialog is "OKed".
453      */
454     public void setBackground(Object background)
455     {
456         if (background == null)
457         {
458             background = PropertyNames.EMPTY_STRING;
459         }
460         settings.cp_DefaultSession.cp_Design.cp_BackgroundImage = (String) background;
461         refreshStylePreview();
462     }
463     private IconsDialog iconsDialog;
464 
465     /**
466      * is called when the user clicks "Icon sets" button.
467      *
468      */
469     public void chooseIconset()
470     {
471         try
472         {
473             setEnabled(btnIconSets, false);
474             if (iconsDialog == null)
475             {
476                 iconsDialog = new IconsDialog(xMSF, settings.cp_IconSets, resources);
477                 iconsDialog.createWindowPeer(xControl.getPeer());
478             }
479 
480             iconsDialog.setIconset(settings.cp_DefaultSession.cp_Design.cp_IconSet);
481 
482             short i = iconsDialog.executeDialog((UnoDialog) WWD_Events.this);
483             if (i == 1) //ok
484             {
485                 setIconset(iconsDialog.getIconset());
486             }
487         }
488         catch (Exception ex)
489         {
490             ex.printStackTrace();
491         }
492         finally
493         {
494             setEnabled(btnIconSets, true);
495         }
496     }
497 
498     /**
499      * invoked when the Iconsets Dialog is OKed.
500      */
501     public void setIconset(String icon)
502     {
503         settings.cp_DefaultSession.cp_Design.cp_IconSet = icon;
504         updateIconsetText();
505     }
506 
507     /* ******************************
508      * STEP 7
509      */
510     /**
511      * sets the publishing url of either a local/zip or ftp publisher.
512      * updates the ui....
513      */
514     private CGPublish setPublishUrl(String publisher, String url, int number)
515     {
516         if (url == null)
517         {
518             return null;
519         }
520         CGPublish p = getPublisher(publisher);
521         p.cp_URL = url;
522         p.cp_Publish = true;
523         updatePublishUI(number);
524         p.overwriteApproved = true;
525         return p;
526     }
527 
528     /**
529      * updates the ui of a certain publisher
530      * (the text box url)
531      * @param number
532      */
533     private void updatePublishUI(int number)
534     {
535         ((DataAware) pubAware.get(number)).updateUI();
536         ((DataAware) pubAware.get(number + 1)).updateUI();
537         checkPublish();
538     }
539 
540     /**
541      * The user clicks the local "..." button.
542      *
543      */
544     public void setPublishLocalDir()
545     {
546         String dir = showFolderDialog("Local destination directory", PropertyNames.EMPTY_STRING, settings.cp_DefaultSession.cp_OutDirectory);
547         //if ok was pressed...
548         setPublishUrl(LOCAL_PUBLISHER, dir, 0);
549 
550     }
551 
552     /**
553      * The user clicks the "Configure" FTP button.
554      *
555      */
556     public void setFTPPublish()
557     {
558         if (showFTPDialog(getPublisher(FTP_PUBLISHER)))
559         {
560             getPublisher(FTP_PUBLISHER).cp_Publish = true;
561             updatePublishUI(2);
562         }
563     }
564 
565     /**
566      * show the ftp dialog
567      * @param pub
568      * @return true if OK was pressed, otherwise false.
569      */
570     private boolean showFTPDialog(CGPublish pub)
571     {
572         try
573         {
574             return getFTPDialog(pub).execute(this) == 1;
575         }
576         catch (Exception ex)
577         {
578             ex.printStackTrace();
579             return false;
580         }
581     }
582 
583     /**
584      * the user clicks the zip "..." button.
585      * Choose a zip file...
586      */
587     public void setZipFilename()
588     {
589         SystemDialog sd = getZipDialog();
590         String zipFile = sd.callStoreDialog(settings.cp_DefaultSession.cp_OutDirectory, resources.resDefaultArchiveFilename);
591         setPublishUrl(ZIP_PUBLISHER, zipFile, 4);
592         getPublisher(ZIP_PUBLISHER).overwriteApproved = true;
593     }
594     private TOCPreview docPreview;
595 
596     /**
597      * the user clicks the "Preview" button.
598      */
599     public void documentPreview()
600     {
601         try
602         {
603             if (docPreview == null)
604             {
605                 docPreview = new TOCPreview(xMSF, settings, resources, stylePreview.tempDir, myFrame);
606             }
607             docPreview.refresh(settings);
608         }
609         catch (Exception ex)
610         {
611             unexpectedError(ex);
612         }
613     }
614 
615     /* **********************
616      * FINISH
617      */
618     /**
619      * This method checks if the given target's path, added the pathExtension argument,
620      * exists, and asks the user what to do about it.
621      * If the user says its all fine, then the target will
622      * be replaced.
623      * @return true if "create" should continue. false if "create" should abort.
624      */
625     private boolean publishTargetApproved()
626     {
627         boolean result = true;
628         // 1. check local publish target
629 
630         CGPublish p = getPublisher(LOCAL_PUBLISHER);
631 
632         // should publish ?
633         if (p.cp_Publish)
634         {
635             String path = getFileAccess().getPath(p.url, null);
636             // target exists?
637             if (getFileAccess().exists(p.url, false))
638             {
639                 //if its a directory
640                 if (getFileAccess().isDirectory(p.url))
641                 {
642                     //check if its empty
643                     String[] files = getFileAccess().listFiles(p.url, true);
644                     if (files.length > 0)
645                     {
646                         /* it is not empty :-(
647                          * it either a local publisher or an ftp (zip uses no directories
648                          * as target...)
649                          */
650                         String message = JavaTools.replaceSubString(resources.resLocalTragetNotEmpty,
651                                 path, "%FILENAME");
652                         result = AbstractErrorHandler.showMessage(
653                                 xMSF, xControl.getPeer(), message,
654                                 ErrorHandler.MESSAGE_WARNING, ErrorHandler.BUTTONS_YES_NO,
655                                 ErrorHandler.DEF_NO, ErrorHandler.RESULT_YES);
656 
657                         if (!result)
658                         {
659                             return result;
660                         }
661                     }
662                 }
663                 else
664                 {//not a directory, but still exists
665                     String message = JavaTools.replaceSubString(resources.resLocalTargetExistsAsfile,
666                             path, "%FILENAME");
667                     AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message, ErrorHandler.ERROR_PROCESS_FATAL);
668                     return false;
669                 }
670 
671             // try to write to the path...
672             }
673             else
674             {
675                 // the local target directory does not exist.
676                 String message = JavaTools.replaceSubString(resources.resLocalTargetCreate,
677                         path, "%FILENAME");
678                 try
679                 {
680                     result = AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
681                             ErrorHandler.ERROR_QUESTION_YES);
682                 }
683                 catch (Exception ex)
684                 {
685                     ex.printStackTrace();
686                 }
687 
688                 if (!result)
689                 {
690                     return result;
691                 // try to create the directory...
692                 }
693                 try
694                 {
695                     getFileAccess().fileAccess.createFolder(p.cp_URL);
696                 }
697                 catch (Exception ex)
698                 {
699                     message = JavaTools.replaceSubString(resources.resLocalTargetCouldNotCreate,
700                             path, "%FILENAME");
701                     AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
702                             ErrorHandler.ERROR_PROCESS_FATAL);
703                     return false;
704                 }
705             }
706         }
707 
708         // 2. Check ZIP
709         // should publish ?
710         p = getPublisher(ZIP_PUBLISHER);
711 
712         if (p.cp_Publish)
713         {
714 
715             String path = getFileAccess().getPath(p.cp_URL, null);
716             // target exists?
717             if (getFileAccess().exists(p.cp_URL, false))
718             {
719                 //if its a directory
720                 if (getFileAccess().isDirectory(p.cp_URL))
721                 {
722                     String message = JavaTools.replaceSubString(resources.resZipTargetIsDir,
723                             path, "%FILENAME");
724                     AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
725                             ErrorHandler.ERROR_PROCESS_FATAL);
726                     return false;
727                 }
728                 else
729                 {//not a directory, but still exists ( a file...)
730                     if (!p.overwriteApproved)
731                     {
732                         String message = JavaTools.replaceSubString(resources.resZipTargetExists,
733                                 path, "%FILENAME");
734                         result = AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
735                                 ErrorHandler.ERROR_QUESTION_YES);
736                         if (!result)
737                         {
738                             return false;
739                         }
740                     }
741                 }
742             }
743         }
744 
745         // 3. check FTP
746         p = getPublisher(FTP_PUBLISHER);
747 
748         // should publish ?
749         if (p.cp_Publish)
750         {
751 
752             String path = getFileAccess().getPath(p.cp_URL, null);
753 
754             // target exists?
755             if (getFileAccess().exists(p.url, false))
756             {
757                 //if its a directory
758                 if (getFileAccess().isDirectory(p.url))
759                 {
760                     //check if its empty
761                     String[] files = getFileAccess().listFiles(p.url, true);
762                     if (files.length > 0)
763                     {
764                         /* it is not empty :-(
765                          * it either a local publisher or an ftp (zip uses no directories
766                          * as target...)
767                          */
768                         String message = JavaTools.replaceSubString(resources.resFTPTargetNotEmpty,
769                                 path, "%FILENAME");
770                         result = AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
771                                 ErrorHandler.ERROR_QUESTION_CANCEL);
772                         if (!result)
773                         {
774                             return result;
775                         }
776                     }
777                 }
778                 else
779                 {//not a directory, but still exists (as a file)
780                     String message = JavaTools.replaceSubString(resources.resFTPTargetExistsAsfile,
781                             path, "%FILENAME");
782                     AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
783                             ErrorHandler.ERROR_PROCESS_FATAL);
784                     return false;
785                 }
786 
787             // try to write to the path...
788             }
789             else
790             {
791                 // the ftp target directory does not exist.
792                 String message = JavaTools.replaceSubString(resources.resFTPTargetCreate,
793                         path, "%FILENAME");
794                 result = AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
795                         ErrorHandler.ERROR_QUESTION_YES);
796                 if (!result)
797                 {
798                     return result;
799                 // try to create the directory...
800                 }
801                 try
802                 {
803                     getFileAccess().fileAccess.createFolder(p.url);
804                 }
805                 catch (Exception ex)
806                 {
807                     message = JavaTools.replaceSubString(resources.resFTPTargetCouldNotCreate,
808                             path, "%FILENAME");
809                     AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message,
810                             ErrorHandler.ERROR_PROCESS_FATAL);
811                     return false;
812                 }
813             }
814         }
815         return true;
816     }
817 
818     /*
819      * return false if "create" should be aborted. true if everything is fine.
820      */
821     private boolean saveSession()
822     {
823         try
824         {
825             Object node = null;
826             String name = getSessionSaveName();
827 
828             //set documents index field.
829             ListModel docs = settings.cp_DefaultSession.cp_Content.cp_Documents;
830 
831             for (int i = 0; i < docs.getSize(); i++)
832             {
833                 ((CGDocument) docs.getElementAt(i)).cp_Index = i;
834             }
835             Object conf = Configuration.getConfigurationRoot(xMSF, CONFIG_PATH + "/SavedSessions", true);
836             // first I check if a session with the given name exists
837             try
838             {
839                 node = Configuration.getNode(name, conf);
840                 if (node != null)
841                 {
842                     if (!AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(),
843                             JavaTools.replaceSubString(resources.resSessionExists, name, "${NAME}"),
844                             ErrorHandler.ERROR_NORMAL_IGNORE))
845                     {
846                         return false;                    //remove the old session
847                     }
848                 }
849                 Configuration.removeNode(conf, name);
850 
851             }
852             catch (NoSuchElementException nsex)
853             {
854             }
855 
856             settings.cp_DefaultSession.cp_Index = 0;
857             node = Configuration.addConfigNode(conf, name);
858             settings.cp_DefaultSession.cp_Name = name;
859             settings.cp_DefaultSession.writeConfiguration(node, CONFIG_READ_PARAM);
860             settings.cp_SavedSessions.reindexSet(conf, name, "Index");
861             Configuration.commit(conf);
862 
863             // now I reload the sessions to actualize the list/combo boxes load/save sessions.
864             settings.cp_SavedSessions.clear();
865 
866             Object confView = Configuration.getConfigurationRoot(xMSF, CONFIG_PATH + "/SavedSessions", false);
867             settings.cp_SavedSessions.readConfiguration(confView, CONFIG_READ_PARAM);
868 
869             settings.cp_LastSavedSession = name;
870             currentSession = name;
871             // now save the name of the last saved session...
872 
873             settings.cp_LastSavedSession = name;
874 
875             // TODO add the <none> session...
876             prepareSessionLists();
877             ListModelBinder.fillList(lstLoadSettings, settings.cp_SavedSessions.items(), null);
878             ListModelBinder.fillComboBox(cbSaveSettings, settings.savedSessions.items(), null);
879             selectSession();
880 
881             currentSession = settings.cp_LastSavedSession;
882 
883             return true;
884         }
885         catch (Exception ex)
886         {
887             ex.printStackTrace();
888             return false;
889         }
890     }
891 
892     private String targetStringFor(String publisher)
893     {
894         CGPublish p = getPublisher(publisher);
895         if (p.cp_Publish)
896         {
897             return "\n" + getFileAccess().getPath(p.cp_URL, null);
898         }
899         else
900         {
901             return PropertyNames.EMPTY_STRING;
902         }
903     }
904 
905     /**
906      * this method will be called when the Status Dialog
907      * is hidden.
908      * It checks if the "Process" was successfull, and if so,
909      * it closes the wizard dialog.
910      */
911     public void finishWizardFinished()
912     {
913         if (process.getResult())
914         {
915             String targets =
916                     targetStringFor(LOCAL_PUBLISHER) +
917                     targetStringFor(ZIP_PUBLISHER) +
918                     targetStringFor(FTP_PUBLISHER);
919             String message = JavaTools.replaceSubString(resources.resFinishedSuccess, targets, "%FILENAME");
920 
921             AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), message, ErrorHandler.ERROR_MESSAGE);
922             if (exitOnCreate)
923             {
924                 this.xDialog.endExecute();
925             }
926         }
927         else
928         {
929             AbstractErrorHandler.showMessage(xMSF, xControl.getPeer(), resources.resFinishedNoSuccess, ErrorHandler.ERROR_WARNING);
930         }
931     }
932 
933     public void cancel()
934     {
935         xDialog.endExecute();
936     }
937     private Process process;
938     private boolean exitOnCreate = true;
939 
940     /**
941      * the user clicks the finish/create button.
942      */
943     public boolean finishWizard()
944     {
945         finishWizard(true);
946         return true;
947     }
948 
949     /**
950      * finish the wizard
951      * @param exitOnCreate_ should the wizard close after
952      * a successfull create.
953      * Default is true,
954      * I have a hidden feature which enables false here
955      */
956     public void finishWizard(boolean exitOnCreate_)
957     {
958 
959         exitOnCreate = exitOnCreate_;
960 
961         /**
962          * First I check if ftp password was set, if not - the ftp dialog pops up...
963          * This may happen when a session is loaded, since the
964          * session saves the ftp url and username, but not the password.
965          */
966         final CGPublish p = getPublisher(FTP_PUBLISHER);
967         // if ftp is checked, and no proxies are set, and password is empty...
968         if (p.cp_Publish && (!proxies) && (p.password == null || p.password.equals(PropertyNames.EMPTY_STRING)))
969         {
970             if (showFTPDialog(p))
971             {
972                 updatePublishUI(2);
973                 //now continue...
974                 finishWizard2();
975             }
976         }
977         else
978         {
979             finishWizard2();
980         }
981     }
982 
983     /**
984      * this method is only called
985      * if ftp-password was eather set, or
986      * the user entered one in the FTP Dialog which
987      * popped up when clicking "Create".
988      *
989      */
990     private void finishWizard2()
991     {
992 
993         CGPublish p = getPublisher(LOCAL_PUBLISHER);
994         p.url = p.cp_URL;
995 
996         /*
997          * zip publisher is using another url form...
998          */
999         p = getPublisher(ZIP_PUBLISHER);
1000         //replace the '%' with '%25'
1001         String url1 = JavaTools.replaceSubString(p.cp_URL, "%25", "%");
1002         //replace all '/' with '%2F'
1003         url1 = JavaTools.replaceSubString(url1, "%2F", "/");
1004 
1005         p.url = "vnd.sun.star.zip://" + url1 + "/";
1006 
1007         /*
1008          * and now ftp...
1009          */
1010         p = getPublisher(FTP_PUBLISHER);
1011         p.url = FTPDialog.getFullURL(p);
1012 
1013 
1014         /* first we check the publishing targets. If they exist we warn and ask
1015          * what to do. a False here means the user said "cancel" (or rather: clicked...)
1016          */
1017         if (!publishTargetApproved())
1018         {
1019             return;
1020         /*
1021          * In order to save the session correctly,
1022          * I return the value of the ftp publisher cp_Publish
1023          * property to its original value...
1024          */
1025         }
1026         p.cp_Publish = __ftp;
1027 
1028         //if the "save settings" checkbox is on...
1029         if (isSaveSession())
1030         {
1031             // if canceled by user
1032             if (!saveSession())
1033             {
1034                 return;
1035             }
1036         }
1037         else
1038         {
1039             settings.cp_LastSavedSession = PropertyNames.EMPTY_STRING;
1040         }
1041         try
1042         {
1043             Object conf = Configuration.getConfigurationRoot(xMSF, CONFIG_PATH, true);
1044             Configuration.set(
1045                     settings.cp_LastSavedSession,
1046                     "LastSavedSession", conf);
1047             Configuration.commit(conf);
1048         }
1049         catch (Exception ex)
1050         {
1051             ex.printStackTrace();
1052         }
1053 
1054         /*
1055          * again, if proxies are on, I disable ftp before the creation process
1056          * starts.
1057          */
1058         if (proxies)
1059         {
1060             p.cp_Publish = false;
1061 
1062         /*
1063          * There is currently a bug, which crashes office when
1064          * writing folders to an existing zip file, after deleting
1065          * its content, so I "manually" delete it here...
1066          */
1067         }
1068         p = getPublisher(ZIP_PUBLISHER);
1069         if (getFileAccess().exists(p.cp_URL, false))
1070         {
1071             getFileAccess().delete(p.cp_URL);
1072         }
1073         try
1074         {
1075 
1076             ErrorHandler eh = new ProcessErrorHandler(xMSF, xControl.getPeer(), resources);
1077 
1078             process = new Process(settings, xMSF, eh);
1079 
1080             StatusDialog pd = getStatusDialog();
1081 
1082             pd.setRenderer(new ProcessStatusRenderer(resources));
1083             pd.execute(this, process.myTask, resources.prodName);  //process,
1084             process.runProcess();
1085             finishWizardFinished();
1086             process.myTask.removeTaskListener(pd);
1087 
1088         }
1089         catch (Exception ex)
1090         {
1091             ex.printStackTrace();
1092         }
1093 
1094     }
1095 
1096     /**
1097      * implements a hidden feature for "finishing" without
1098      * closing the wizard.
1099      * press "&%" quite fast when the focus is on one
1100      * of the last steps' checkboxes.
1101      * @author rp143992
1102      */
1103     private class Create implements XKeyListener
1104     {
1105 
1106         long time = 0;
1107         int count = 0;
1108 
1109         /* (non-Javadoc)
1110          * @see com.sun.star.awt.XKeyListener#keyPressed(com.sun.star.awt.KeyEvent)
1111          */
1112         public void keyPressed(KeyEvent ke)
1113         {
1114             if (ke.KeyChar == '&')
1115             {
1116                 time = System.currentTimeMillis();
1117             }
1118             else if (ke.KeyChar == '%' && ((System.currentTimeMillis() - time) < 300))
1119             {
1120                 Boolean b = (Boolean) getControlProperty("btnWizardFinish", PropertyNames.PROPERTY_ENABLED);
1121                 if (b.booleanValue())
1122                 {
1123                     finishWizard(false);
1124                 }
1125             }
1126         }
1127 
1128         public void keyReleased(KeyEvent arg0)
1129         {
1130         }
1131 
1132         public void disposing(EventObject arg0)
1133         {
1134         }
1135     }
1136 
1137     /**
1138      * is called on the WindowHidden event,
1139      * deletes the temporary directory.
1140      */
1141     public void cleanup()
1142     {
1143 
1144 
1145         try
1146         {
1147             dpStylePreview.dispose();
1148         }
1149         catch (Exception ex)
1150         {
1151             ex.printStackTrace();
1152         }
1153 
1154         stylePreview.cleanup();
1155 
1156         try
1157         {
1158             if (bgDialog != null)
1159             {
1160                 bgDialog.xComponent.dispose();
1161             }
1162         }
1163         catch (Exception ex)
1164         {
1165             ex.printStackTrace();
1166         }
1167 
1168         try
1169         {
1170             if (iconsDialog != null)
1171             {
1172                 iconsDialog.xComponent.dispose();
1173             }
1174         }
1175         catch (Exception ex)
1176         {
1177             ex.printStackTrace();
1178         }
1179 
1180         try
1181         {
1182             if (ftpDialog != null)
1183             {
1184                 ftpDialog.xComponent.dispose();
1185             }
1186         }
1187         catch (Exception ex)
1188         {
1189             ex.printStackTrace();
1190         }
1191 
1192         try
1193         {
1194             xComponent.dispose();
1195         }
1196         catch (Exception ex)
1197         {
1198             ex.printStackTrace();
1199         }
1200 
1201         try
1202         {
1203             //XCloseable xCloseable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, myDocument);
1204             //if (xCloseable != null)
1205             //    xCloseable.close(false);
1206 
1207             XCloseable xCloseable = UnoRuntime.queryInterface(XCloseable.class, myFrame);
1208             if (xCloseable != null)
1209             {
1210                 xCloseable.close(false);
1211             }
1212         }
1213         catch (Exception ex)
1214         {
1215             ex.printStackTrace();
1216         }
1217 
1218     }
1219 
1220     public class LoadDocs
1221     {
1222 
1223         private XControl xC;
1224         String[] files;
1225         Task task;
1226 
1227         public LoadDocs(XControl xC_, String[] files_, Task task_)
1228         {
1229             xC = xC_;
1230             files = files_;
1231             task = task_;
1232         }
1233 
1234         public void loadDocuments()
1235         {
1236             //LogTaskListener lts = new LogTaskListener();
1237             //task.addTaskListener(lts);
1238 
1239 //            task.start();
1240 
1241             // where the documents are added to in the list (offset)
1242             int offset = (getSelectedDoc().length > 0 ? selectedDoc[0] + 1 : getDocsCount());
1243 
1244             /* if the user chose one file, the list starts at 0,
1245              * if he chose more than one, the first entry is a directory name,
1246              * all the others are filenames.
1247              */
1248             int start = (files.length > 1 ? 1 : 0);
1249             /*
1250              * Number of documents failed to validate.
1251              */
1252             int failed = 0;
1253 
1254             // store the directory
1255             settings.cp_DefaultSession.cp_InDirectory = start == 1 ? files[0] : FileAccess.getParentDir(files[0]);
1256 
1257             /*
1258              * Here i go through each file, and validate it.
1259              * If its ok, I add it to the ListModel/ConfigSet
1260              */
1261             for (int i = start; i < files.length; i++)
1262             {
1263                 CGDocument doc = new CGDocument();
1264                 doc.setRoot(settings);
1265 
1266                 doc.cp_URL = (start == 0) ? files[i] : FileAccess.connectURLs(files[0], files[i]);
1267 
1268                 /* so - i check each document and if it is ok I add it.
1269                  * The failed variable is used only to calculate the place to add -
1270                  * Error reporting to the user is (or should (-:  )done in the checkDocument(...) method
1271                  */
1272                 if (checkDocument(doc, task, xC))
1273                 {
1274                     settings.cp_DefaultSession.cp_Content.cp_Documents.add(offset + i - failed - start, doc);
1275                 }
1276                 else
1277                 {
1278                     failed++;
1279                 }
1280             }
1281 
1282             // if any documents where added,
1283             // set the first one to be the current-selected document.
1284             if (files.length > start + failed)
1285             {
1286                 setSelectedDoc(new short[]
1287                         {
1288                             (short) offset
1289                         });
1290             }
1291             // update the ui...
1292             docListDA.updateUI();
1293             // this enables/disables the next steps.
1294             // when no documents in the list, all next steps are disabled
1295             checkSteps();
1296             /* a small insurance that the status dialog will
1297              * really close...
1298              */
1299             while (task.getStatus() < task.getMax())
1300             {
1301                 task.advance(false);
1302             }
1303         }
1304     }
1305 }
1306 
1307