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