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 
24 package com.sun.star.wizards.agenda;
25 
26 import java.util.Vector;
27 
28 import com.sun.star.awt.ItemEvent;
29 import com.sun.star.awt.VclWindowPeerAttribute;
30 import com.sun.star.awt.XItemListener;
31 import com.sun.star.awt.XWindow;
32 import com.sun.star.awt.XWindowPeer;
33 import com.sun.star.beans.PropertyValue;
34 import com.sun.star.frame.XStorable;
35 import com.sun.star.lang.EventObject;
36 import com.sun.star.lang.XMultiServiceFactory;
37 import com.sun.star.task.XInteractionHandler;
38 import com.sun.star.text.XTextDocument;
39 import com.sun.star.uno.UnoRuntime;
40 import com.sun.star.util.CloseVetoException;
41 import com.sun.star.util.XCloseable;
42 import com.sun.star.wizards.common.Configuration;
43 import com.sun.star.wizards.common.Desktop;
44 import com.sun.star.wizards.common.FileAccess;
45 import com.sun.star.wizards.common.Helper;
46 import com.sun.star.wizards.common.NoValidPathException;
47 import com.sun.star.wizards.common.SystemDialog;
48 import com.sun.star.wizards.common.HelpIds;
49 import com.sun.star.wizards.common.PropertyNames;
50 import com.sun.star.wizards.document.OfficeDocument;
51 import com.sun.star.wizards.text.ViewHandler;
52 import com.sun.star.wizards.ui.PathSelection;
53 import com.sun.star.wizards.ui.XPathSelectionListener;
54 import com.sun.star.wizards.ui.event.DataAware;
55 import com.sun.star.wizards.ui.event.RadioDataAware;
56 import com.sun.star.wizards.ui.event.UnoDataAware;
57 
58 /**
59  * This class is the dialog implementation class -
60  * there is not much business logic here - but mostley
61  * event methods.
62  * Some event methods are also implemented in TopicsControl and TopicsControl.ControlRow.
63  * @author rp143992
64  */
65 public class AgendaWizardDialogImpl extends AgendaWizardDialog
66 {
67     /**
68      * used to prevent a double start of the wizard.
69      */
70     static boolean running;
71 
72     /**
73      * the preview document controller.
74      */
75     AgendaTemplate agendaTemplate;
76     /**
77      * the data model, read from the OOo configuration.
78      * (live synchronized: when the user changes the gui,
79      * the data model changes, except for topics).
80      */
81     private CGAgenda agenda;
82 
83     /**
84      * the topics control, a gui element which
85      * manipulates the topics data according to the
86      * user's input.
87      */
88     private TopicsControl topicsControl;
89 
90     /**
91      * an array with two array memebers:
92      * agendaTemplates[0] contains an array with
93      * UI template names.
94      * agendaTemplates[1] contains an array with
95      * corresponding URLs.
96      */
97     private String[][] agendaTemplates;
98 
99     PathSelection myPathSelection;
100 
101     String sTemplatePath;
102     String sUserTemplatePath;
103     String sBitmapPath;
104 
105     String sPath;
106 
107     /** constructor */
AgendaWizardDialogImpl(XMultiServiceFactory xmsf)108     public AgendaWizardDialogImpl(XMultiServiceFactory xmsf)
109     {
110         super(xmsf);
111     }
112 
enterStep(int OldStep, int NewStep)113     protected void enterStep(int OldStep, int NewStep) {}
leaveStep(int OldStep, int NewStep)114     protected void leaveStep(int OldStep, int NewStep) {}
115 
116     /**
117      * read the configuration data, open the specified template,
118      * initialize the template controller (AgendaTemplate) and
119      * set the status of the displayed template to the one
120      * read from the configuration.
121      * build the dialog.
122      * Synchronize the dialog to the same status (read from
123      * the configuration).
124      * show the dialog.
125      */
startWizard()126     public void startWizard() {
127         running = true;
128         try  {
129             // read configuration data.
130             agenda = new CGAgenda();
131 
132             Object root = Configuration.getConfigurationRoot(xMSF, "/org.openoffice.Office.Writer/Wizards/Agenda", false);
133             agenda.readConfiguration(root,"cp_");
134 
135             // initialize the agenda template
136             agendaTemplate = new AgendaTemplate(xMSF, agenda, resources, this);
137             initializeTemplates();
138 
139             agendaTemplate.load(agendaTemplates[1][agenda.cp_AgendaType] , new Vector());
140 
141             // build the dialog.
142             buildStep1();
143             buildStep2();
144             buildStep3();
145             buildStep4();
146             buildStep5();
147             topicsControl = new TopicsControl(this,xMSF, agenda);
148             buildStep6();
149             drawNaviBar();
150 
151             initializePaths();
152 
153             //special Control for setting the save Path:
154             insertPathSelectionControl();
155 
156             // create the peer
157             XWindow xw = agendaTemplate.xFrame.getContainerWindow();
158             XWindowPeer xWindowPeer = UnoRuntime.queryInterface(XWindowPeer.class, xw);
159             this.createWindowPeer( xWindowPeer );
160 
161             // initialize roadmap
162             this.addRoadmap();
163             this.insertRoadMapItems(
164                     new String[] { resources.resStep1, resources.resStep2, resources.resStep3, resources.resStep4, resources.resStep5, resources.resStep6, } ,
165                     new int[] { 1,2,3,4,5,6},
166                     new boolean[] { true,true,true,true,true,true }
167                     );
168             this.setMaxStep(6);
169 
170             // synchronize GUI and CGAgenda object.
171             makeDA();
172             if(myPathSelection.xSaveTextBox.getText().equalsIgnoreCase(PropertyNames.EMPTY_STRING)) {myPathSelection.initializePath();}
173 
174             executeDialog(agendaTemplate.xFrame);
175             removeTerminateListener();
176             closeDocument();
177             running = false;
178 
179         }
180         catch (Exception ex) {
181             removeTerminateListener();
182             ex.printStackTrace();
183             running=false;
184             }
185 
186 
187     }
188 
189     private class myPathSelectionListener implements XPathSelectionListener {
validatePath()190         public void validatePath() {
191             if (myPathSelection.usedPathPicker) {
192                 filenameChanged = true;
193             }
194             myPathSelection.usedPathPicker = false;
195         }
196     }
197 
198 
insertPathSelectionControl()199     public void insertPathSelectionControl() {
200         myPathSelection = new PathSelection(xMSF, this, PathSelection.TransferMode.SAVE, PathSelection.DialogTypes.FILE);
201         myPathSelection.insert(6, 97, 70, 205, (short) 45, resources.reslblTemplatePath_value, true, HelpIds.getHelpIdString( HID + 24 ), HelpIds.getHelpIdString( HID + 25 ));
202         myPathSelection.sDefaultDirectory = sUserTemplatePath;
203         myPathSelection.sDefaultName = "myAgendaTemplate.ott";
204         myPathSelection.sDefaultFilter = "writer8_template";
205         myPathSelection.addSelectionListener(new myPathSelectionListener());
206     }
207 
initializePaths()208     private void initializePaths() {
209         try {
210             sTemplatePath = FileAccess.getOfficePath(xMSF, "Template", "share", "/wizard");
211             sUserTemplatePath = FileAccess.getOfficePath(xMSF, "Template", "user", PropertyNames.EMPTY_STRING);
212             sBitmapPath = FileAccess.combinePaths(xMSF, sTemplatePath, "/../wizard/bitmap");
213         } catch (NoValidPathException e) {
214             e.printStackTrace();
215         }
216     }
217 
checkSavePath()218     private void checkSavePath() {
219         if (agenda.cp_TemplatePath == null ||
220                 agenda.cp_TemplatePath.equals(PropertyNames.EMPTY_STRING) ||
221                 !getFileAccess().exists(FileAccess.getParentDir(agenda.cp_TemplatePath),false) ||
222                 !getFileAccess().isDirectory(FileAccess.getParentDir(agenda.cp_TemplatePath )))
223             {
224                 try  {
225                     agenda.cp_TemplatePath =
226                         FileAccess.connectURLs(
227                             FileAccess.getOfficePath(xMSF, "Work", PropertyNames.EMPTY_STRING, PropertyNames.EMPTY_STRING) ,
228                             resources.resDefaultFilename
229                         );
230                 }
231                 catch (Exception ex) {
232                     ex.printStackTrace();
233                 }
234             }
235     }
236 
237     /**
238      * bind controls to the agenda member (DataAware model)
239      */
makeDA()240     private void makeDA() {
241 
242         setControlProperty("listPageDesign", PropertyNames.STRING_ITEM_LIST, agendaTemplates[0]);
243 
244         checkSavePath();
245         //setFilename(agenda.cp_TemplatePath);
246 
247         UnoDataAware.attachListBox( agenda, "cp_AgendaType", listPageDesign , null, true ).updateUI();
248         UnoDataAware.attachCheckBox( agenda, "cp_IncludeMinutes", chkMinutes, null, true).updateUI();
249 
250         UnoDataAware.attachEditControl(agenda, "cp_Title", txtTitle, agendaTemplate , true).updateUI();
251         UnoDataAware.attachDateControl(agenda, "cp_Date", txtDate, agendaTemplate , true).updateUI();
252         UnoDataAware.attachTimeControl(agenda, "cp_Time", txtTime, agendaTemplate , true).updateUI();
253         UnoDataAware.attachEditControl(agenda, "cp_Location", cbLocation, agendaTemplate , true).updateUI();
254 
255         UnoDataAware.attachCheckBox(agenda,"cp_ShowMeetingType", chkMeetingTitle , new RedrawListener( TemplateConsts.FILLIN_MEETING_TYPE ) , true);
256         UnoDataAware.attachCheckBox(agenda,"cp_ShowRead", chkRead , new RedrawListener( TemplateConsts.FILLIN_READ ) , true).updateUI();
257         UnoDataAware.attachCheckBox(agenda,"cp_ShowBring", chkBring , new RedrawListener( TemplateConsts.FILLIN_BRING ) , true).updateUI();
258         UnoDataAware.attachCheckBox(agenda,"cp_ShowNotes", chkNotes , new RedrawListener( TemplateConsts.FILLIN_NOTES ) , true).updateUI();
259 
260         UnoDataAware.attachCheckBox(agenda,"cp_ShowCalledBy", chkConvenedBy , new RedrawListener( TemplateConsts.FILLIN_CALLED_BY ) , true).updateUI();
261         UnoDataAware.attachCheckBox(agenda,"cp_ShowFacilitator", chkPresiding , new RedrawListener( TemplateConsts.FILLIN_FACILITATOR ) , true).updateUI();
262         UnoDataAware.attachCheckBox(agenda,"cp_ShowNotetaker", chkNoteTaker , new RedrawListener( TemplateConsts.FILLIN_NOTETAKER ) , true).updateUI();
263         UnoDataAware.attachCheckBox(agenda,"cp_ShowTimekeeper", chkTimekeeper , new RedrawListener( TemplateConsts.FILLIN_TIMEKEEPER ) , true).updateUI();
264         UnoDataAware.attachCheckBox(agenda,"cp_ShowAttendees", chkAttendees , new RedrawListener( TemplateConsts.FILLIN_PARTICIPANTS ) , true).updateUI();
265         UnoDataAware.attachCheckBox(agenda,"cp_ShowObservers", chkObservers , new RedrawListener( TemplateConsts.FILLIN_OBSERVERS ) , true).updateUI();
266         UnoDataAware.attachCheckBox(agenda,"cp_ShowResourcePersons", chkResourcePersons , new RedrawListener( TemplateConsts.FILLIN_RESOURCE_PERSONS ) , true).updateUI();
267 
268         UnoDataAware.attachEditControl(agenda, "cp_TemplateName", txtTemplateName, null, true).updateUI();
269         RadioDataAware.attachRadioButtons( agenda, "cp_ProceedMethod",
270                 new Object[] {optCreateAgenda, optMakeChanges} ,null,true).updateUI();
271 
272         listPageDesign.addItemListener(new XItemListener() {
273             public void itemStateChanged(ItemEvent ie) {
274                 pageDesignChanged(ie);
275             }
276             public void disposing(EventObject eo) {}
277         });
278     }
279 
280     /** used in development to start the wizard */
main(String args[])281     public static void main(String args[])
282     {
283         String ConnectStr = "uno:socket,host=127.0.0.1,port=8100;urp,negotiate=0,forcesynchronous=1;StarOffice.ServiceManager";
284         try {
285             XMultiServiceFactory xLocMSF = Desktop.connect(ConnectStr);
286             AgendaWizardDialogImpl wizard = new AgendaWizardDialogImpl(xLocMSF);
287             wizard.startWizard();
288 
289         }
290         catch (Exception exception) {
291             exception.printStackTrace();
292         }
293     }
294 
295 
296     /*
297     private void initializePaths() {
298         try {
299 
300             sUserTemplatePath = FileAccess.getOfficePath(xMSF, "Template", "user");
301             sBitmapPath = FileAccess.combinePaths(xMSF, sTemplatePath, "/../wizard/bitmap");
302         } catch (NoValidPathException e) {
303             e.printStackTrace();
304         }
305     }*/
306 
307     /**
308      * read the available agenda wizard templates.
309      */
initializeTemplates()310     public boolean initializeTemplates() {
311         try {
312             String sTemplatePath = FileAccess.getOfficePath(xMSF, "Template", "share", "/wizard");
313 
314             //sCurrentNorm = Norms[getCurrentLetter().cp_Norm];
315             String sAgendaPath = FileAccess.combinePaths(xMSF, sTemplatePath, "/wizard/agenda" );
316 
317             agendaTemplates = FileAccess.getFolderTitles(xMSF, "aw" , sAgendaPath);
318 
319             return true;
320         } catch (NoValidPathException nopathexception) {
321             nopathexception.printStackTrace();
322             return false;
323         } catch (Exception exception) {
324             exception.printStackTrace();
325             return false;
326         }
327     }
328 
329     /* ******************************
330      * Event methods
331      * ******************************
332      */
333 
334     /**
335      * first page, page design listbox changed.
336      */
pageDesignChanged(ItemEvent ie)337     public void pageDesignChanged(ItemEvent ie) {
338         int selected = ie.Selected;
339         try {
340             agendaTemplate.load( agendaTemplates[1][selected] , topicsControl.getTopicsData());
341         }
342         catch (Exception ex) {
343             SystemDialog.showMessageBox(xMSF, "ErrBox", VclWindowPeerAttribute.OK, resources.resErrOpenTemplate);
344             ex.printStackTrace();
345         }
346     }
347 
348     /**
349      * last page, template title changed...
350      */
templateTitleChanged()351     public void templateTitleChanged() {
352         String title = (String)Helper.getUnoPropertyValue( getModel(txtTemplateName), "Text" );
353         agendaTemplate.setTemplateTitle( title );
354     }
355 
356 
357     private FileAccess fileAccess1;
358     /** convenience method.
359      *  instead of creating a FileAccess object every time
360      *  it is needed, I have a FileAccess object member.
361      *  the first time it is needed it will be created, and
362      *  then be reused...
363      * @return the FileAccess member object.
364      */
getFileAccess()365     private FileAccess getFileAccess() {
366         if (fileAccess1 == null)
367             try {
368                 fileAccess1 = new FileAccess(xMSF);
369             } catch (Exception e) {
370                 e.printStackTrace();
371             }
372         return fileAccess1;
373 
374     }
375     /**
376      * indicates if the filename was changed by the user through
377      * the "save as" dialog.
378      * If it is so, one needs not warn the user
379      * upon overwrite, since she was already warned.
380      */
381     private boolean filenameChanged = false;
382 
383     /**
384      * last page, "browse" ("...") button was clicked...
385      */
saveAs()386     public void saveAs() {
387         try {
388 
389             checkSavePath();
390 
391             SystemDialog saveAs = SystemDialog.createStoreDialog(xMSF);
392             saveAs.addFilterToDialog("ott","writer8_template",true);
393             // call the saveAs dialog.
394             String url = saveAs.callStoreDialog(
395                 FileAccess.getParentDir(agenda.cp_TemplatePath),
396                 FileAccess.getFilename(agenda.cp_TemplatePath));
397 
398             if (url != null) {
399                 agenda.cp_TemplatePath = url;
400                 setFilename(url);
401                 filenameChanged = true;
402             }
403         }
404         catch (Exception ex) {
405             ex.printStackTrace();
406         }
407 
408 
409     }
410 
411     /**
412      * is called when the user
413      * changes the path through the "save as" dialog.
414      * The path displayed is a translated, user-friendly, platform dependent path.
415      * @param url the new save url.
416      */
setFilename(String url)417     private void setFilename(String url) {
418         try {
419             String path = getFileAccess().getPath(url,PropertyNames.EMPTY_STRING);
420             Helper.setUnoPropertyValue( getModel(myPathSelection.xSaveTextBox), "Text", path);
421         }
422         catch (Exception ex) {
423             ex.printStackTrace();
424         }
425 
426     }
427 
insertRow()428     public void insertRow() {
429         topicsControl.insertRow();
430     }
431 
removeRow()432     public void removeRow() {
433         topicsControl.removeRow();
434     }
435 
rowUp()436     public void rowUp() {
437         topicsControl.rowUp();
438     }
439 
rowDown()440     public void rowDown() {
441         topicsControl.rowDown();
442     }
443 
444 
445     /* ************************
446      * Navigation bar methods
447      * ************************
448      */
449 
cancelWizard()450     public void cancelWizard() {
451         xDialog.endExecute();
452         running = false;
453     }
454 
finishWizard()455     public boolean finishWizard() {
456         boolean bSaveSuccess = false; // pesimistic :(
457         XTextDocument xTextDocument;
458 
459         try {
460             FileAccess fileAccess = new FileAccess(xMSF);
461             sPath = myPathSelection.getSelectedPath();
462             if (sPath.equals(PropertyNames.EMPTY_STRING)) {
463                 myPathSelection.triggerPathPicker();
464                 sPath = myPathSelection.getSelectedPath();
465             }
466             sPath = fileAccess.getURL(sPath);
467 
468             //first, if the filename was not changed, thus
469             //it is coming from a saved session, check if the
470             // file exists and warn the user.
471             if (!filenameChanged)
472                 if (fileAccess.exists(sPath, true)) {
473 
474                     int answer = SystemDialog.showMessageBox(xMSF, xControl.getPeer(), "MessBox", VclWindowPeerAttribute.YES_NO + VclWindowPeerAttribute.DEF_NO, resources.resFileExists);
475                     if (answer == 3) // user said: no, do not overwrite....
476                         return false;
477                 }
478 
479             agendaTemplate.xTextDocument.lockControllers();
480 
481             xTextDocument = UnoRuntime.queryInterface(XTextDocument.class,agendaTemplate.document);
482 
483             bSaveSuccess = OfficeDocument.store(xMSF, xTextDocument, sPath , "writer8_template", false );
484         } catch (Exception e) {
485             SystemDialog.showMessageBox(xMSF, xControl.getPeer(), "ErrBox", VclWindowPeerAttribute.OK, resources.resErrSaveTemplate);
486             //e.printStackTrace();
487         }
488 
489         if (bSaveSuccess) {
490             try {
491                 topicsControl.saveTopics(agenda);
492                 Object root = Configuration.getConfigurationRoot(xMSF, "/org.openoffice.Office.Writer/Wizards/Agenda", true);
493                 agenda.writeConfiguration(root,"cp_");
494                 Configuration.commit(root);
495             }
496             catch (Exception ex) {
497                 ex.printStackTrace();
498             }
499 
500             agendaTemplate.finish( topicsControl.getTopicsData());
501             try {
502                 XStorable xStoreable = UnoRuntime.queryInterface(XStorable.class, agendaTemplate.document);
503                 xStoreable.store();
504             }
505             catch (Exception ex) {
506                 SystemDialog.showMessageBox(xMSF, "ErrBox", VclWindowPeerAttribute.OK, resources.resErrSaveTemplate);
507                 ex.printStackTrace();
508             }
509 
510             //xWindow.setVisible(false);
511             //running = false;
512             agendaTemplate.xTextDocument.unlockControllers();
513             //closeDocument();
514             //removeTerminateListener();
515 
516             PropertyValue loadValues[] = new PropertyValue[2];
517             loadValues[0] = new PropertyValue();
518             loadValues[0].Name = "AsTemplate";
519             if (agenda.cp_ProceedMethod == 1) {
520                 loadValues[0].Value = Boolean.TRUE;
521             } else {
522                 loadValues[0].Value = Boolean.FALSE;
523             }
524             loadValues[1] = new PropertyValue();
525             loadValues[1].Name = "InteractionHandler";
526             try {
527                 loadValues[1].Value = UnoRuntime.queryInterface(XInteractionHandler.class, xMSF.createInstance("com.sun.star.comp.uui.UUIInteractionHandler"));
528             } catch (Exception e) {
529                 // TODO Auto-generated catch block
530                 e.printStackTrace();
531             }
532             //Object oDoc = OfficeDocument.load(Desktop.getDesktop(xMSF), agenda.cp_TemplatePath, "_default", new PropertyValue[0]);
533             Object oDoc = OfficeDocument.load(Desktop.getDesktop(xMSF), sPath, "_default", new PropertyValue[0]);
534                         xTextDocument = (com.sun.star.text.XTextDocument) oDoc;
535             XMultiServiceFactory xDocMSF = UnoRuntime.queryInterface(XMultiServiceFactory.class, xTextDocument);
536             ViewHandler myViewHandler = new ViewHandler(xDocMSF, xTextDocument);
537             try {
538                 myViewHandler.setViewSetting("ZoomType", new Short(com.sun.star.view.DocumentZoomType.OPTIMAL));
539             }
540             catch (Exception ex) {
541                 ex.printStackTrace();
542             }
543         } else {
544             agendaTemplate.xTextDocument.unlockControllers();
545             return false;
546         }
547         xDialog.endExecute();
548         running = false;
549         return true;
550     }
551 
closeDocument()552     private void closeDocument() {
553         try {
554             //xComponent.dispose();
555             XCloseable xCloseable = UnoRuntime.queryInterface(XCloseable.class, agendaTemplate.xFrame);
556             xCloseable.close(false);
557         } catch (CloseVetoException e) {
558             e.printStackTrace();
559         }
560     }
561 
562     /* ********************
563      * Sub Classes
564      * ********************
565      */
566 
567 
568     /**
569      * this class is used to redraw an item's table when
570      * the user clicks one of the checkboxes in step 3 or 4.
571      */
572     private class RedrawListener implements DataAware.Listener {
573 
574         private String itemName;
575 
RedrawListener(String itemName_)576         public RedrawListener(String itemName_) {
577             itemName = itemName_;
578         }
579 
580         /* (non-Javadoc)
581          * @see com.sun.star.wizards.ui.event.DataAware.Listener#eventPerformed(java.lang.Object)
582          */
eventPerformed(Object event)583         public void eventPerformed(Object event) {
584             agendaTemplate.xTextDocument.lockControllers();
585             agendaTemplate.redraw(itemName);
586             agendaTemplate.xTextDocument.unlockControllers();
587         }
588     }
589 
590 
591 }
592 
593