xref: /trunk/main/wizards/com/sun/star/wizards/reportbuilder/layout/ReportBuilderLayouter.java (revision b6fd66b75b193ec5c149e1b2c838579d044a0b3d)
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 StringBuilder aDataField = new StringBuilder(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 //
1034 //            Locale aLocale = new Locale("en","US");
1035 //            SimpleDateFormat aFormat = new SimpleDateFormat(_sFormat, aLocale);
1036 //            String aBuf = aFormat.format(aCalendar.getTime());
1037 //            // DebugHelper.writeInfo("Date: " + aBuf);
1038 //            return aBuf;
1039 //    }
1040 //    protected String getCurrentDate()
1041 //    {
1042 //        Calendar aCalendar = Calendar.getInstance();
1043 ////        aCalendar.setTimeInMillis(1202382900000L);
1044 ////        aCalendar.
1045 //        Date aDate = new Date();
1046 //        String sDate = DateFormat.getDateInstance().format(aDate);
1047 //        // String aCalStr = aCalendar.toString();
1048 //        return sDate;
1049 //        //
1050 ////        Date aDate = new Date();
1051 ////        aDate.setSeconds(0);
1052 ////        aDate.setMinutes(15);
1053 ////        aDate.setHours(12);
1054 ////        // aDate.setMonth(2);
1055 ////        // aDate.setYear(2008);
1056 ////        // aDate.setDay(7);
1057 ////        long nTime = aDate.getTime();
1058 ////        Long aLong = new Long(nTime);
1059 ////        String aStr = aLong.toString();
1060 ////
1061 ////        Date aNewDate = new Date(1202382900000L);
1062 //////         aNewDate.
1063 ////        String aDateStr = aNewDate.toString();
1064 //////         Datetime aNewTime = new Time(1202382900);
1065 //////         String aTimeStr = aNewTime.toString();
1066 ////
1067 //
1068 //    }
clearPageFooter()1069     protected void clearPageFooter()
1070     {
1071         XSection xSection;
1072         try
1073         {
1074             if (getReportDefinition().getPageFooterOn())
1075             {
1076                 xSection = getReportDefinition().getPageFooter();
1077                 emptySection(xSection);
1078             }
1079         }
1080         catch (com.sun.star.container.NoSuchElementException e)
1081         {
1082             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1083         }
1084     }
1085 
setPageOrientation(int _nOrientation)1086     public void setPageOrientation(int _nOrientation)
1087     {
1088         final int nWidth = getFromPageStyles(PropertyNames.PROPERTY_WIDTH, 0);
1089         final int nHeight = getFromPageStyles(PropertyNames.PROPERTY_HEIGHT, 0);
1090 
1091         if (com.sun.star.wizards.report.ReportLayouter.SOOPTLANDSCAPE == _nOrientation)
1092         {
1093             setToPageStyles("IsLandscape", Boolean.TRUE);
1094             if (nWidth < nHeight)
1095             {
1096                 setToPageStyles(PropertyNames.PROPERTY_WIDTH, new Integer(nHeight));
1097                 setToPageStyles(PropertyNames.PROPERTY_HEIGHT, new Integer(nWidth));
1098             }
1099         }
1100         else
1101         {
1102             setToPageStyles("IsLandscape", Boolean.FALSE);
1103             if (nHeight < nWidth)
1104             {
1105                 setToPageStyles(PropertyNames.PROPERTY_WIDTH, new Integer(nHeight));
1106                 setToPageStyles(PropertyNames.PROPERTY_HEIGHT, new Integer(nWidth));
1107             }
1108         }
1109         // dirty the PageWidth
1110         m_nPageWidth = -1;
1111     }
1112 
1113     /**
1114      * Returns the width and height of a given string (_sText) in 1/100mm drawn in the given font descriptor.
1115      * 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.
1116      *
1117      * @param _sText
1118      * @param _aFont
1119      * @return width of given text in 1/100mm
1120      */
getPreferredSize(String _sText, FontDescriptor _aFont)1121     Size getPreferredSize(String _sText, FontDescriptor _aFont)
1122     {
1123         Size aSizeMM_100TH = new Size(0, 0);
1124         try
1125         {
1126             // Object aControlContainer = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlContainer");
1127             // XControlContainer xControlContainer = UnoRuntime.queryInterface(XControlContainer.class, aControlContainer);
1128 
1129             final Object aFixedTextModel = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlFixedTextModel");
1130             final XControlModel xFixedTextModel = UnoRuntime.queryInterface(XControlModel.class, aFixedTextModel);
1131 
1132             final PropertySetHelper aPropertySetHelper = new PropertySetHelper(xFixedTextModel);
1133 //          aPropertySetHelper.showProperties();
1134             aPropertySetHelper.setPropertyValueDontThrow(PropertyNames.FONT_DESCRIPTOR, _aFont);
1135 
1136             final Object aUnoCtrlFixedText = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlFixedText");
1137 //            XServiceInfo xServiceInfo2 = UnoRuntime.queryInterface(XServiceInfo.class, aUnoCtrlFixedText);
1138 //            String[] sServices2 = xServiceInfo2.getSupportedServiceNames();
1139 
1140             final XWindow xWindow = UnoRuntime.queryInterface(XWindow.class, aUnoCtrlFixedText);
1141             xWindow.setVisible(false);
1142 
1143             final XControl xControl = UnoRuntime.queryInterface(XControl.class, aUnoCtrlFixedText);
1144             xControl.setModel(xFixedTextModel);
1145 
1146             final com.sun.star.awt.XFixedText xFixedText = UnoRuntime.queryInterface(com.sun.star.awt.XFixedText.class, aUnoCtrlFixedText);
1147             xFixedText.setText(_sText);
1148 
1149             final XLayoutConstrains xLayoutConstraints = UnoRuntime.queryInterface(XLayoutConstrains.class, aUnoCtrlFixedText);
1150             final Size aSizeInPixel = xLayoutConstraints.getPreferredSize();
1151 
1152             final XWindowPeer xPeerOfReportDefinition = UnoRuntime.queryInterface(XWindowPeer.class, getReportDefinition().getCurrentController().getFrame().getComponentWindow());
1153             xControl.createPeer(null, xPeerOfReportDefinition);
1154 
1155             final XWindowPeer x = xControl.getPeer();
1156 
1157             final XUnitConversion xConversion = UnoRuntime.queryInterface(XUnitConversion.class, x);
1158             aSizeMM_100TH = xConversion.convertSizeToLogic(aSizeInPixel, com.sun.star.util.MeasureUnit.MM_100TH);
1159             // xToolkit.createScreenCompatibleDevice(_nWidth, _nWidth).
1160             // XWindow x = getReportDefinition().getCurrentController().getFrame().getContainerWindow();
1161             // Object aObj = _xSection.getParent();
1162 
1163             // we don't need the created objects any longer
1164             final XComponent xFixedTextDeleter = UnoRuntime.queryInterface(XComponent.class, xFixedText);
1165             xFixedTextDeleter.dispose();
1166 
1167             final XComponent xFixedTextModelDeleter = UnoRuntime.queryInterface(XComponent.class, aFixedTextModel);
1168             xFixedTextModelDeleter.dispose();
1169         }
1170         catch (Exception e)
1171         {
1172             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1173         }
1174         return aSizeMM_100TH;
1175     }
1176 
getTableName()1177     protected String getTableName()
1178     {
1179         if (m_sTableName != null)
1180         {
1181             return m_sTableName;
1182         }
1183         return PropertyNames.EMPTY_STRING;
1184     }
1185 
getUserNameFromConfiguration()1186     protected String getUserNameFromConfiguration()
1187     {
1188         String sFirstName = PropertyNames.EMPTY_STRING;
1189         String sLastName = PropertyNames.EMPTY_STRING;
1190         try
1191         {
1192             Object oProdNameAccess = Configuration.getConfigurationRoot(getGlobalMSF(), "org.openoffice.UserProfile/Data", false);
1193             sFirstName = (String) Helper.getUnoObjectbyName(oProdNameAccess, "givenname");
1194             sLastName = (String) Helper.getUnoObjectbyName(oProdNameAccess, "sn");
1195         }
1196         catch (Exception e)
1197         {
1198             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1199         }
1200         return sFirstName + PropertyNames.SPACE + sLastName;
1201     }
1202 
1203     /**
1204      * Helper function, to copy all not read only properties of _xFromSection to _xToSection
1205      * @param _xFromSection
1206      * @param _xToSection
1207      */
copyProperties(Object _aFrom, Object _aTo)1208     private void copyProperties(Object _aFrom, Object _aTo)
1209     {
1210         XPropertySet xFrom = UnoRuntime.queryInterface(XPropertySet.class, _aFrom);
1211         XPropertySet xTo = UnoRuntime.queryInterface(XPropertySet.class, _aTo);
1212 
1213 
1214         XPropertySetInfo xForeignPropInfo = xFrom.getPropertySetInfo();
1215         XPropertySetInfo xSectionPropInfo = xTo.getPropertySetInfo();
1216         Property[] aAllProperties = xForeignPropInfo.getProperties();
1217         for (int i = 0; i < aAllProperties.length; i++)
1218         {
1219             String sPropertyName = aAllProperties[i].Name;
1220             if (xSectionPropInfo.hasPropertyByName(sPropertyName))
1221             {
1222                 try
1223                 {
1224                     Property aDestProp = xForeignPropInfo.getPropertyByName(sPropertyName);
1225                     if ((aDestProp.Attributes & PropertyAttribute.READONLY) == 0)
1226                     {
1227                         xTo.setPropertyValue(sPropertyName, xFrom.getPropertyValue(sPropertyName));
1228                     }
1229                 }
1230                 catch (Exception e)
1231                 {
1232                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1233                 }
1234             }
1235         }
1236     }
1237 
1238     /**
1239      * Helper Funktion to copy the whole content of _xFromSection to the _xToSection
1240      * @param _xFromSection
1241      * @param _xToSection
1242      */
copySection(XSection _xFromSection, XSection _xToSection)1243     private void copySection(XSection _xFromSection, XSection _xToSection)
1244     {
1245         copyProperties(_xFromSection, _xToSection);
1246 
1247         try
1248         {
1249             XEnumeration xEnum = _xFromSection.createEnumeration();
1250             while (xEnum.hasMoreElements())
1251             {
1252                 Object aEnumObj = xEnum.nextElement();
1253                 XReportComponent aComponent = UnoRuntime.queryInterface(XReportComponent.class, aEnumObj);
1254 
1255                 // XCloneable aClone = UnoRuntime.queryInterface(XCloneable.class, aEnumObj);
1256                 if (aComponent != null)
1257                 {
1258                     Object aClone = aComponent.createClone();
1259                     if (aClone != null)
1260                     {
1261                         XShape aShape = UnoRuntime.queryInterface(XShape.class, aClone);
1262 
1263                         // normally 'createClone' will create a real clone of the component,
1264                         // but there seems some problems, we have to control.
1265                         copyProperties(aComponent, aClone);
1266 
1267                         // aShape.setPosition(aComponent.getPosition());
1268                         // aShape.setSize(aComponent.getSize());
1269                         _xToSection.add(aShape);
1270                     }
1271                 }
1272             }
1273         }
1274         catch (Exception e)
1275         {
1276             Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1277         }
1278         // String sName = xForeignSection.getName();
1279         // int dummy = 0;
1280     }
1281 
insertPageHeader()1282     protected void insertPageHeader()
1283     {
1284         if (getDesignTemplate() != null)
1285         {
1286             if (getDesignTemplate().getPageHeaderOn())
1287             {
1288                 // copy all Section information from Page Header to our Header
1289                 try
1290                 {
1291                     XSection xForeignSection = getDesignTemplate().getPageHeader();
1292 
1293                     if (xForeignSection != null)
1294                     {
1295                         getReportDefinition().setPageHeaderOn(true);
1296                         XSection xSection = getReportDefinition().getPageHeader();
1297 
1298                         // copy Sections
1299                         copySection(xForeignSection, xSection);
1300                     }
1301                 }
1302                 catch (Exception e)
1303                 {
1304                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1305                 }
1306                 }
1307             else
1308             {
1309                 // we won't a page header
1310                 // getReportDefinition().setPageHeaderOn(true);
1311                 getReportDefinition().setPageHeaderOn(false);
1312             }
1313         }
1314         else
1315         {
1316             if (getReportDefinition() == null)
1317             {
1318                 return;
1319             }
1320             // there is no foreign report definition
1321             // TODO: #i86902# rpt:Title() out of the document
1322 
1323             // TODO: #i86902# rpt:Author() can't set with something like rpt:author()
1324             // TODO: #i86902# more fieldnames need.
1325             final String sTitleTitle = getResource().getResText(UIConsts.RID_REPORT + 86); // "Title:"
1326             final String sTitle = getTableName(); // "Default title, this is a first draft report generated by the new report wizard.";
1327             final String sAuthorTitle = getResource().getResText(UIConsts.RID_REPORT + 87); // "Author:"
1328             final String sAuthor = getUserNameFromConfiguration(); // "You";     // rpt:fieldvalue();
1329             final String sDateTitle = getResource().getResText(UIConsts.RID_REPORT + 88); // "Date:"
1330             // TODO: #i86911# Date: we need to set the style of the date.
1331             final String sDate = "rpt:now()"; // getDateString("EEE, d MMM yyyy HH:mm:ss zzzz");
1332 
1333             try
1334             {
1335                 getReportDefinition().setPageHeaderOn(true);
1336                 XSection xSection = null;
1337                 xSection = getReportDefinition().getPageHeader();
1338 
1339                 Rectangle aRect = new Rectangle();
1340                 aRect.X = getLeftPageIndent();
1341                 SectionObject aSOLabel = SectionEmptyObject.create();
1342                 aSOLabel.setFontToBold();
1343                 aRect.Y = aSOLabel.getHeight(LayoutConstants.LabelHeight);
1344 
1345                 final int nWidth = 3000;
1346 
1347                 aRect = insertLabel(xSection, sTitleTitle, aRect, nWidth, aSOLabel);
1348 
1349                 final int nTitleWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - 3000;
1350                 // aRect = insertFormattedField(xSection, "rpt:Title()", aRect, nTitleWidth);
1351                 aRect = insertLabel(xSection, sTitle, aRect, nTitleWidth, aSOLabel);
1352 
1353                 aRect.Y += aSOLabel.getHeight(LayoutConstants.LabelHeight) + LayoutConstants.LineHeight;
1354 
1355                 aRect.X = getLeftPageIndent();
1356                 aRect = insertLabel(xSection, sAuthorTitle, aRect, nWidth, aSOLabel);
1357                 // aRect = insertFormattedField(xSection, "rpt:Author()", aRect, nWidth);
1358                 aRect = insertLabel(xSection, sAuthor, aRect, nTitleWidth, aSOLabel);
1359 
1360                 aRect.Y += aSOLabel.getHeight(LayoutConstants.LabelHeight);
1361 
1362                 aRect.X = getLeftPageIndent();
1363                 aRect = insertLabel(xSection, sDateTitle, aRect, nWidth, aSOLabel);
1364                 // aRect = insertFormattedField(xSection, "rpt:Date()", aRect, nWidth);
1365                 aRect = insertFormattedField(xSection, sDate, aRect, nTitleWidth, aSOLabel);
1366 
1367                 aRect.Y += aSOLabel.getHeight(LayoutConstants.FormattedFieldHeight) + LayoutConstants.LineHeight;
1368 
1369                 // draw a line under the label/formattedfield
1370                 aRect.X = getLeftPageIndent();
1371                 final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X;
1372                 final int nLineHeight = LayoutConstants.LineHeight;
1373                 insertHorizontalLine(xSection, aRect, nLineWidth, nLineHeight);
1374 
1375                 aRect.Y += nLineHeight;
1376 
1377                 xSection.setHeight(aRect.Y);
1378             }
1379             catch (com.sun.star.uno.Exception e)
1380             {
1381                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1382             }
1383         }
1384     }
1385 
insertPageFooter()1386     protected void insertPageFooter()
1387     {
1388         if (getDesignTemplate() != null)
1389         {
1390             if (getDesignTemplate().getPageFooterOn())
1391             {
1392                 try
1393                 {
1394                     XSection xForeignSection = getDesignTemplate().getPageFooter();
1395 
1396                     if (xForeignSection != null)
1397                     {
1398                         getReportDefinition().setPageFooterOn(true);
1399                         XSection xSection = getReportDefinition().getPageFooter();
1400 
1401                         // copy Sections
1402                         copySection(xForeignSection, xSection);
1403                     }
1404                 }
1405                 catch (Exception e)
1406                 {
1407                     Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1408                 }
1409             }
1410             else
1411             {
1412                 // getReportDefinition().setPageFooterOn(true);
1413                 getReportDefinition().setPageFooterOn(false);
1414             }
1415         }
1416         else
1417         {
1418             if (getReportDefinition() == null)
1419             {
1420                 return;
1421             }
1422 
1423             // TODO: how should we arrive this code (set page and pagecount in the middle of the page footer)
1424             // If there exists a design template, don't use it.
1425 
1426             // we don't have a default report definition
1427             final String sPageOf = getResource().getResText(UIConsts.RID_REPORT + 89); // 'Page #page# of #count#'
1428 
1429             // Convert
1430             // 'Page #page# of #count#'
1431             // to something like
1432             // '\"Page \" & PageNumber() & \" of \" & PageCount()'
1433             // due to the fact that is is not fixed, where #page# or #count# occurs, we make it
1434             // a little bit trickier.
1435             // we first surround the string with double quotes,
1436             // second, replace the #...#
1437             // last, we remove double 'double quotes'.
1438             final String sSurroundDoubleQuotes = "\"" + sPageOf + "\"";
1439             final String sPageNumber = sSurroundDoubleQuotes.replaceAll("#page#", "\" & PageNumber() & \"");
1440             final String sPageCount = sPageNumber.replaceAll("#count#", "\" & PageCount() & \"");
1441             final String sNoLastUnusedQuotes = sPageCount.replaceAll(" & \\\"\\\"", PropertyNames.EMPTY_STRING);
1442             final String sNoFirstUnusedQuotes = sNoLastUnusedQuotes.replaceAll("\\\"\\\" & ", PropertyNames.EMPTY_STRING);
1443 
1444             final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent();
1445 
1446             try
1447             {
1448                 getReportDefinition().setPageFooterOn(true);
1449                 XSection xSection = null;
1450                 xSection = getReportDefinition().getPageFooter();
1451 
1452                 Rectangle aRect = new Rectangle();
1453                 aRect.X = getLeftPageIndent();
1454 
1455                 // draw a line over the label/formattedfield
1456                 final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X;
1457                 final int nLineHeight = LayoutConstants.LineHeight;
1458                 insertHorizontalLine(xSection, aRect, nLineWidth, nLineHeight);
1459 
1460                 aRect.Y += nLineHeight;
1461                 aRect.Y += LayoutConstants.LabelHeight;
1462 
1463                 aRect.X = getLeftPageIndent();
1464 
1465                 aRect = insertFormattedField(xSection, "rpt:" + sNoFirstUnusedQuotes, aRect, nUsablePageWidth, null, (short) com.sun.star.awt.TextAlign.CENTER);
1466 
1467                 aRect.Y += LayoutConstants.FormattedFieldHeight + LayoutConstants.LineHeight;
1468                 xSection.setHeight(aRect.Y);
1469             }
1470             catch (Exception e)
1471             {
1472                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1473             }
1474         }
1475     }
1476 
getResource()1477     protected Resource getResource()
1478     {
1479         return m_aResource;
1480     }
1481     protected int m_aCommandType; // Table or Query
1482     protected String m_sTableName;
1483     protected String[] m_aGroupNames;
1484     protected String[] m_aFieldNames;
1485     protected String[] m_aFieldTitleNames;
1486     protected int[] m_aFieldWidths;
1487     protected int[] m_aFieldTypes;
1488     // protected int[]    m_nLeftIndent;
1489     private DesignTemplate m_xDesignTemplate = null;
1490 
initializeData(IReportBuilderLayouter _aOther)1491     public void initializeData(IReportBuilderLayouter _aOther)
1492     {
1493         if (_aOther instanceof ReportBuilderLayouter)
1494         {
1495             final ReportBuilderLayouter aOther = (ReportBuilderLayouter) _aOther;
1496             m_aCommandType = aOther.m_aCommandType;
1497             m_sTableName = aOther.m_sTableName;
1498             m_aGroupNames = aOther.m_aGroupNames;
1499             m_aFieldNames = aOther.m_aFieldNames;
1500             m_aFieldTitleNames = aOther.m_aFieldTitleNames;
1501             m_aFieldWidths = aOther.m_aFieldWidths;
1502             m_aFieldTypes = aOther.m_aFieldTypes;
1503             // m_nLeftIndent = aOther.m_nLeftIndent;
1504             m_xDesignTemplate = aOther.m_xDesignTemplate;
1505 
1506             // dirty PageWidth
1507             m_nPageWidth = -1;
1508         }
1509     }
1510 
1511     /**
1512      * Get the maximal label width of all labels
1513      * @return the width in 1/100mm
1514      */
getMaxLabelWidth()1515     protected int getMaxLabelWidth()
1516     {
1517         int nWidth = 0;
1518         final String[] aFieldTitles = m_aFieldTitleNames; // we want all Field Titles here // getFieldTitleNames();
1519         for (int i = 0; i < aFieldTitles.length; i++)
1520         {
1521             final String sLabel = aFieldTitles[i];
1522             nWidth = Math.max(nWidth, getLabelWidth(sLabel));
1523         }
1524         for (int i = 0; i < m_aGroupNames.length; i++)
1525         {
1526             final String sGroupName = m_aGroupNames[i];
1527             final SectionObject a = getDesignTemplate().getGroupLabel(i);
1528             final FontDescriptor aFD = a.getFontDescriptor();
1529             nWidth = Math.max(nWidth, getLabelWidth(sGroupName, aFD));
1530         }
1531 
1532         if (nWidth == 0)
1533         {
1534             nWidth = 3000;
1535         }
1536         else
1537         {
1538             nWidth += 500;
1539         }
1540         return nWidth;
1541     }
1542 
1543     /**
1544      * Get width of a given string (Label) in 1/100mm
1545      * @param _sLabel
1546      * @return the width in 1/100mm
1547      */
getLabelWidth(String _sLabel)1548     protected int getLabelWidth(String _sLabel)
1549     {
1550         return getLabelWidth(_sLabel, 0.0f, 0.0f);
1551     }
1552     XFixedText m_aFixedTextHelper = null;
1553     HashMap m_aLabelWidthMap;
1554 
getLabelWidth(String _sLabel, FontDescriptor _aFD)1555     protected int getLabelWidth(String _sLabel, FontDescriptor _aFD)
1556     {
1557         float fCharWeight = 0.0f;
1558         float fCharHeight = 0.0f;
1559         if (_aFD != null)
1560         {
1561             fCharWeight = _aFD.Weight;
1562             fCharHeight = _aFD.Height;
1563         }
1564         return getLabelWidth(_sLabel, fCharWeight, fCharHeight);
1565     }
1566 
getLabelWidth(String _sLabel, float _nCharWeight, float _nCharHeight)1567     protected int getLabelWidth(String _sLabel, float _nCharWeight, float _nCharHeight)
1568     {
1569         int nWidth = 0;
1570 
1571         if (m_aLabelWidthMap == null)
1572         {
1573             m_aLabelWidthMap = new HashMap();
1574         }
1575         // At first, try to get the Width out of a HashMap (Cache)
1576         StringBuilder aKey = new StringBuilder(40);
1577         final String sKey = aKey.append(_sLabel).append(_nCharWeight).append(_nCharHeight).toString();
1578         if (m_aLabelWidthMap.containsKey(sKey))
1579         {
1580             final Object aWidth = m_aLabelWidthMap.get(sKey);
1581             final Integer aIntegerWidth = (Integer) aWidth;
1582             nWidth = aIntegerWidth.intValue();
1583         }
1584         else
1585         {
1586             try
1587             {
1588                 if (m_aFixedTextHelper == null)
1589                 {
1590                     final Object aFixedText = getMSFofReportDefinition().createInstance("com.sun.star.report.FixedText");
1591                     m_aFixedTextHelper = UnoRuntime.queryInterface(XFixedText.class, aFixedText);
1592                 }
1593 
1594                 m_aFixedTextHelper.setLabel(_sLabel);
1595                 if (_nCharWeight > 0.1f)
1596                 {
1597                     m_aFixedTextHelper.setCharWeight(_nCharWeight);
1598                 }
1599                 if (_nCharHeight > 0.1f)
1600                 {
1601                     m_aFixedTextHelper.setCharHeight(_nCharHeight);
1602                 }
1603 
1604                 final FontDescriptor xFont = m_aFixedTextHelper.getFontDescriptor();
1605                 final Size aSize = getPreferredSize(_sLabel, xFont);
1606                 nWidth = aSize.Width;
1607                 // cache the found width
1608                 m_aLabelWidthMap.put(sKey, new Integer(nWidth));
1609             }
1610             catch (com.sun.star.uno.Exception e)
1611             {
1612                 Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e);
1613             }
1614         }
1615         return nWidth;
1616     }
1617 
doNotBreakInTable(Object _xSectionOrGroup)1618     protected void doNotBreakInTable(Object _xSectionOrGroup)
1619     {
1620 //         try
1621 //         {
1622 //            _xSection.setKeepTogether(true);
1623         final PropertySetHelper aHelper = new PropertySetHelper(_xSectionOrGroup);
1624         aHelper.setPropertyValueDontThrow("KeepTogether", Boolean.TRUE);
1625 //        }
1626 //        catch (com.sun.star.uno.Exception e)
1627 //        {
1628 //            // Exception not set, but not really from interest.
1629 //        }
1630     }
1631 
getDesignTemplate()1632     protected DesignTemplate getDesignTemplate()
1633     {
1634         if (m_xDesignTemplate == null)
1635         {
1636             // initialise the report definition.
1637             String sDefaultHeaderLayout = m_xReportDefinitionReadAccess.getDefaultHeaderLayout();
1638             loadAndSetBackgroundTemplate(sDefaultHeaderLayout);
1639 
1640             // copy all functions from the design template to the current report definition
1641 //            XFunctions xOtherFunctions = m_xDesignTemplate.getReportDefinition().getFunctions();
1642 //            final int nFunctionCount = xOtherFunctions.getCount();
1643 //            for (int i=0;i<nFunctionCount;i++)
1644 //            {
1645 //                try
1646 //                {
1647 //                    Object aOtherFunction = xOtherFunctions.getByIndex(i);
1648 //                    XFunctions xFunctions = getReportDefinition().getFunctions();
1649 //                    XFunction xFunction = xFunctions.createFunction();
1650 //
1651 //                    copyProperties(aOtherFunction, xFunction);
1652 //                    xFunctions.insertByIndex(xFunctions.getCount(), xFunction);
1653 //                }
1654 //                catch (com.sun.star.lang.IllegalArgumentException e)
1655 //                {
1656 //                }
1657 //                catch (IndexOutOfBoundsException ex)
1658 //                {
1659 //                    ex.printStackTrace();
1660 //                }
1661 //                catch (WrappedTargetException ex)
1662 //                {
1663 //                    ex.printStackTrace();
1664 //                }
1665 //
1666 //            }
1667 
1668         }
1669         return m_xDesignTemplate;
1670     }
1671 
1672     /**
1673      * If there already exists a foreign report definition, which we use to get the layout from
1674      * close it.
1675      * Veto is not allowed here.
1676      */
closeDesignTemplate()1677     private void closeDesignTemplate()
1678     {
1679         if (m_xDesignTemplate != null)
1680         {
1681             m_xDesignTemplate.close();
1682             m_xDesignTemplate = null;
1683         }
1684     }
1685 
1686     /**
1687      * load the given string as a template and use it's content to paint the other
1688      * @param LayoutTemplatePath
1689      */
loadAndSetBackgroundTemplate(String LayoutTemplatePath)1690     public void loadAndSetBackgroundTemplate(String LayoutTemplatePath)
1691     {
1692         closeDesignTemplate();
1693 
1694         String sName = FileAccess.getFilename(LayoutTemplatePath);
1695         if (sName.toLowerCase().equals("default.otr_")
1696                 || LayoutTemplatePath.equals("DefaultLayoutOfHeaders"))
1697         {
1698             // this is the default layout, we don't want to have a layout for this.
1699         }
1700         else
1701         {
1702             XMultiServiceFactory xMSF = getGlobalMSF();
1703             m_xDesignTemplate = DesignTemplate.create(xMSF, LayoutTemplatePath);
1704         }
1705     }
1706 }
1707