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