1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package com.sun.star.wizards.text;
24 
25 import java.util.Calendar;
26 import java.util.GregorianCalendar;
27 
28 import com.sun.star.container.NoSuchElementException;
29 import com.sun.star.container.XNameAccess;
30 import com.sun.star.document.XDocumentProperties;
31 import com.sun.star.document.XDocumentPropertiesSupplier;
32 import com.sun.star.frame.XController;
33 import com.sun.star.frame.XComponentLoader;
34 import com.sun.star.frame.XDesktop;
35 import com.sun.star.frame.XFramesSupplier;
36 import com.sun.star.frame.XLoadable;
37 import com.sun.star.frame.XModel;
38 import com.sun.star.frame.XModule;
39 import com.sun.star.frame.XTerminateListener;
40 import com.sun.star.frame.XStorable;
41 import com.sun.star.i18n.NumberFormatIndex;
42 import com.sun.star.awt.Size;
43 import com.sun.star.awt.XWindow;
44 import com.sun.star.awt.XWindowPeer;
45 import com.sun.star.beans.PropertyValue;
46 import com.sun.star.beans.PropertyVetoException;
47 import com.sun.star.lang.Locale;
48 import com.sun.star.lang.WrappedTargetException;
49 import com.sun.star.lang.XComponent;
50 import com.sun.star.lang.XMultiServiceFactory;
51 
52 import com.sun.star.style.XStyle;
53 import com.sun.star.style.XStyleFamiliesSupplier;
54 import com.sun.star.task.XStatusIndicatorFactory;
55 import com.sun.star.text.XPageCursor;
56 import com.sun.star.text.XSimpleText;
57 import com.sun.star.text.XText;
58 import com.sun.star.text.XTextContent;
59 import com.sun.star.text.XTextCursor;
60 import com.sun.star.text.XTextDocument;
61 import com.sun.star.text.XTextViewCursor;
62 import com.sun.star.text.XTextViewCursorSupplier;
63 import com.sun.star.uno.UnoRuntime;
64 import com.sun.star.util.DateTime;
65 import com.sun.star.util.XModifiable;
66 import com.sun.star.util.XNumberFormatsSupplier;
67 import com.sun.star.util.XRefreshable;
68 import com.sun.star.wizards.common.Configuration;
69 import com.sun.star.wizards.common.Desktop;
70 import com.sun.star.wizards.common.Helper;
71 import com.sun.star.wizards.common.JavaTools;
72 import com.sun.star.wizards.common.Helper.DateUtils;
73 import com.sun.star.wizards.common.PropertyNames;
74 import com.sun.star.wizards.document.OfficeDocument;
75 
76 public class TextDocument
77 {
78 
79     public XComponent xComponent;
80     public com.sun.star.text.XTextDocument xTextDocument;
81     public com.sun.star.util.XNumberFormats NumberFormats;
82     public com.sun.star.document.XDocumentProperties m_xDocProps;
83     public com.sun.star.task.XStatusIndicator xProgressBar;
84     public com.sun.star.frame.XFrame xFrame;
85     public XText xText;
86     public XMultiServiceFactory xMSFDoc;
87     public XMultiServiceFactory xMSF;
88     public com.sun.star.util.XNumberFormatsSupplier xNumberFormatsSupplier;
89     public com.sun.star.awt.XWindowPeer xWindowPeer;
90     public int PageWidth;
91     public int ScaleWidth;
92     public Size DocSize;
93     public com.sun.star.awt.Rectangle PosSize;
94     public com.sun.star.lang.Locale CharLocale;
95     public XStorable xStorable;
96 
97     // creates an instance of TextDocument and creates a named frame. No document is actually loaded into this frame.
TextDocument(XMultiServiceFactory xMSF, XTerminateListener listener, String FrameName)98     public TextDocument(XMultiServiceFactory xMSF, XTerminateListener listener, String FrameName)
99     {
100         this.xMSF = xMSF;
101         xFrame = OfficeDocument.createNewFrame(xMSF, listener, FrameName);
102     }
103 
104     // creates an instance of TextDocument by loading a given URL as preview
TextDocument(XMultiServiceFactory xMSF, String _sPreviewURL, boolean bShowStatusIndicator, XTerminateListener listener)105     public TextDocument(XMultiServiceFactory xMSF, String _sPreviewURL, boolean bShowStatusIndicator, XTerminateListener listener)
106     {
107         this.xMSF = xMSF;
108 
109         xFrame = OfficeDocument.createNewFrame(xMSF, listener);
110         xTextDocument = loadAsPreview(_sPreviewURL, true);
111         xComponent = UnoRuntime.queryInterface(XComponent.class, xTextDocument);
112 
113         if (bShowStatusIndicator)
114         {
115             showStatusIndicator();
116         }
117         init();
118     }
119 
120     // creates an instance of TextDocument from the desktop's current frame
TextDocument(XMultiServiceFactory xMSF, boolean bShowStatusIndicator, XTerminateListener listener)121     public TextDocument(XMultiServiceFactory xMSF, boolean bShowStatusIndicator, XTerminateListener listener)
122     {
123         this.xMSF = xMSF;
124 
125         XDesktop xDesktop = Desktop.getDesktop(xMSF);
126         XFramesSupplier xFrameSupplier = UnoRuntime.queryInterface(XFramesSupplier.class, xDesktop);
127         xFrame = xFrameSupplier.getActiveFrame();
128         xComponent = UnoRuntime.queryInterface(XComponent.class, xFrame.getController().getModel());
129         xTextDocument = UnoRuntime.queryInterface(XTextDocument.class, xComponent);
130 
131         if (bShowStatusIndicator)
132         {
133             showStatusIndicator();
134         }
135         init();
136     }
137 
138     public static class ModuleIdentifier
139     {
140 
141         private String m_identifier;
142 
getIdentifier()143         protected final String getIdentifier()
144         {
145             return m_identifier;
146         }
147 
ModuleIdentifier(String _identifier)148         public ModuleIdentifier(String _identifier)
149         {
150             m_identifier = _identifier;
151         }
152     }
153 
154     // creates an instance of TextDocument containing a blank text document
TextDocument(XMultiServiceFactory xMSF, ModuleIdentifier _moduleIdentifier, boolean bShowStatusIndicator)155     public TextDocument(XMultiServiceFactory xMSF, ModuleIdentifier _moduleIdentifier, boolean bShowStatusIndicator)
156     {
157         this.xMSF = xMSF;
158 
159         try
160         {
161             // create the empty document, and set its module identifier
162             xTextDocument = UnoRuntime.queryInterface(XTextDocument.class,
163                     xMSF.createInstance("com.sun.star.text.TextDocument"));
164 
165             XLoadable xLoadable = UnoRuntime.queryInterface(XLoadable.class, xTextDocument);
166             xLoadable.initNew();
167 
168             XModule xModule = UnoRuntime.queryInterface(XModule.class,
169                     xTextDocument);
170             xModule.setIdentifier(_moduleIdentifier.getIdentifier());
171 
172             // load the document into a blank frame
173             XDesktop xDesktop = Desktop.getDesktop(xMSF);
174             XComponentLoader xLoader = UnoRuntime.queryInterface(XComponentLoader.class, xDesktop);
175             PropertyValue[] loadArgs = new PropertyValue[]
176             {
177                 new PropertyValue("Model", -1, xTextDocument, com.sun.star.beans.PropertyState.DIRECT_VALUE)
178             };
179             xLoader.loadComponentFromURL("private:object", "_blank", 0, loadArgs);
180 
181             // remember some things for later usage
182             xFrame = xTextDocument.getCurrentController().getFrame();
183             xComponent = UnoRuntime.queryInterface(XComponent.class, xTextDocument);
184         }
185         catch (Exception e)
186         {
187             // TODO: it seems the whole project does not really have an error handling. Other menthods
188             // seem to generally silence errors, so we can't do anything else here ...
189         }
190 
191         if (bShowStatusIndicator)
192         {
193             showStatusIndicator();
194         }
195         init();
196     }
197 
198     //creates an instance of TextDocument from a given XTextDocument
TextDocument(XMultiServiceFactory xMSF, XTextDocument _textDocument, boolean bshowStatusIndicator)199     public TextDocument(XMultiServiceFactory xMSF, XTextDocument _textDocument, boolean bshowStatusIndicator)
200     {
201         this.xMSF = xMSF;
202         xFrame = _textDocument.getCurrentController().getFrame();
203         xComponent = UnoRuntime.queryInterface(XComponent.class, _textDocument);
204         xTextDocument = UnoRuntime.queryInterface(XTextDocument.class, xComponent);
205         //PosSize = xFrame.getComponentWindow().getPosSize();
206         if (bshowStatusIndicator)
207         {
208             XStatusIndicatorFactory xStatusIndicatorFactory = UnoRuntime.queryInterface(XStatusIndicatorFactory.class, xFrame);
209             xProgressBar = xStatusIndicatorFactory.createStatusIndicator();
210             xProgressBar.start(PropertyNames.EMPTY_STRING, 100);
211             xProgressBar.setValue(5);
212         }
213         xWindowPeer = UnoRuntime.queryInterface(XWindowPeer.class, xFrame.getComponentWindow());
214         xMSFDoc = UnoRuntime.queryInterface(XMultiServiceFactory.class, xTextDocument);
215         xNumberFormatsSupplier = UnoRuntime.queryInterface(XNumberFormatsSupplier.class, xTextDocument);
216 
217         XDocumentPropertiesSupplier xDocPropsSuppl = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xTextDocument);
218         m_xDocProps = xDocPropsSuppl.getDocumentProperties();
219         CharLocale = (Locale) Helper.getUnoStructValue((Object) xComponent, "CharLocale");
220         xText = xTextDocument.getText();
221     }
222 
init()223     private void init()
224     {
225         xWindowPeer = UnoRuntime.queryInterface(XWindowPeer.class, xFrame.getComponentWindow());
226         xMSFDoc = UnoRuntime.queryInterface(XMultiServiceFactory.class, xTextDocument);
227         xNumberFormatsSupplier = UnoRuntime.queryInterface(XNumberFormatsSupplier.class, xTextDocument);
228         XDocumentPropertiesSupplier xDocPropsSuppl = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xTextDocument);
229         m_xDocProps = xDocPropsSuppl.getDocumentProperties();
230         CharLocale = (Locale) Helper.getUnoStructValue((Object) xComponent, "CharLocale");
231         xStorable = UnoRuntime.queryInterface(XStorable.class, xTextDocument);
232         xText = xTextDocument.getText();
233     }
234 
showStatusIndicator()235     private void showStatusIndicator()
236     {
237         XStatusIndicatorFactory xStatusIndicatorFactory = UnoRuntime.queryInterface(XStatusIndicatorFactory.class, xFrame);
238         xProgressBar = xStatusIndicatorFactory.createStatusIndicator();
239         xProgressBar.start(PropertyNames.EMPTY_STRING, 100);
240         xProgressBar.setValue(5);
241     }
242 
loadAsPreview(String sDefaultTemplate, boolean asTemplate)243     public XTextDocument loadAsPreview(String sDefaultTemplate, boolean asTemplate)
244     {
245         PropertyValue loadValues[] = new PropertyValue[3];
246         //      open document in the Preview mode
247         loadValues[0] = new PropertyValue();
248         loadValues[0].Name = PropertyNames.READ_ONLY;
249         loadValues[0].Value = Boolean.TRUE;
250         loadValues[1] = new PropertyValue();
251         loadValues[1].Name = "AsTemplate";
252         loadValues[1].Value = asTemplate ? Boolean.TRUE : Boolean.FALSE;
253         loadValues[2] = new PropertyValue();
254         loadValues[2].Name = "Preview";
255         loadValues[2].Value = Boolean.TRUE;
256 
257         //set the preview document to non-modified mode in order to avoid the 'do u want to save' box
258         if (xTextDocument != null)
259         {
260             try
261             {
262                 XModifiable xModi = UnoRuntime.queryInterface(XModifiable.class, xTextDocument);
263                 xModi.setModified(false);
264             }
265             catch (PropertyVetoException e1)
266             {
267                 e1.printStackTrace(System.out);
268             }
269         }
270         Object oDoc = OfficeDocument.load(xFrame, sDefaultTemplate, "_self", loadValues);
271         xTextDocument = (com.sun.star.text.XTextDocument) oDoc;
272         DocSize = getPageSize();
273         xMSFDoc = UnoRuntime.queryInterface(XMultiServiceFactory.class, xTextDocument);
274 
275         ViewHandler myViewHandler = new ViewHandler(xMSFDoc, xTextDocument);
276         try
277         {
278             myViewHandler.setViewSetting("ZoomType", new Short(com.sun.star.view.DocumentZoomType.ENTIRE_PAGE));
279         }
280         catch (Exception e)
281         {
282             e.printStackTrace();
283         }
284 
285         TextFieldHandler myFieldHandler = new TextFieldHandler(xMSF, xTextDocument);
286         myFieldHandler.updateDocInfoFields();
287 
288         return xTextDocument;
289 
290     }
291 
getPageSize()292     public Size getPageSize()
293     {
294         try
295         {
296             XStyleFamiliesSupplier xStyleFamiliesSupplier = UnoRuntime.queryInterface(XStyleFamiliesSupplier.class, xTextDocument);
297             com.sun.star.container.XNameAccess xNameAccess = null;
298             xNameAccess = xStyleFamiliesSupplier.getStyleFamilies();
299             com.sun.star.container.XNameContainer xPageStyleCollection = null;
300             xPageStyleCollection = UnoRuntime.queryInterface(com.sun.star.container.XNameContainer.class, xNameAccess.getByName("PageStyles"));
301             XStyle xPageStyle = UnoRuntime.queryInterface(XStyle.class, xPageStyleCollection.getByName("First Page"));
302             return (Size) Helper.getUnoPropertyValue(xPageStyle, "Size");
303 
304         }
305         catch (Exception exception)
306         {
307             exception.printStackTrace(System.out);
308             return null;
309         }
310     }
311 
312     //creates an instance of TextDocument and creates a frame and loads a document
TextDocument(XMultiServiceFactory xMSF, String URL, PropertyValue[] xArgs, XTerminateListener listener)313     public TextDocument(XMultiServiceFactory xMSF, String URL, PropertyValue[] xArgs, XTerminateListener listener)
314     {
315         this.xMSF = xMSF;
316         XDesktop xDesktop = Desktop.getDesktop(xMSF);
317 
318         xFrame = OfficeDocument.createNewFrame(xMSF, listener);
319         Object oDoc = OfficeDocument.load(xFrame, URL, "_self", xArgs);
320         xTextDocument = (XTextDocument) oDoc;
321         xComponent = UnoRuntime.queryInterface(XComponent.class, xTextDocument);
322         XWindow xWindow = xFrame.getComponentWindow();
323 
324         xWindowPeer = UnoRuntime.queryInterface(XWindowPeer.class, xFrame.getComponentWindow());
325         xMSFDoc = UnoRuntime.queryInterface(XMultiServiceFactory.class, xTextDocument);
326         xNumberFormatsSupplier = UnoRuntime.queryInterface(XNumberFormatsSupplier.class, xTextDocument);
327 
328         XDocumentPropertiesSupplier xDocPropsSuppl = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xTextDocument);
329         m_xDocProps = xDocPropsSuppl.getDocumentProperties();
330         CharLocale = (Locale) Helper.getUnoStructValue((Object) xComponent, "CharLocale");
331     }
332 
createTextCursor(Object oCursorContainer)333     public static XTextCursor createTextCursor(Object oCursorContainer)
334     {
335         XSimpleText xText = UnoRuntime.queryInterface(XSimpleText.class, oCursorContainer);
336         return xText.createTextCursor();
337     }
338 
339     // Todo: This method is  unsecure because the last index is not necessarily the last section
340 
341     // Todo: This Routine should be  modified, because I cannot rely on the last Table in the document to be the last in the TextTables sequence
342     // to make it really safe you must acquire the Tablenames before the insertion and after the insertion of the new Table. By comparing the
343     // two sequences of tablenames you can find out the tablename of the last inserted Table
344 
345     // Todo: This method is  unsecure because the last index is not necessarily the last section
getCharWidth(String ScaleString)346     public int getCharWidth(String ScaleString)
347     {
348         int iScale = 200;
349         xTextDocument.lockControllers();
350         int iScaleLen = ScaleString.length();
351         com.sun.star.text.XTextCursor xTextCursor = createTextCursor(xTextDocument.getText());
352         xTextCursor.gotoStart(false);
353         com.sun.star.wizards.common.Helper.setUnoPropertyValue(xTextCursor, "PageDescName", "First Page");
354         xTextCursor.setString(ScaleString);
355         XTextViewCursorSupplier xViewCursor = UnoRuntime.queryInterface(XTextViewCursorSupplier.class, xTextDocument.getCurrentController());
356         XTextViewCursor xTextViewCursor = xViewCursor.getViewCursor();
357         xTextViewCursor.gotoStart(false);
358         int iFirstPos = xTextViewCursor.getPosition().X;
359         xTextViewCursor.gotoEnd(false);
360         int iLastPos = xTextViewCursor.getPosition().X;
361         iScale = (iLastPos - iFirstPos) / iScaleLen;
362         xTextCursor.gotoStart(false);
363         xTextCursor.gotoEnd(true);
364         xTextCursor.setString(PropertyNames.EMPTY_STRING);
365         unlockallControllers();
366         return iScale;
367     }
368 
unlockallControllers()369     public void unlockallControllers()
370     {
371         while (xTextDocument.hasControllersLocked())
372         {
373             xTextDocument.unlockControllers();
374         }
375     }
376 
refresh()377     public void refresh()
378     {
379         XRefreshable xRefreshable = UnoRuntime.queryInterface(XRefreshable.class, xTextDocument);
380         xRefreshable.refresh();
381     }
382 
383     /**
384      * This method sets the Author of a Wizard-generated template correctly
385      * and adds a explanatory sentence to the template description.
386      * @param WizardName The name of the Wizard.
387      * @param TemplateDescription The old Description which is being appended with another sentence.
388      * @return void.
389      */
setWizardTemplateDocInfo(String WizardName, String TemplateDescription)390     public void setWizardTemplateDocInfo(String WizardName, String TemplateDescription)
391     {
392         try
393         {
394             Object uD = Configuration.getConfigurationRoot(xMSF, "/org.openoffice.UserProfile/Data", false);
395             XNameAccess xNA = UnoRuntime.queryInterface(XNameAccess.class, uD);
396             Object gn = xNA.getByName("givenname");
397             Object sn = xNA.getByName("sn");
398             String fullname = gn + PropertyNames.SPACE + sn;
399 
400             Calendar cal = new GregorianCalendar();
401             int year = cal.get(Calendar.YEAR);
402             int month = cal.get(Calendar.MONTH);
403             int day = cal.get(Calendar.DAY_OF_MONTH);
404             DateTime currentDate = new DateTime();
405             currentDate.Day = (short) day;
406             currentDate.Month = (short) month;
407             currentDate.Year = (short) year;
408             DateUtils du = new DateUtils(xMSF, this.xTextDocument);
409             int ff = du.getFormat(NumberFormatIndex.DATE_SYS_DDMMYY);
410             String myDate = du.format(ff, currentDate);
411 
412             XDocumentPropertiesSupplier xDocPropsSuppl = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xTextDocument);
413             XDocumentProperties xDocProps2 = xDocPropsSuppl.getDocumentProperties();
414             xDocProps2.setAuthor(fullname);
415             xDocProps2.setModifiedBy(fullname);
416             String description = xDocProps2.getDescription();
417             description = description + PropertyNames.SPACE + TemplateDescription;
418             description = JavaTools.replaceSubString(description, WizardName, "<wizard_name>");
419             description = JavaTools.replaceSubString(description, myDate, "<current_date>");
420             xDocProps2.setDescription(description);
421         }
422         catch (NoSuchElementException e)
423         {
424             // TODO Auto-generated catch block
425             e.printStackTrace();
426         }
427         catch (WrappedTargetException e)
428         {
429             // TODO Auto-generated catch block
430             e.printStackTrace();
431         }
432         catch (Exception e)
433         {
434             // TODO Auto-generated catch block
435             e.printStackTrace();
436         }
437     }
438 
439     /**
440      * removes an arbitrary Object which supports the  'XTextContent' interface
441      * @param oTextContent
442      * @return
443      */
removeTextContent(Object oTextContent)444     public boolean removeTextContent(Object oTextContent)
445     {
446         try
447         {
448             XTextContent xTextContent = UnoRuntime.queryInterface(XTextContent.class, oTextContent);
449             xText.removeTextContent(xTextContent);
450             return true;
451         }
452         catch (NoSuchElementException e)
453         {
454             e.printStackTrace(System.out);
455             return false;
456         }
457     }
458 
459     /**
460      * Apparently there is no other way to get the
461      * page count of a text document other than using a cursor and
462      * making it jump to the last page...
463      * @param model the document model.
464      * @return the page count of the document.
465      */
getPageCount(Object model)466     public static int getPageCount(Object model)
467     {
468         XModel xModel = UnoRuntime.queryInterface(XModel.class, model);
469         XController xController = xModel.getCurrentController();
470         XTextViewCursorSupplier xTextVCS = UnoRuntime.queryInterface(XTextViewCursorSupplier.class, xController);
471         XTextViewCursor xTextVC = xTextVCS.getViewCursor();
472         XPageCursor xPC = UnoRuntime.queryInterface(XPageCursor.class, xTextVC);
473         xPC.jumpToLastPage();
474         return xPC.getPage();
475     }
476 
477     /* Possible Values for "OptionString" are: "LoadCellStyles", "LoadTextStyles", "LoadFrameStyles",
478     "LoadPageStyles", "LoadNumberingStyles", "OverwriteStyles" */
479 }
480