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.reportbuilder.layout;
24 
25 import com.sun.star.awt.FontDescriptor;
26 import com.sun.star.awt.Rectangle;
27 import com.sun.star.awt.Size;
28 import com.sun.star.awt.XControl;
29 import com.sun.star.awt.XControlModel;
30 import com.sun.star.awt.XLayoutConstrains;
31 import com.sun.star.awt.XUnitConversion;
32 import com.sun.star.awt.XWindow;
33 import com.sun.star.awt.XWindowPeer;
34 import com.sun.star.beans.Property;
35 import com.sun.star.beans.PropertyAttribute;
36 import com.sun.star.beans.XPropertySet;
37 import com.sun.star.beans.XPropertySetInfo;
38 import com.sun.star.container.XEnumeration;
39 import com.sun.star.container.XNameAccess;
40 import com.sun.star.lang.XComponent;
41 import com.sun.star.lang.XMultiServiceFactory;
42 import com.sun.star.report.XFixedLine;
43 import com.sun.star.report.XFixedText;
44 import com.sun.star.report.XFormattedField;
45 import com.sun.star.report.XGroup;
46 import com.sun.star.report.XGroups;
47 import com.sun.star.report.XImageControl;
48 import com.sun.star.report.XReportComponent;
49 import com.sun.star.report.XReportControlModel;
50 import com.sun.star.report.XReportDefinition;
51 import com.sun.star.report.XSection;
52 import com.sun.star.drawing.XShape;
53 import com.sun.star.sdbc.DataType;
54 import com.sun.star.style.XStyle;
55 import com.sun.star.uno.UnoRuntime;
56 import com.sun.star.util.XNumberFormatTypes;
57 import com.sun.star.util.XNumberFormats;
58 import com.sun.star.util.XNumberFormatsSupplier;
59 import com.sun.star.wizards.common.Configuration;
60 import com.sun.star.wizards.common.FileAccess;
61 import com.sun.star.wizards.common.Helper;
62 import com.sun.star.wizards.common.PropertyNames;
63 import com.sun.star.wizards.common.PropertySetHelper;
64 import com.sun.star.wizards.common.Resource;
65 import com.sun.star.wizards.report.IReportBuilderLayouter;
66 import com.sun.star.wizards.report.IReportDefinitionReadAccess;
67 import com.sun.star.wizards.ui.UIConsts;
68 import java.util.HashMap;
69 import java.util.Locale;
70 import java.util.logging.Level;
71 import java.util.logging.Logger;
72 
73 /**
74  * This class is abstract and more like a helper for create different layouts for Report Builder Wizard.
75  * @author ll93751
76  */// TODO: let a little bit place between 2 formatted fields
77 // TODO: move all sectionobjects which have a connect to the right max page width to left if there is a orientation change.
78 abstract public class ReportBuilderLayouter implements IReportBuilderLayouter
79 {
80 
81     private IReportDefinitionReadAccess m_xReportDefinitionReadAccess;
82     private Resource m_aResource;
83     private String[][] m_aSortNames;
84 
85     /**
86      * dispose the ReportBuilderLayouter
87      */
dispose()88     public void dispose()
89     {
90         closeDesignTemplate();
91         m_xReportDefinitionReadAccess = null;
92         // m_xReportBuilderLayouter = null;
93     }
94 
95     /**
96      * The Constructor is protected, this is a abstract class, use Tabular or other to create an instance.
97      * @param _xDefinitionAccess
98      * @param _aResource
99      */
ReportBuilderLayouter(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource)100     protected ReportBuilderLayouter(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource)
101     {
102         m_xReportDefinitionReadAccess = _xDefinitionAccess;
103         m_aResource = _aResource;
104     }
105 
106     /**
107      * Access to the current ReportDefinition
108      * @return the ReportDefinition
109      */
getReportDefinition()110     public XReportDefinition getReportDefinition()
111     {
112         // we have to ask our parent for this value
113         return m_xReportDefinitionReadAccess.getReportDefinition();
114     }
115 
116     /**
117      * Access to the global MultiServiceFactory
118      * @return the global Service Factory
119      */
getGlobalMSF()120     private XMultiServiceFactory getGlobalMSF()
121     {
122         return m_xReportDefinitionReadAccess.getGlobalMSF();
123     }
124 
125     /**
126      * Layout the complete report new, by all information we know until this time.
127      *
128      * If there are some information less, it is no problem for this function, they will be leaved out.
129      * It is possible to call this function after every change, but be careful, could take a little bit longer.
130      */
layout()131     public synchronized void layout()
132     {
133         try
134         {
135             // we bring the clear and insert methods together, this should be a little bit smoother
136             clearReportHeader();
137             insertReportHeader();
138 
139             clearReportFooter();
140             insertReportFooter();
141 
142             clearPageHeader();
143             insertPageHeader();
144 
145             clearPageFooter();
146             insertPageFooter();
147 
148             clearGroups();
149             int lastGroupPostion = insertGroups();
150 
151             clearDetails();
152             // clearFieldTitles();
153             insertDetailFieldTitles(lastGroupPostion);
154             insertDetailFields();
155         }
156         catch (java.lang.ArrayIndexOutOfBoundsException e)
157         {
158             // could happen, if you change the count of values
159         }
160         catch (java.lang.RuntimeException e)
161         {
162             throw e;
163         }
164         catch (Exception ex)
165         {
166             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
167         }
168     }
169     // -------------------------------------------------------------------------
170 
171     /**
172      * Remove all Groups
173      */
clearGroups()174     protected void clearGroups()
175     {
176         final XGroups xGroups = getReportDefinition().getGroups();
177 //        int nCount = xGroups.getCount();
178         while (xGroups.hasElements())
179         {
180             try
181             {
182                 xGroups.removeByIndex(0);
183             }
184             catch (com.sun.star.uno.Exception ex)
185             {
186                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
187             }
188         }
189     }
190     // -------------------------------------------------------------------------
191 
192     /**
193      * Remove all fields
194      * @param _xSectionToClear
195      */
emptySection(XSection _xSectionToClear)196     private void emptySection(XSection _xSectionToClear)
197     {
198         if (_xSectionToClear == null)
199         {
200             return;
201         }
202         //      int nCount = _xSectionToClear.getCount();
203         while (_xSectionToClear.hasElements())
204         {
205             try
206             {
207                 final Object aObj = _xSectionToClear.getByIndex(0);
208                 final XShape aShape = UnoRuntime.queryInterface(XShape.class, aObj);
209                 _xSectionToClear.remove(aShape);
210             }
211             catch (com.sun.star.uno.Exception ex)
212             {
213                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
214             }
215 
216         }
217     }
218 
clearDetails()219     private void clearDetails()
220     {
221         final XSection xSection = getReportDefinition().getDetail();
222         emptySection(xSection);
223     }
224 //    public void clearFieldTitles()
225 //    {
226 //    }
227 
228     /**
229      *
230      * @param _nGroupCount
231      * @return the left indent in 1/100mm
232      */
getLeftGroupIndent(int _nGroupCount)233     protected int getLeftGroupIndent(int _nGroupCount)
234     {
235 // TODO: Fix values for group indent (1/2cm) only the first 2 groups
236         int nIndent = 0;
237         final int MAX_INDENT = 2;
238         if (_nGroupCount <= MAX_INDENT)
239         {
240             nIndent = _nGroupCount * LayoutConstants.IndentFactorWidth;
241         }
242         else
243         {
244             nIndent = MAX_INDENT * LayoutConstants.IndentFactorWidth;
245         }
246         return nIndent;
247     }
248     /**
249      * Get left page indent.
250      * The left indent is the area on the left side which will no be printed.
251      * The default is 2000 1/100mm what is 2cm of DIN A4.
252      * @return the left indent in 1/100mm
253      */
254     int m_nLeftIndent = -1;
255 
getLeftPageIndent()256     protected int getLeftPageIndent()
257     {
258         if (m_nLeftIndent < 0)
259         {
260             m_nLeftIndent = getFromPageStyles("LeftMargin", 2000);
261         }
262         return m_nLeftIndent;
263     }
264     /**
265      * Get right page indent.
266      * The right indent is the area on the right side which will no be printed.
267      * The default is 2000 1/100mm what is 2cm of DIN A4.
268      * @return the right indent in 1/100mm
269      */
270     int m_nRightIndent = -1;
271 
getRightPageIndent()272     protected int getRightPageIndent()
273     {
274         if (m_nRightIndent < 0)
275         {
276             m_nRightIndent = getFromPageStyles("RightMargin", 2000);
277         }
278         return m_nRightIndent;
279     }
280 
getUsedStyle(String _sStyleName)281     private XStyle getUsedStyle(String _sStyleName)
282     {
283         XStyle aUsedStyle = null;
284         final XNameAccess xNameAccess = getReportDefinition().getStyleFamilies();
285         try
286         {
287             // <Analysecode>
288             // String[] aNames = xNameAccess.getElementNames();
289             // </Analysecode>
290 
291             // get all Page Styles
292             final Object aPageStylesObj = xNameAccess.getByName(_sStyleName);
293             final XNameAccess xContainer = UnoRuntime.queryInterface(XNameAccess.class, aPageStylesObj);
294 
295             // step over all Page Styles, search the one which is in use
296             final String[] aElementNames = xContainer.getElementNames();
297             for (int i = 0; i < aElementNames.length; i++)
298             {
299                 final String sName = aElementNames[i];
300                 final Object aObj = xContainer.getByName(sName);
301                 final XStyle xStyle = UnoRuntime.queryInterface(XStyle.class, aObj);
302                 if (xStyle.isInUse())
303                 {
304                     aUsedStyle = xStyle;
305                     break;
306                 }
307             }
308         }
309         catch (com.sun.star.uno.Exception ex)
310         {
311             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
312         }
313         return aUsedStyle;
314     }
315 
getFromPageStyles(String _sStyleName, int _nDefault)316     protected int getFromPageStyles(String _sStyleName, int _nDefault)
317     {
318         int nValue = _nDefault;
319         final XStyle xStyle = getUsedStyle("PageStyles");
320         if (xStyle != null)
321         {
322             // we found the page style which is in use
323             final PropertySetHelper aHelper = new PropertySetHelper(xStyle);
324             nValue = aHelper.getPropertyValueAsInteger(_sStyleName, nValue);
325         }
326         return nValue;
327     }
328 
setToPageStyles(String _sStyleName, Object _aObj)329     protected void setToPageStyles(String _sStyleName, Object _aObj)
330     {
331         final XStyle xStyle = getUsedStyle("PageStyles");
332         if (xStyle != null)
333         {
334             final PropertySetHelper aHelper = new PropertySetHelper(xStyle);
335             aHelper.setPropertyValueDontThrow(_sStyleName, _aObj);
336         }
337     }
338     /**
339      * Get page width. The default is 21000 1/100mm what is 21cm of DIN A4.
340      * @return the Width of the page in 1/100mm
341      */
342     int m_nPageWidth = -1;
343 
getPageWidth()344     protected int getPageWidth()
345     {
346         if (m_nPageWidth < 0)
347         {
348             m_nPageWidth = getFromPageStyles(PropertyNames.PROPERTY_WIDTH, 21000);
349         }
350         return m_nPageWidth;
351     }
352     // -------------------------------------------------------------------------
353 
354     /**
355      * Stores the Group names. To insert/create a report with such group names, call layout()
356      * @param _aGroupNames
357      */
insertGroupNames(String[] _aGroupNames)358     public void insertGroupNames(String[] _aGroupNames)
359     {
360         m_aGroupNames = _aGroupNames;
361     }
362 
insertSortingNames(String[][] _aSortFieldNames)363     public void insertSortingNames(String[][] _aSortFieldNames)
364     {
365         m_aSortNames = _aSortFieldNames;
366     }
367 
copyGroupProperties(int _nGroup)368     protected void copyGroupProperties(int _nGroup)
369     {
370         if (getDesignTemplate() != null)
371         {
372             try
373             {
374                 final XGroups xForeignGroups = getDesignTemplate().getGroups();
375                 if (_nGroup < xForeignGroups.getCount())
376                 {
377                     XGroup xForeignGroup = UnoRuntime.queryInterface(XGroup.class, xForeignGroups.getByIndex(_nGroup));
378                     XSection xForeignGroupSection = xForeignGroup.getHeader();
379 
380                     if (xForeignGroupSection != null)
381                     {
382                         final XGroups xGroups = getReportDefinition().getGroups();
383                         Object aGroup = xGroups.getByIndex(_nGroup);
384                         XGroup xGroup = UnoRuntime.queryInterface(XGroup.class, aGroup);
385                         XSection xGroupSection = xGroup.getHeader();
386 
387                         // copy Properties
388                         copyProperties(xForeignGroupSection, xGroupSection);
389                     }
390                 }
391             }
392             catch (Exception ex)
393             {
394                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
395             }
396         }
397     }
398     // -------------------------------------------------------------------------
399 
insertGroups()400     protected int insertGroups()
401     {
402         final XGroups xGroups = getReportDefinition().getGroups();
403         int lastGroupPosition = -1;
404 
405         if (m_aGroupNames != null)
406         {
407             final int nLeftPageIndent = getLeftPageIndent();
408             final int nLabelWidth = getMaxLabelWidth(); // 3000;
409             final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - getLeftGroupIndent(getCountOfGroups());
410             final int nFieldWidth = nUsablePageWidth - nLabelWidth;
411 
412             XGroup aLastGroup = null;
413             // after done with all groups, we need access to the last group, for set property 'KeepTogether' so we remember it.
414 
415             for (int i = 0; i < m_aGroupNames.length; i++)
416             {
417                 lastGroupPosition = i;
418                 final XGroup xGroup = xGroups.createGroup();
419                 aLastGroup = xGroup;
420 
421                 xGroup.setExpression(m_aGroupNames[i]);
422                 xGroup.setHeaderOn(true);
423 
424                 try
425                 {
426                     int nCount = xGroups.getCount();
427                     xGroups.insertByIndex(nCount, xGroup);
428                     final XSection xGroupSection = xGroup.getHeader();
429                     copyGroupProperties(nCount);
430 
431                     Rectangle aRect = new Rectangle();
432                     aRect.X = nLeftPageIndent + getLeftGroupIndent(i);
433                     SectionObject aSO = getDesignTemplate().getGroupLabel(i);
434                     aRect = insertLabel(xGroupSection, getTitleFromFieldName(m_aGroupNames[i]), aRect, nLabelWidth, aSO);
435                     final String sGroupName = convertToFieldName(m_aGroupNames[i]);
436                     aSO = getDesignTemplate().getGroupTextField(i);
437                     aRect = insertFormattedField(xGroupSection, sGroupName, aRect, nFieldWidth, aSO);
438                     int height = aRect.Height;
439 
440                     // draw a line under the label/formattedfield
441                     aRect.X = nLeftPageIndent + getLeftGroupIndent(i);
442                     aRect.Y = aRect.Height;
443                     final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X;
444                     final int nLineHeight = LayoutConstants.LineHeight;
445                     insertHorizontalLine(xGroupSection, aRect, nLineWidth, nLineHeight);
446                     xGroupSection.setHeight(height + nLineHeight);
447                 }
448                 catch (com.sun.star.uno.Exception ex)
449                 {
450                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
451                 }
452             }
453 
454             // hold the inner group together
455             if (aLastGroup != null)
456             {
457                 doNotBreakInTable(aLastGroup);
458             }
459         }
460         if (m_aSortNames != null)
461         {
462             for (String[] sortFieldName : m_aSortNames)
463             {
464                 try
465                 {
466                     final XGroup xGroup = xGroups.createGroup();
467                     xGroup.setExpression(sortFieldName[0]);
468                     xGroup.setSortAscending(PropertyNames.ASC.equals(sortFieldName[1]));
469                     xGroup.setHeaderOn(false);
470                     int nCount = xGroups.getCount();
471                     xGroups.insertByIndex(nCount, xGroup);
472                 }
473                 catch (java.lang.Exception ex)
474                 {
475                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
476                 }
477             }
478         }
479         return lastGroupPosition;
480     }
481 
482     // -------------------------------------------------------------------------
483     /**
484      * Give a list off all field title names to insert the field title names, call layout()
485      * @param _aFieldTitleNames
486      */
insertFieldTitles(String[] _aFieldTitleNames)487     public void insertFieldTitles(String[] _aFieldTitleNames)
488     {
489         m_aFieldTitleNames = _aFieldTitleNames;
490     }
491 
492     // -------------------------------------------------------------------------
getTitleFromFieldName(String _sField)493     protected String getTitleFromFieldName(String _sField)
494     {
495         for (int i = 0; i < m_aFieldNames.length; i++)
496         {
497             if (m_aFieldNames[i].equals(_sField))
498             {
499                 return m_aFieldTitleNames[i];
500             }
501         }
502         return PropertyNames.EMPTY_STRING;
503     }
504 
getTypeFromFieldName(String _sField)505     protected int getTypeFromFieldName(String _sField)
506     {
507         for (int i = 0; i < m_aFieldNames.length; i++)
508         {
509             if (m_aFieldNames[i].equals(_sField))
510             {
511                 return m_aFieldTypes[i];
512             }
513         }
514         return 0;
515     }
516 
listContains(String[] _aList, String _aValue)517     protected boolean listContains(String[] _aList, String _aValue)
518     {
519         for (int i = 0; i < _aList.length; i++)
520         {
521             if (_aList[i].equals(_aValue))
522             {
523                 return true;
524             }
525         }
526         return false;
527     }
528     // -------------------------------------------------------------------------
529 
530     /**
531      * Helper to get all field names without the names which are already in the group names
532      * @param _aList
533      * @param _aGetResultFrom
534      * @return
535      */
getNamesWithoutGroupNames(String[] _aList, String[] _aGetResultFrom)536     protected String[] getNamesWithoutGroupNames(String[] _aList, String[] _aGetResultFrom)
537     {
538         if (_aList == null /* || _aGetResultsFrom == null */)
539         {
540             return new String[]
541                     {
542                     }; /* empty list */
543         }
544         if (getCountOfGroups() == 0)
545         {
546             if (_aGetResultFrom != null)
547             {
548                 return _aGetResultFrom;
549             }
550             return _aList;
551         }
552         final int nNewLength = _aList.length - getCountOfGroups();
553         String[] aNewList = new String[nNewLength];
554         int j = 0;
555         for (int i = 0; i < _aList.length; i++)
556         {
557             final String sField = _aList[i];
558             if (listContains(m_aGroupNames, sField))
559             {
560                 continue;
561             }
562             if (_aGetResultFrom != null)
563             {
564                 aNewList[j++] = _aGetResultFrom[i];
565             }
566             else
567             {
568                 aNewList[j++] = sField;
569             }
570             if (j == nNewLength)
571             {
572                 break; // Emergency break, we leave the result list.
573             }
574         }
575         return aNewList;
576     }
577 
578     // -------------------------------------------------------------------------
calculateFieldWidth(int _nLeftIndent, int _nFieldCount)579     protected int calculateFieldWidth(int _nLeftIndent, int _nFieldCount)
580     {
581         int nWidth = 3000;
582         if (_nFieldCount > 0)
583         {
584             nWidth = (getPageWidth() - getLeftPageIndent() - getRightPageIndent() - _nLeftIndent) / _nFieldCount;
585         }
586         return nWidth;
587     }
588 
getFieldTitleNames()589     protected String[] getFieldTitleNames()
590     {
591         return getNamesWithoutGroupNames(m_aFieldNames, m_aFieldTitleNames);
592     }
593     // -------------------------------------------------------------------------
594 
insertDetailFieldTitles(int lastGroupPostion)595     abstract protected void insertDetailFieldTitles(int lastGroupPostion);
596     // -------------------------------------------------------------------------
597 
598     /**
599      * Give a list off all field names to insert the field names, call layout()
600      * @param _aFieldNames
601      */
insertFieldNames(String[] _aFieldNames)602     public void insertFieldNames(String[] _aFieldNames)
603     {
604         m_aFieldNames = _aFieldNames;
605     }
606 
insertFieldTypes(int[] _aFieldTypes)607     public void insertFieldTypes(int[] _aFieldTypes)
608     {
609         m_aFieldTypes = _aFieldTypes;
610     }
611 
insertFieldWidths(int[] _aFieldWidths)612     public void insertFieldWidths(int[] _aFieldWidths)
613     {
614         m_aFieldWidths = _aFieldWidths;
615     }
616 
getCountOfGroups()617     protected int getCountOfGroups()
618     {
619         return ((m_aGroupNames == null) ? 0 : m_aGroupNames.length);
620     }
621 
622     // -------------------------------------------------------------------------
getFieldNames()623     protected String[] getFieldNames()
624     {
625         return getNamesWithoutGroupNames(m_aFieldNames, null);
626     }
627 
insertDetailFields()628     abstract protected void insertDetailFields();
629 
copyDetailProperties()630     protected void copyDetailProperties()
631     {
632         if (getDesignTemplate() != null)
633         {
634             try
635             {
636                 XSection xForeignSection = getDesignTemplate().getDetail();
637                 if (xForeignSection != null)
638                 {
639                     XSection xSection = getReportDefinition().getDetail();
640 
641                     // copy Properties
642                     copyProperties(xForeignSection, xSection);
643                 }
644             }
645             catch (Exception ex)
646             {
647                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
648             }
649         }
650     }
651     // -------------------------------------------------------------------------
652 
insertLabel(XSection _xSection, String _sLabel, Rectangle _aRect, int _nWidth, SectionObject _aSO)653     protected Rectangle insertLabel(XSection _xSection, String _sLabel, Rectangle _aRect, int _nWidth, SectionObject _aSO)
654     {
655         if (_xSection != null)
656         {
657             try
658             {
659                 final Object aFixedText = getMSFofReportDefinition().createInstance("com.sun.star.report.FixedText");
660                 final XFixedText xFixedText = UnoRuntime.queryInterface(XFixedText.class, aFixedText);
661 
662 
663                 int nHeight = LayoutConstants.LabelHeight;        // default height of label is fixed.
664                 if (_aSO != null)
665                 {
666                     if (_aSO instanceof SectionEmptyObject)
667                     {
668                         float fCharWeight = _aSO.getCharWeight(com.sun.star.awt.FontWeight.NORMAL);
669                         if (fCharWeight > 0.1f)
670                         {
671                             xFixedText.setCharWeight(fCharWeight);
672                         }
673                     }
674                     else
675                     {
676 // TODO: there seems to be some problems with copy all properties from the design template to the current design
677                         final FontDescriptor aFD = _aSO.getFontDescriptor();
678                         if (aFD != null)
679                         {
680                             xFixedText.setFontDescriptor(aFD);
681                             copyProperties(_aSO.getParent(), xFixedText);
682                         }
683                         nHeight = _aSO.getHeight(LayoutConstants.LabelHeight);
684                     }
685                 }
686                 xFixedText.setLabel(_sLabel);
687 
688                 xFixedText.setPositionX(_aRect.X);
689                 xFixedText.setPositionY(_aRect.Y);
690 
691                 // Width will calculate from outside.
692                 // We have to set, because there exist no right default (0)
693                 xFixedText.setWidth(_nWidth);
694                 _aRect.X += _nWidth;
695                 xFixedText.setHeight(nHeight);
696                 _xSection.add(xFixedText);
697             }
698             catch (com.sun.star.uno.Exception ex)
699             {
700                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
701             }
702         }
703         return _aRect;
704     }
705     // -------------------------------------------------------------------------
706 
convertToFieldName(String _sElementName)707     protected String convertToFieldName(String _sElementName)
708     {
709         final StringBuffer aDataField = new StringBuffer(32);
710         aDataField.append("field:[").append(_sElementName).append(']');
711         return aDataField.toString();
712 
713     }
714 
convertFromFieldName(String _sName)715     protected String convertFromFieldName(String _sName)
716     {
717         if (_sName.startsWith("field:["))
718         {
719             int nCloseBrace = _sName.lastIndexOf("]");
720             return _sName.substring(7, nCloseBrace).trim();
721         }
722         return _sName;
723     }
724     // -------------------------------------------------------------------------
725 
726     /**
727      * Insert a already formatted field name into a given section
728      *
729      * Use 'convertToFieldName(dbfield)' to convert a dbfield name in the right.
730      *
731      * @param _xSection        in which section the formatted field will store
732      * @param _sFormattedfield as String a dbfield or an other function
733      * @param _aRect           .X, .Y are the absolute position (1/100mm) where the formatted field will set
734      * @param _nWidth          the width of the field in 1/100mm
735      * @param _aSO
736      * @return a new Rectangle with the new Rect.X position, Rect.Y will not change.
737      */
insertFormattedField(XSection _xSection, String _sFormattedfield, Rectangle _aRect, int _nWidth, SectionObject _aSO)738     protected Rectangle insertFormattedField(XSection _xSection, String _sFormattedfield, Rectangle _aRect, int _nWidth, SectionObject _aSO)
739     {
740         return insertFormattedField(_xSection, _sFormattedfield, _aRect, _nWidth, _aSO, (short) com.sun.star.awt.TextAlign.LEFT);
741     }
742 
insertFormattedField(XSection _xSection, String _sFormattedfield, Rectangle _aRect, int _nWidth, SectionObject _aSO, short _nAlignment)743     protected Rectangle insertFormattedField(XSection _xSection, String _sFormattedfield, Rectangle _aRect, int _nWidth, SectionObject _aSO, short _nAlignment)
744     {
745         if (_xSection != null)
746         {
747             try
748             {
749                 Object aField;
750                 int nHeight = LayoutConstants.FormattedFieldHeight;
751 
752                 int nType = getTypeFromFieldName(convertFromFieldName(_sFormattedfield));
753                 if (nType == DataType.BINARY
754                         || nType == DataType.VARBINARY
755                         || nType == DataType.LONGVARBINARY)
756                 {
757                     aField = getMSFofReportDefinition().createInstance("com.sun.star.report.ImageControl");
758                     nHeight = LayoutConstants.BinaryHeight;
759                 }
760                 else
761                 {
762                     aField = getMSFofReportDefinition().createInstance("com.sun.star.report.FormattedField");
763                     nHeight = LayoutConstants.FormattedFieldHeight;
764                     if (nType == DataType.LONGVARCHAR) /* memo */
765 
766                     {
767                         nHeight = LayoutConstants.MemoFieldHeight; // special case for memo
768                     }
769                 }
770                 _aRect.Height = nHeight;
771 
772                 final XReportControlModel xReportControlModel = UnoRuntime.queryInterface(XReportControlModel.class, aField);
773                 if (xReportControlModel != null)
774                 {
775                     // #i86907# not documented right in idl description.
776                     xReportControlModel.setDataField(_sFormattedfield);
777                     if (_aSO != null)
778                     {
779                         // TODO: there seems to be some problems with copy all properties from the design template to the current design
780                         final FontDescriptor aFD = _aSO.getFontDescriptor();
781                         if (aFD != null)
782                         {
783                             xReportControlModel.setFontDescriptor(aFD);
784                             copyProperties(_aSO.getParent(), xReportControlModel);
785                         }
786                         nHeight = _aSO.getHeight(nHeight);
787                     }
788                     xReportControlModel.setPositionX(_aRect.X);
789                     xReportControlModel.setPositionY(_aRect.Y);
790                     xReportControlModel.setWidth(_nWidth);
791                     _aRect.X += _nWidth;
792                     xReportControlModel.setHeight(nHeight);
793 
794                     if (nType == DataType.BINARY
795                             || nType == DataType.VARBINARY
796                             || nType == DataType.LONGVARBINARY)
797                     {
798                         // aField = getMSFofReportDefinition().createInstance("com.sun.star.report.ImageControl");
799                         final XImageControl xImageControl = UnoRuntime.queryInterface(XImageControl.class, xReportControlModel);
800                         if (xImageControl != null)
801                         {
802                             // xImageControl.setScaleImage(true);
803 
804                             xImageControl.setScaleMode(com.sun.star.awt.ImageScaleMode.ISOTROPIC);
805                         }
806                     }
807                     else
808                     {
809                         try
810                         {
811                             xReportControlModel.setParaAdjust(_nAlignment);
812                             // if (nType == DataType.LONGVARCHAR)
813                             // {
814                             //     xReportControlModel.???
815                             // }
816                         }
817                         catch (com.sun.star.beans.UnknownPropertyException ex)
818                         {
819                             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
820                         }
821                     }
822                     // spezial case rpt:now() (default date format)
823                     if (_sFormattedfield.equals("rpt:now()"))
824                     {
825                         final XFormattedField xFormattedField = UnoRuntime.queryInterface(XFormattedField.class, xReportControlModel);
826 
827                         XNumberFormatsSupplier x = xFormattedField.getFormatsSupplier();
828                         XNumberFormats xFormats = x.getNumberFormats();
829                         XNumberFormatTypes x3 = UnoRuntime.queryInterface(XNumberFormatTypes.class, xFormats);
830                         Locale.getDefault();
831                         com.sun.star.lang.Locale aLocale = new com.sun.star.lang.Locale();
832                         aLocale.Country = Locale.getDefault().getCountry();
833                         aLocale.Language = Locale.getDefault().getLanguage();
834 
835                         int nFormat = x3.getStandardFormat(com.sun.star.util.NumberFormat.DATE, aLocale);
836                         xFormattedField.setFormatKey(nFormat);
837                     }
838                     _xSection.add(xReportControlModel);
839                 }
840             }
841             catch (com.sun.star.uno.Exception ex)
842             {
843                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
844             }
845         }
846         return _aRect;
847     }
848 
849     // -------------------------------------------------------------------------
850 // TODO: check with Query, this code will not work with Queries
setTableName(int _aType, String _sTableName)851     public void setTableName(int _aType, String _sTableName)
852     {
853         m_aCommandType = _aType;
854         m_sTableName = _sTableName;
855 
856         // getReportDefinition().setCommandType(com.sun.star.sdb.CommandType.TABLE);
857         getReportDefinition().setCommandType(_aType);
858         getReportDefinition().setCommand(_sTableName);
859     }    // -------------------------------------------------------------------------
860     protected XMultiServiceFactory m_xMSF;
861 
getMSFofReportDefinition()862     protected XMultiServiceFactory getMSFofReportDefinition()
863     {
864         if (m_xMSF == null)
865         {
866             m_xMSF = UnoRuntime.queryInterface(XMultiServiceFactory.class, getReportDefinition());
867         }
868         return m_xMSF;
869     }
870     // -------------------------------------------------------------------------
871 
insertVerticalLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight)872     protected Rectangle insertVerticalLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight)
873     {
874         return insertLine(_xSection, _aRect, _nWidth, _nHeight, 1);
875     }
876 
insertHorizontalLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight)877     protected Rectangle insertHorizontalLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight)
878     {
879         return insertLine(_xSection, _aRect, _nWidth, _nHeight, 0);
880     }
881 
insertLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight, int _nOrientation)882     protected Rectangle insertLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight, int _nOrientation)
883     {
884         if (_xSection != null)
885         {
886             try
887             {
888                 final Object aFixedLine = getMSFofReportDefinition().createInstance("com.sun.star.report.FixedLine");
889                 final XFixedLine xFixedLine = UnoRuntime.queryInterface(XFixedLine.class, aFixedLine);
890 
891                 xFixedLine.setOrientation(_nOrientation);
892                 // TODO: line width is fixed
893                 xFixedLine.setLineWidth(8);
894 
895                 xFixedLine.setPositionX(_aRect.X);
896                 xFixedLine.setPositionY(_aRect.Y);
897 
898                 xFixedLine.setWidth(_nWidth);
899                 _aRect.X += _nWidth;
900                 xFixedLine.setHeight(_nHeight);
901                 _xSection.add(xFixedLine);
902             }
903             catch (com.sun.star.uno.Exception ex)
904             {
905                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
906             }
907         }
908         return _aRect;
909     }
910     // -------------------------------------------------------------------------
911 
clearReportHeader()912     protected void clearReportHeader()
913     {
914         XSection xSection;
915         try
916         {
917             if (getReportDefinition().getReportHeaderOn())
918             {
919                 xSection = getReportDefinition().getReportHeader();
920                 emptySection(xSection);
921             }
922         }
923         catch (com.sun.star.container.NoSuchElementException ex)
924         {
925             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex);
926         }
927     }
928 
insertReportHeader()929     protected void insertReportHeader()
930     {
931         if (getDesignTemplate() != null)
932         {
933             if (getDesignTemplate().getReportHeaderOn())
934             {
935                 // copy all Section information from Page Header to our Header
936                 try
937                 {
938                     XSection xForeignSection = getDesignTemplate().getReportHeader();
939 
940                     if (xForeignSection != null)
941                     {
942                         getReportDefinition().setReportHeaderOn(true);
943                         XSection xSection = getReportDefinition().getReportHeader();
944 
945                         // copy Sections
946                         copySection(xForeignSection, xSection);
947                     }
948                 }
949                 catch (Exception e)
950                 {
951                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
952                 }
953             }
954             else
955             {
956                 // we won't a page header
957                 getReportDefinition().setReportHeaderOn(false);
958             }
959         }
960     }
961 
clearReportFooter()962     protected void clearReportFooter()
963     {
964         XSection xSection;
965         try
966         {
967             if (getReportDefinition().getReportFooterOn())
968             {
969                 xSection = getReportDefinition().getReportFooter();
970                 emptySection(xSection);
971             }
972         }
973         catch (com.sun.star.container.NoSuchElementException e)
974         {
975             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
976         }
977     }
978 
insertReportFooter()979     protected void insertReportFooter()
980     {
981         if (getDesignTemplate() != null)
982         {
983             if (getDesignTemplate().getReportFooterOn())
984             {
985                 // copy all Section information from Page Header to our Header
986                 try
987                 {
988                     XSection xForeignSection = getDesignTemplate().getReportFooter();
989 
990                     if (xForeignSection != null)
991                     {
992                         getReportDefinition().setReportFooterOn(true);
993                         XSection xSection = getReportDefinition().getReportFooter();
994 
995                         // copy Sections
996                         copySection(xForeignSection, xSection);
997                     }
998                 }
999                 catch (Exception e)
1000                 {
1001                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1002                 }
1003             }
1004             else
1005             {
1006                 // we won't a page header
1007                 getReportDefinition().setReportFooterOn(false);
1008             }
1009         }
1010     }
1011     // -------------------------------------------------------------------------
1012 
clearPageHeader()1013     protected void clearPageHeader()
1014     {
1015         XSection xSection;
1016         try
1017         {
1018             if (getReportDefinition().getPageHeaderOn())
1019             {
1020                 xSection = getReportDefinition().getPageHeader();
1021                 emptySection(xSection);
1022             }
1023         }
1024         catch (com.sun.star.container.NoSuchElementException e)
1025         {
1026             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1027         }
1028     }
1029 
1030 //    protected static String getDateString(String _sFormat)
1031 //        {
1032 //            GregorianCalendar aCalendar = new GregorianCalendar();
1033 //            StringBuffer aBuf = new StringBuffer();
1034 //
1035 //            Locale aLocale = new Locale("en","US");
1036 //            SimpleDateFormat aFormat = new SimpleDateFormat(_sFormat, aLocale);
1037 //            aBuf = aFormat.format(aCalendar.getTime(), aBuf, new FieldPosition(0) );
1038 //            // DebugHelper.writeInfo("Date: " + aBuf.toString());
1039 //            return aBuf.toString();
1040 //    }
1041 //    protected String getCurrentDate()
1042 //    {
1043 //        Calendar aCalendar = Calendar.getInstance();
1044 ////        aCalendar.setTimeInMillis(1202382900000L);
1045 ////        aCalendar.
1046 //        Date aDate = new Date();
1047 //        String sDate = DateFormat.getDateInstance().format(aDate);
1048 //        // String aCalStr = aCalendar.toString();
1049 //        return sDate;
1050 //        //
1051 ////        Date aDate = new Date();
1052 ////        aDate.setSeconds(0);
1053 ////        aDate.setMinutes(15);
1054 ////        aDate.setHours(12);
1055 ////        // aDate.setMonth(2);
1056 ////        // aDate.setYear(2008);
1057 ////        // aDate.setDay(7);
1058 ////        long nTime = aDate.getTime();
1059 ////        Long aLong = new Long(nTime);
1060 ////        String aStr = aLong.toString();
1061 ////
1062 ////        Date aNewDate = new Date(1202382900000L);
1063 //////         aNewDate.
1064 ////        String aDateStr = aNewDate.toString();
1065 //////         Datetime aNewTime = new Time(1202382900);
1066 //////         String aTimeStr = aNewTime.toString();
1067 ////
1068 //
1069 //    }
clearPageFooter()1070     protected void clearPageFooter()
1071     {
1072         XSection xSection;
1073         try
1074         {
1075             if (getReportDefinition().getPageFooterOn())
1076             {
1077                 xSection = getReportDefinition().getPageFooter();
1078                 emptySection(xSection);
1079             }
1080         }
1081         catch (com.sun.star.container.NoSuchElementException e)
1082         {
1083             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1084         }
1085     }
1086 
setPageOrientation(int _nOrientation)1087     public void setPageOrientation(int _nOrientation)
1088     {
1089         final int nWidth = getFromPageStyles(PropertyNames.PROPERTY_WIDTH, 0);
1090         final int nHeight = getFromPageStyles(PropertyNames.PROPERTY_HEIGHT, 0);
1091 
1092         if (com.sun.star.wizards.report.ReportLayouter.SOOPTLANDSCAPE == _nOrientation)
1093         {
1094             setToPageStyles("IsLandscape", Boolean.TRUE);
1095             if (nWidth < nHeight)
1096             {
1097                 setToPageStyles(PropertyNames.PROPERTY_WIDTH, new Integer(nHeight));
1098                 setToPageStyles(PropertyNames.PROPERTY_HEIGHT, new Integer(nWidth));
1099             }
1100         }
1101         else
1102         {
1103             setToPageStyles("IsLandscape", Boolean.FALSE);
1104             if (nHeight < nWidth)
1105             {
1106                 setToPageStyles(PropertyNames.PROPERTY_WIDTH, new Integer(nHeight));
1107                 setToPageStyles(PropertyNames.PROPERTY_HEIGHT, new Integer(nWidth));
1108             }
1109         }
1110         // dirty the PageWidth
1111         m_nPageWidth = -1;
1112     }
1113 
1114     /**
1115      * Returns the width and height of a given string (_sText) in 1/100mm drawn in the given font descriptor.
1116      * TODO: This function is a performance leak, we could store already calculated values in a map, to build a cache. Access should be much faster then.
1117      *
1118      * @param _sText
1119      * @param _aFont
1120      * @return width of given text in 1/100mm
1121      */
getPreferredSize(String _sText, FontDescriptor _aFont)1122     Size getPreferredSize(String _sText, FontDescriptor _aFont)
1123     {
1124         Size aSizeMM_100TH = new Size(0, 0);
1125         try
1126         {
1127             // Object aControlContainer = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlContainer");
1128             // XControlContainer xControlContainer = (XControlContainer)UnoRuntime.queryInterface(XControlContainer.class, aControlContainer);
1129 
1130             final Object aFixedTextModel = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlFixedTextModel");
1131             final XControlModel xFixedTextModel = UnoRuntime.queryInterface(XControlModel.class, aFixedTextModel);
1132 
1133             final PropertySetHelper aPropertySetHelper = new PropertySetHelper(xFixedTextModel);
1134 //          aPropertySetHelper.showProperties();
1135             aPropertySetHelper.setPropertyValueDontThrow(PropertyNames.FONT_DESCRIPTOR, _aFont);
1136 
1137             final Object aUnoCtrlFixedText = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlFixedText");
1138 //            XServiceInfo xServiceInfo2 = (XServiceInfo)UnoRuntime.queryInterface(XServiceInfo.class, aUnoCtrlFixedText);
1139 //            String[] sServices2 = xServiceInfo2.getSupportedServiceNames();
1140 
1141             final XWindow xWindow = UnoRuntime.queryInterface(XWindow.class, aUnoCtrlFixedText);
1142             xWindow.setVisible(false);
1143 
1144             final XControl xControl = UnoRuntime.queryInterface(XControl.class, aUnoCtrlFixedText);
1145             xControl.setModel(xFixedTextModel);
1146 
1147             final com.sun.star.awt.XFixedText xFixedText = UnoRuntime.queryInterface(com.sun.star.awt.XFixedText.class, aUnoCtrlFixedText);
1148             xFixedText.setText(_sText);
1149 
1150             final XLayoutConstrains xLayoutConstraints = UnoRuntime.queryInterface(XLayoutConstrains.class, aUnoCtrlFixedText);
1151             final Size aSizeInPixel = xLayoutConstraints.getPreferredSize();
1152 
1153             final XWindowPeer xPeerOfReportDefinition = UnoRuntime.queryInterface(XWindowPeer.class, getReportDefinition().getCurrentController().getFrame().getComponentWindow());
1154             xControl.createPeer(null, xPeerOfReportDefinition);
1155 
1156             final XWindowPeer x = xControl.getPeer();
1157 
1158             final XUnitConversion xConversion = UnoRuntime.queryInterface(XUnitConversion.class, x);
1159             aSizeMM_100TH = xConversion.convertSizeToLogic(aSizeInPixel, com.sun.star.util.MeasureUnit.MM_100TH);
1160             // xToolkit.createScreenCompatibleDevice(_nWidth, _nWidth).
1161             // XWindow x = getReportDefinition().getCurrentController().getFrame().getContainerWindow();
1162             // Object aObj = _xSection.getParent();
1163 
1164             // we don't need the created objects any longer
1165             final XComponent xFixedTextDeleter = UnoRuntime.queryInterface(XComponent.class, xFixedText);
1166             xFixedTextDeleter.dispose();
1167 
1168             final XComponent xFixedTextModelDeleter = UnoRuntime.queryInterface(XComponent.class, aFixedTextModel);
1169             xFixedTextModelDeleter.dispose();
1170         }
1171         catch (Exception e)
1172         {
1173             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1174         }
1175         return aSizeMM_100TH;
1176     }
1177 
getTableName()1178     protected String getTableName()
1179     {
1180         if (m_sTableName != null)
1181         {
1182             return m_sTableName;
1183         }
1184         return PropertyNames.EMPTY_STRING;
1185     }
1186 
getUserNameFromConfiguration()1187     protected String getUserNameFromConfiguration()
1188     {
1189         String sFirstName = PropertyNames.EMPTY_STRING;
1190         String sLastName = PropertyNames.EMPTY_STRING;
1191         try
1192         {
1193             Object oProdNameAccess = Configuration.getConfigurationRoot(getGlobalMSF(), "org.openoffice.UserProfile/Data", false);
1194             sFirstName = (String) Helper.getUnoObjectbyName(oProdNameAccess, "givenname");
1195             sLastName = (String) Helper.getUnoObjectbyName(oProdNameAccess, "sn");
1196         }
1197         catch (Exception e)
1198         {
1199             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1200         }
1201         return sFirstName + PropertyNames.SPACE + sLastName;
1202     }
1203 
1204     /**
1205      * Helper function, to copy all not read only properties of _xFromSection to _xToSection
1206      * @param _xFromSection
1207      * @param _xToSection
1208      */
copyProperties(Object _aFrom, Object _aTo)1209     private void copyProperties(Object _aFrom, Object _aTo)
1210     {
1211         XPropertySet xFrom = UnoRuntime.queryInterface(XPropertySet.class, _aFrom);
1212         XPropertySet xTo = UnoRuntime.queryInterface(XPropertySet.class, _aTo);
1213 
1214 
1215         XPropertySetInfo xForeignPropInfo = xFrom.getPropertySetInfo();
1216         XPropertySetInfo xSectionPropInfo = xTo.getPropertySetInfo();
1217         Property[] aAllProperties = xForeignPropInfo.getProperties();
1218         for (int i = 0; i < aAllProperties.length; i++)
1219         {
1220             String sPropertyName = aAllProperties[i].Name;
1221             if (xSectionPropInfo.hasPropertyByName(sPropertyName))
1222             {
1223                 try
1224                 {
1225                     Property aDestProp = xForeignPropInfo.getPropertyByName(sPropertyName);
1226                     if ((aDestProp.Attributes & PropertyAttribute.READONLY) == 0)
1227                     {
1228                         xTo.setPropertyValue(sPropertyName, xFrom.getPropertyValue(sPropertyName));
1229                     }
1230                 }
1231                 catch (Exception e)
1232                 {
1233                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1234                 }
1235             }
1236         }
1237     }
1238 
1239     /**
1240      * Helper Funktion to copy the whole content of _xFromSection to the _xToSection
1241      * @param _xFromSection
1242      * @param _xToSection
1243      */
copySection(XSection _xFromSection, XSection _xToSection)1244     private void copySection(XSection _xFromSection, XSection _xToSection)
1245     {
1246         copyProperties(_xFromSection, _xToSection);
1247 
1248         try
1249         {
1250             XEnumeration xEnum = _xFromSection.createEnumeration();
1251             while (xEnum.hasMoreElements())
1252             {
1253                 Object aEnumObj = xEnum.nextElement();
1254                 XReportComponent aComponent = UnoRuntime.queryInterface(XReportComponent.class, aEnumObj);
1255 
1256                 // XCloneable aClone = (XCloneable)UnoRuntime.queryInterface(XCloneable.class, aEnumObj);
1257                 if (aComponent != null)
1258                 {
1259                     Object aClone = aComponent.createClone();
1260                     if (aClone != null)
1261                     {
1262                         XShape aShape = UnoRuntime.queryInterface(XShape.class, aClone);
1263 
1264                         // normally 'createClone' will create a real clone of the component,
1265                         // but there seems some problems, we have to control.
1266                         copyProperties(aComponent, aClone);
1267 
1268                         // aShape.setPosition(aComponent.getPosition());
1269                         // aShape.setSize(aComponent.getSize());
1270                         _xToSection.add(aShape);
1271                     }
1272                 }
1273             }
1274         }
1275         catch (Exception e)
1276         {
1277             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1278         }
1279         // String sName = xForeignSection.getName();
1280         // int dummy = 0;
1281     }
1282 
insertPageHeader()1283     protected void insertPageHeader()
1284     {
1285         if (getDesignTemplate() != null)
1286         {
1287             if (getDesignTemplate().getPageHeaderOn())
1288             {
1289                 // copy all Section information from Page Header to our Header
1290                 try
1291                 {
1292                     XSection xForeignSection = getDesignTemplate().getPageHeader();
1293 
1294                     if (xForeignSection != null)
1295                     {
1296                         getReportDefinition().setPageHeaderOn(true);
1297                         XSection xSection = getReportDefinition().getPageHeader();
1298 
1299                         // copy Sections
1300                         copySection(xForeignSection, xSection);
1301                     }
1302                 }
1303                 catch (Exception e)
1304                 {
1305                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1306                 }
1307                 }
1308             else
1309             {
1310                 // we won't a page header
1311                 // getReportDefinition().setPageHeaderOn(true);
1312                 getReportDefinition().setPageHeaderOn(false);
1313             }
1314         }
1315         else
1316         {
1317             if (getReportDefinition() == null)
1318             {
1319                 return;
1320             }
1321             // there is no foreign report definition
1322             // TODO: #i86902# rpt:Title() out of the document
1323 
1324             // TODO: #i86902# rpt:Author() can't set with something like rpt:author()
1325             // TODO: #i86902# more fieldnames need.
1326             final String sTitleTitle = getResource().getResText(UIConsts.RID_REPORT + 86); // "Title:"
1327             final String sTitle = getTableName(); // "Default title, this is a first draft report generated by the new report wizard.";
1328             final String sAuthorTitle = getResource().getResText(UIConsts.RID_REPORT + 87); // "Author:"
1329             final String sAuthor = getUserNameFromConfiguration(); // "You";     // rpt:fieldvalue();
1330             final String sDateTitle = getResource().getResText(UIConsts.RID_REPORT + 88); // "Date:"
1331             // TODO: #i86911# Date: we need to set the style of the date.
1332             final String sDate = "rpt:now()"; // getDateString("EEE, d MMM yyyy HH:mm:ss zzzz");
1333 
1334             try
1335             {
1336                 getReportDefinition().setPageHeaderOn(true);
1337                 XSection xSection = null;
1338                 xSection = getReportDefinition().getPageHeader();
1339 
1340                 Rectangle aRect = new Rectangle();
1341                 aRect.X = getLeftPageIndent();
1342                 SectionObject aSOLabel = SectionEmptyObject.create();
1343                 aSOLabel.setFontToBold();
1344                 aRect.Y = aSOLabel.getHeight(LayoutConstants.LabelHeight);
1345 
1346                 final int nWidth = 3000;
1347 
1348                 aRect = insertLabel(xSection, sTitleTitle, aRect, nWidth, aSOLabel);
1349 
1350                 final int nTitleWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - 3000;
1351                 // aRect = insertFormattedField(xSection, "rpt:Title()", aRect, nTitleWidth);
1352                 aRect = insertLabel(xSection, sTitle, aRect, nTitleWidth, aSOLabel);
1353 
1354                 aRect.Y += aSOLabel.getHeight(LayoutConstants.LabelHeight) + LayoutConstants.LineHeight;
1355 
1356                 aRect.X = getLeftPageIndent();
1357                 aRect = insertLabel(xSection, sAuthorTitle, aRect, nWidth, aSOLabel);
1358                 // aRect = insertFormattedField(xSection, "rpt:Author()", aRect, nWidth);
1359                 aRect = insertLabel(xSection, sAuthor, aRect, nTitleWidth, aSOLabel);
1360 
1361                 aRect.Y += aSOLabel.getHeight(LayoutConstants.LabelHeight);
1362 
1363                 aRect.X = getLeftPageIndent();
1364                 aRect = insertLabel(xSection, sDateTitle, aRect, nWidth, aSOLabel);
1365                 // aRect = insertFormattedField(xSection, "rpt:Date()", aRect, nWidth);
1366                 aRect = insertFormattedField(xSection, sDate, aRect, nTitleWidth, aSOLabel);
1367 
1368                 aRect.Y += aSOLabel.getHeight(LayoutConstants.FormattedFieldHeight) + LayoutConstants.LineHeight;
1369 
1370                 // draw a line under the label/formattedfield
1371                 aRect.X = getLeftPageIndent();
1372                 final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X;
1373                 final int nLineHeight = LayoutConstants.LineHeight;
1374                 insertHorizontalLine(xSection, aRect, nLineWidth, nLineHeight);
1375 
1376                 aRect.Y += nLineHeight;
1377 
1378                 xSection.setHeight(aRect.Y);
1379             }
1380             catch (com.sun.star.uno.Exception e)
1381             {
1382                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1383             }
1384         }
1385     }
1386 
insertPageFooter()1387     protected void insertPageFooter()
1388     {
1389         if (getDesignTemplate() != null)
1390         {
1391             if (getDesignTemplate().getPageFooterOn())
1392             {
1393                 try
1394                 {
1395                     XSection xForeignSection = getDesignTemplate().getPageFooter();
1396 
1397                     if (xForeignSection != null)
1398                     {
1399                         getReportDefinition().setPageFooterOn(true);
1400                         XSection xSection = getReportDefinition().getPageFooter();
1401 
1402                         // copy Sections
1403                         copySection(xForeignSection, xSection);
1404                     }
1405                 }
1406                 catch (Exception e)
1407                 {
1408                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1409                 }
1410             }
1411             else
1412             {
1413                 // getReportDefinition().setPageFooterOn(true);
1414                 getReportDefinition().setPageFooterOn(false);
1415             }
1416         }
1417         else
1418         {
1419             if (getReportDefinition() == null)
1420             {
1421                 return;
1422             }
1423 
1424             // TODO: how should we arrive this code (set page and pagecount in the middle of the page footer)
1425             // If there exists a design template, don't use it.
1426 
1427             // we don't have a default report definition
1428             final String sPageOf = getResource().getResText(UIConsts.RID_REPORT + 89); // 'Page #page# of #count#'
1429 
1430             // Convert
1431             // 'Page #page# of #count#'
1432             // to something like
1433             // '\"Page \" & PageNumber() & \" of \" & PageCount()'
1434             // due to the fact that is is not fixed, where #page# or #count# occurs, we make it
1435             // a little bit trickier.
1436             // we first surround the string with double quotes,
1437             // second, replace the #...#
1438             // last, we remove double 'double quotes'.
1439             final String sSurroundDoubleQuotes = "\"" + sPageOf + "\"";
1440             final String sPageNumber = sSurroundDoubleQuotes.replaceAll("#page#", "\" & PageNumber() & \"");
1441             final String sPageCount = sPageNumber.replaceAll("#count#", "\" & PageCount() & \"");
1442             final String sNoLastUnusedQuotes = sPageCount.replaceAll(" & \\\"\\\"", PropertyNames.EMPTY_STRING);
1443             final String sNoFirstUnusedQuotes = sNoLastUnusedQuotes.replaceAll("\\\"\\\" & ", PropertyNames.EMPTY_STRING);
1444 
1445             final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent();
1446 
1447             try
1448             {
1449                 getReportDefinition().setPageFooterOn(true);
1450                 XSection xSection = null;
1451                 xSection = getReportDefinition().getPageFooter();
1452 
1453                 Rectangle aRect = new Rectangle();
1454                 aRect.X = getLeftPageIndent();
1455 
1456                 // draw a line over the label/formattedfield
1457                 final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X;
1458                 final int nLineHeight = LayoutConstants.LineHeight;
1459                 insertHorizontalLine(xSection, aRect, nLineWidth, nLineHeight);
1460 
1461                 aRect.Y += nLineHeight;
1462                 aRect.Y += LayoutConstants.LabelHeight;
1463 
1464                 aRect.X = getLeftPageIndent();
1465 
1466                 aRect = insertFormattedField(xSection, "rpt:" + sNoFirstUnusedQuotes, aRect, nUsablePageWidth, null, (short) com.sun.star.awt.TextAlign.CENTER);
1467 
1468                 aRect.Y += LayoutConstants.FormattedFieldHeight + LayoutConstants.LineHeight;
1469                 xSection.setHeight(aRect.Y);
1470             }
1471             catch (Exception e)
1472             {
1473                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1474             }
1475         }
1476     }
1477 
getResource()1478     protected Resource getResource()
1479     {
1480         return m_aResource;
1481     }
1482     protected int m_aCommandType; // Table or Query
1483     protected String m_sTableName;
1484     protected String[] m_aGroupNames;
1485     protected String[] m_aFieldNames;
1486     protected String[] m_aFieldTitleNames;
1487     protected int[] m_aFieldWidths;
1488     protected int[] m_aFieldTypes;
1489     // protected int[]    m_nLeftIndent;
1490     private DesignTemplate m_xDesignTemplate = null;
1491 
initializeData(IReportBuilderLayouter _aOther)1492     public void initializeData(IReportBuilderLayouter _aOther)
1493     {
1494         if (_aOther instanceof ReportBuilderLayouter)
1495         {
1496             final ReportBuilderLayouter aOther = (ReportBuilderLayouter) _aOther;
1497             m_aCommandType = aOther.m_aCommandType;
1498             m_sTableName = aOther.m_sTableName;
1499             m_aGroupNames = aOther.m_aGroupNames;
1500             m_aFieldNames = aOther.m_aFieldNames;
1501             m_aFieldTitleNames = aOther.m_aFieldTitleNames;
1502             m_aFieldWidths = aOther.m_aFieldWidths;
1503             m_aFieldTypes = aOther.m_aFieldTypes;
1504             // m_nLeftIndent = aOther.m_nLeftIndent;
1505             m_xDesignTemplate = aOther.m_xDesignTemplate;
1506 
1507             // dirty PageWidth
1508             m_nPageWidth = -1;
1509         }
1510     }
1511 
1512     /**
1513      * Get the maximal label width of all labels
1514      * @return the width in 1/100mm
1515      */
getMaxLabelWidth()1516     protected int getMaxLabelWidth()
1517     {
1518         int nWidth = 0;
1519         final String[] aFieldTitles = m_aFieldTitleNames; // we want all Field Titles here // getFieldTitleNames();
1520         for (int i = 0; i < aFieldTitles.length; i++)
1521         {
1522             final String sLabel = aFieldTitles[i];
1523             nWidth = Math.max(nWidth, getLabelWidth(sLabel));
1524         }
1525         for (int i = 0; i < m_aGroupNames.length; i++)
1526         {
1527             final String sGroupName = m_aGroupNames[i];
1528             final SectionObject a = getDesignTemplate().getGroupLabel(i);
1529             final FontDescriptor aFD = a.getFontDescriptor();
1530             nWidth = Math.max(nWidth, getLabelWidth(sGroupName, aFD));
1531         }
1532 
1533         if (nWidth == 0)
1534         {
1535             nWidth = 3000;
1536         }
1537         else
1538         {
1539             nWidth += 500;
1540         }
1541         return nWidth;
1542     }
1543 
1544     /**
1545      * Get width of a given string (Label) in 1/100mm
1546      * @param _sLabel
1547      * @return the width in 1/100mm
1548      */
getLabelWidth(String _sLabel)1549     protected int getLabelWidth(String _sLabel)
1550     {
1551         return getLabelWidth(_sLabel, 0.0f, 0.0f);
1552     }
1553     XFixedText m_aFixedTextHelper = null;
1554     HashMap m_aLabelWidthMap;
1555 
getLabelWidth(String _sLabel, FontDescriptor _aFD)1556     protected int getLabelWidth(String _sLabel, FontDescriptor _aFD)
1557     {
1558         float fCharWeight = 0.0f;
1559         float fCharHeight = 0.0f;
1560         if (_aFD != null)
1561         {
1562             fCharWeight = _aFD.Weight;
1563             fCharHeight = _aFD.Height;
1564         }
1565         return getLabelWidth(_sLabel, fCharWeight, fCharHeight);
1566     }
1567 
getLabelWidth(String _sLabel, float _nCharWeight, float _nCharHeight)1568     protected int getLabelWidth(String _sLabel, float _nCharWeight, float _nCharHeight)
1569     {
1570         int nWidth = 0;
1571 
1572         if (m_aLabelWidthMap == null)
1573         {
1574             m_aLabelWidthMap = new HashMap();
1575         }
1576         // At first, try to get the Width out of a HashMap (Cache)
1577         StringBuffer aKey = new StringBuffer(40);
1578         final String sKey = aKey.append(_sLabel).append(_nCharWeight).append(_nCharHeight).toString();
1579         if (m_aLabelWidthMap.containsKey(sKey))
1580         {
1581             final Object aWidth = m_aLabelWidthMap.get(sKey);
1582             final Integer aIntegerWidth = (Integer) aWidth;
1583             nWidth = aIntegerWidth.intValue();
1584         }
1585         else
1586         {
1587             try
1588             {
1589                 if (m_aFixedTextHelper == null)
1590                 {
1591                     final Object aFixedText = getMSFofReportDefinition().createInstance("com.sun.star.report.FixedText");
1592                     m_aFixedTextHelper = UnoRuntime.queryInterface(XFixedText.class, aFixedText);
1593                 }
1594 
1595                 m_aFixedTextHelper.setLabel(_sLabel);
1596                 if (_nCharWeight > 0.1f)
1597                 {
1598                     m_aFixedTextHelper.setCharWeight(_nCharWeight);
1599                 }
1600                 if (_nCharHeight > 0.1f)
1601                 {
1602                     m_aFixedTextHelper.setCharHeight(_nCharHeight);
1603                 }
1604 
1605                 final FontDescriptor xFont = m_aFixedTextHelper.getFontDescriptor();
1606                 final Size aSize = getPreferredSize(_sLabel, xFont);
1607                 nWidth = aSize.Width;
1608                 // cache the found width
1609                 m_aLabelWidthMap.put(sKey, new Integer(nWidth));
1610             }
1611             catch (com.sun.star.uno.Exception e)
1612             {
1613                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1614             }
1615         }
1616         return nWidth;
1617     }
1618 
doNotBreakInTable(Object _xSectionOrGroup)1619     protected void doNotBreakInTable(Object _xSectionOrGroup)
1620     {
1621 //         try
1622 //         {
1623 //            _xSection.setKeepTogether(true);
1624         final PropertySetHelper aHelper = new PropertySetHelper(_xSectionOrGroup);
1625         aHelper.setPropertyValueDontThrow("KeepTogether", Boolean.TRUE);
1626 //        }
1627 //        catch (com.sun.star.uno.Exception e)
1628 //        {
1629 //            // Exception not set, but not really from interest.
1630 //        }
1631     }
1632 
getDesignTemplate()1633     protected DesignTemplate getDesignTemplate()
1634     {
1635         if (m_xDesignTemplate == null)
1636         {
1637             // initialise the report definition.
1638             String sDefaultHeaderLayout = m_xReportDefinitionReadAccess.getDefaultHeaderLayout();
1639             loadAndSetBackgroundTemplate(sDefaultHeaderLayout);
1640 
1641             // copy all functions from the design template to the current report definition
1642 //            XFunctions xOtherFunctions = m_xDesignTemplate.getReportDefinition().getFunctions();
1643 //            final int nFunctionCount = xOtherFunctions.getCount();
1644 //            for (int i=0;i<nFunctionCount;i++)
1645 //            {
1646 //                try
1647 //                {
1648 //                    Object aOtherFunction = xOtherFunctions.getByIndex(i);
1649 //                    XFunctions xFunctions = getReportDefinition().getFunctions();
1650 //                    XFunction xFunction = xFunctions.createFunction();
1651 //
1652 //                    copyProperties(aOtherFunction, xFunction);
1653 //                    xFunctions.insertByIndex(xFunctions.getCount(), xFunction);
1654 //                }
1655 //                catch (com.sun.star.lang.IllegalArgumentException e)
1656 //                {
1657 //                }
1658 //                catch (IndexOutOfBoundsException ex)
1659 //                {
1660 //                    ex.printStackTrace();
1661 //                }
1662 //                catch (WrappedTargetException ex)
1663 //                {
1664 //                    ex.printStackTrace();
1665 //                }
1666 //
1667 //            }
1668 
1669         }
1670         return m_xDesignTemplate;
1671     }
1672 
1673     /**
1674      * If there already exists a foreign report definition, which we use to get the layout from
1675      * close it.
1676      * Veto is not allowed here.
1677      */
closeDesignTemplate()1678     private void closeDesignTemplate()
1679     {
1680         if (m_xDesignTemplate != null)
1681         {
1682             m_xDesignTemplate.close();
1683             m_xDesignTemplate = null;
1684         }
1685     }
1686 
1687     /**
1688      * load the given string as a template and use it's content to paint the other
1689      * @param LayoutTemplatePath
1690      */
loadAndSetBackgroundTemplate(String LayoutTemplatePath)1691     public void loadAndSetBackgroundTemplate(String LayoutTemplatePath)
1692     {
1693         closeDesignTemplate();
1694 
1695         String sName = FileAccess.getFilename(LayoutTemplatePath);
1696         if (sName.toLowerCase().equals("default.otr_")
1697                 || LayoutTemplatePath.equals("DefaultLayoutOfHeaders"))
1698         {
1699             // this is the default layout, we don't want to have a layout for this.
1700         }
1701         else
1702         {
1703             XMultiServiceFactory xMSF = getGlobalMSF();
1704             m_xDesignTemplate = DesignTemplate.create(xMSF, LayoutTemplatePath);
1705         }
1706     }
1707 }
1708