diff options
Diffstat (limited to 'wizards/com/sun/star/wizards/reportbuilder')
15 files changed, 3500 insertions, 0 deletions
diff --git a/wizards/com/sun/star/wizards/reportbuilder/MANIFEST.MF b/wizards/com/sun/star/wizards/reportbuilder/MANIFEST.MF new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/MANIFEST.MF @@ -0,0 +1 @@ + diff --git a/wizards/com/sun/star/wizards/reportbuilder/ReportBuilderImplementation.java b/wizards/com/sun/star/wizards/reportbuilder/ReportBuilderImplementation.java new file mode 100644 index 000000000..1c7a90ba3 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/ReportBuilderImplementation.java @@ -0,0 +1,692 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.sun.star.awt.XWindowPeer; +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.XPropertySet; +import com.sun.star.container.XHierarchicalNameContainer; +import com.sun.star.frame.XController; +import com.sun.star.frame.XDispatch; +import com.sun.star.frame.XDispatchProvider; +import com.sun.star.frame.XFrame; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.report.XReportDefinition; +import com.sun.star.sdb.XSubDocument; +import com.sun.star.sdb.application.DatabaseObject; +import com.sun.star.sdb.application.XDatabaseDocumentUI; +import com.sun.star.ucb.XCommandProcessor; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.util.XModeSelector; +import com.sun.star.util.XModifiable; +import com.sun.star.util.XURLTransformer; +import com.sun.star.wizards.common.FileAccess; +import com.sun.star.wizards.common.NamedValueCollection; +import com.sun.star.wizards.common.PropertyNames; +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.db.FieldColumn; +import com.sun.star.wizards.report.IReportBuilderLayouter; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.report.IReportDocument; +import com.sun.star.wizards.report.ReportImplementationHelper; +import com.sun.star.wizards.report.ReportLayouter; +import com.sun.star.wizards.report.ReportWizard; +import com.sun.star.wizards.ui.UIConsts; + +/** + * This class use the IReportDocument Interface to communicate between the UI + * and the ReportBuilderLayouter which communicates to the new Report Builder. + */ +@SuppressWarnings("ucd") +public class ReportBuilderImplementation extends ReportImplementationHelper + implements IReportDocument, IReportDefinitionReadAccess +{ + + private Resource m_resource; + private XDatabaseDocumentUI m_documentUI; + private static final int MAXIMUM_GROUPCOUNT = 4; + private String[] groupNames = null; + + private ReportBuilderImplementation(XMultiServiceFactory _serviceFactory) + { + // creates an access to the ReportBuilder Extension + super(_serviceFactory, ReportLayouter.SOOPTLANDSCAPE); + } + + public static IReportDocument create(XMultiServiceFactory i_serviceFactory) + { + return new ReportBuilderImplementation(i_serviceFactory); + } + + public void initialize(final XDatabaseDocumentUI i_documentUI, final Resource i_resource) + { + m_documentUI = i_documentUI; + m_resource = i_resource; + } + + public void clearDocument() + { + } + + public XWindowPeer getWizardParent() + { + return UnoRuntime.queryInterface(XWindowPeer.class, getFrame().getComponentWindow()); + } + private XFrame m_xFrame = null; + private String m_sReportBuilderLayoutName = PropertyNames.EMPTY_STRING; + + /** + * Get access to the current ReportLayouter, which depends on the name. + * To change the ReportBuilderLayouter use <code>setReportBuilderLayouterName(String Name)</code>. + * @return + */ + private IReportBuilderLayouter getReportBuilderLayouter() + { + return getLayoutMap().get(m_sReportBuilderLayoutName); + } + private Object m_aReportDocument; + private XPropertySet m_documentDefinition; + private XReportDefinition m_reportDocument; + + /** + * initialize the Report Builder and open it representation + * @param _aDoc + */ + private void initialize(Object _aDoc) + { + m_aReportDocument = _aDoc; + + try + { + NamedValueCollection creationArgs = new NamedValueCollection(); + creationArgs.put("DocumentServiceName", "com.sun.star.report.ReportDefinition"); + creationArgs.put("Mode", "remote"); + + XComponent[] docDefinition = new XComponent[] + { + null + }; + XComponent reportDefinitionComp = m_documentUI.createComponentWithArguments( + DatabaseObject.REPORT, creationArgs.getPropertyValues(), docDefinition); + + m_documentDefinition = UnoRuntime.queryInterface(XPropertySet.class, docDefinition[0]); + m_reportDocument = UnoRuntime.queryInterface(XReportDefinition.class, reportDefinitionComp); + } + catch (com.sun.star.uno.Exception e) + { + ReportWizard.getLogger().log(com.sun.star.logging.LogLevel.SEVERE, "Problems with initialize the ReportDefinition" + e.getMessage()); + + } + + switchOffPropertyBrowser(); + switchOffAddFieldWindow(); + + setPageOrientation(m_nDefaultPageOrientation, false /* NO_LAYOUT*/); + } + + private XModeSelector getModeSelector() + { + final XController xController = getReportDefinition().getCurrentController(); + return UnoRuntime.queryInterface(XModeSelector.class, xController); + } + + private void switchOffAddFieldWindow() + { + try + { + getModeSelector().setMode("remote"); + } + catch (com.sun.star.uno.Exception e) + { + } + } + + private void switchOnAddFieldWindow() + { + try + { + getModeSelector().setMode("normal"); + } + catch (com.sun.star.uno.Exception e) + { + } + } + + private void switchOffPropertyBrowser() + { + try + { + final XController xController = getReportDefinition().getCurrentController(); + final XDispatchProvider xDP = UnoRuntime.queryInterface(XDispatchProvider.class, xController); + + // Create special service for parsing of given URL. + final Object aURLTransformer = getMSF().createInstance("com.sun.star.util.URLTransformer"); + final XURLTransformer xURLTransformer = UnoRuntime.queryInterface(com.sun.star.util.XURLTransformer.class, aURLTransformer); + + com.sun.star.util.URL[] aURL = new com.sun.star.util.URL[1]; + aURL[0] = new com.sun.star.util.URL(); + aURL[0].Complete = ".uno:ControlProperties"; + xURLTransformer.parseStrict(aURL); + + final XDispatch xDispatch = xDP.queryDispatch(aURL[0], "_self", 0); + PropertyValue[] xEmpty = new PropertyValue[0]; + xDispatch.dispatch(aURL[0], xEmpty); + } + catch (com.sun.star.uno.Exception e) + { + } + } + + private void switchOnPropertyBrowser() + { + // This is implemented with a toggle algorithm. + switchOffPropertyBrowser(); + } + + /** + * Returns the Frame of the underlying Document + * @return Returns the Frame of the parent (underlying) Document + */ + public XFrame getFrame() + { + if (m_xFrame == null) + { + initialize(getRecordParser().getReportDocuments()); + m_xFrame = getReportDefinition().getCurrentController().getFrame(); + setPageOrientation(m_nDefaultPageOrientation, true /* NO_LAYOUT*/); + } + return m_xFrame; + } + + public boolean reconnectToDatabase(XMultiServiceFactory xMSF, PropertyValue[] Properties) + { + return false; + } + + public void insertDatabaseDatatoReportDocument(XMultiServiceFactory xMSF) + { + } + + public void StopProcess() + { + } + + public void store(String Name, int OpenMode) throws com.sun.star.uno.Exception + { + // store into the ZIP Storage + if (OpenMode == 1 /* static Report */) + { + // we will store later + return; + } + + final XCommandProcessor xProcessor = UnoRuntime.queryInterface(XCommandProcessor.class, m_documentDefinition); + final com.sun.star.ucb.Command aCommand = new com.sun.star.ucb.Command(); + aCommand.Name = "store"; + + xProcessor.execute(aCommand, xProcessor.createCommandIdentifier(), null); + + final XHierarchicalNameContainer aNameContainer = UnoRuntime.queryInterface(XHierarchicalNameContainer.class, m_aReportDocument); + aNameContainer.insertByHierarchicalName(Name, m_documentDefinition); + } + + public boolean liveupdate_addGroupNametoDocument(String[] GroupNames, String CurGroupTitle, ArrayList<String> GroupFieldVector, ArrayList<String> ReportPath, int iSelCount) + { + final int GroupCount = GroupFieldVector.size(); + if (GroupCount < MAXIMUM_GROUPCOUNT) + { + final FieldColumn CurFieldColumn = getRecordParser().getFieldColumnByTitle(CurGroupTitle); + GroupFieldVector.add(CurFieldColumn.getFieldName()); + } + return true; + } + + public void refreshGroupFields(String[] _sNewNames) + { + } + + public void liveupdate_removeGroupName(String[] NewSelGroupNames, String CurGroupTitle, ArrayList<String> GroupFieldVector) + { + final FieldColumn CurFieldColumn = getRecordParser().getFieldColumnByTitle(CurGroupTitle); + GroupFieldVector.remove(CurFieldColumn.getFieldName()); + } + + private void setPageOrientation(int nOrientation, boolean bDoLayout) + { + getReportBuilderLayouter().setPageOrientation(nOrientation); + if (bDoLayout) + { + getReportBuilderLayouter().layout(); + } + } + + public void setPageOrientation(int nOrientation) + { + setPageOrientation(nOrientation, true); + } + + public void liveupdate_changeLayoutTemplate(String LayoutTemplatePath/*, String BitmapPath*/) + { + /* Right Listbox */ + final IReportBuilderLayouter aLayouter = getReportBuilderLayouter(); + aLayouter.loadAndSetBackgroundTemplate(LayoutTemplatePath); + aLayouter.layout(); + } + + /** + * Change the current Layouter by a new one with the given Name _sName. + * If there exist no other layouter with the given name, nothing happens, the layouter will not change to + * an illegal one. + * @param _sName Name of the other layouter. + */ + public void setReportBuilderLayouterName(String _sName) + { + final IReportBuilderLayouter aCurrentLayouter = getReportBuilderLayouter(); + final IReportBuilderLayouter aNewLayouter = m_aLayoutMap.get(_sName); + if (aNewLayouter != null) + { + m_sReportBuilderLayoutName = _sName; + aNewLayouter.initializeData(aCurrentLayouter); + aNewLayouter.layout(); + } + } + + public void liveupdate_changeContentTemplate(String ContentTemplatePath) + { + /* Left Listbox */ + setReportBuilderLayouterName(ContentTemplatePath); + } + + public void layout_setupRecordSection(String TemplateName) + { + } + + public void removeTextTableAndTextSection() + { + } + + public void layout_selectFirstPage() + { + } + + private void closeReportDefinition() + { + try + { + if (m_documentDefinition != null) + { + // set the document to "not modified", to ensure that it won't ask the user before closing + XModifiable documentModify = UnoRuntime.queryInterface(XModifiable.class, m_reportDocument); + documentModify.setModified(false); + // actually close + XSubDocument subComponent = UnoRuntime.queryInterface(XSubDocument.class, m_documentDefinition); + subComponent.close(); + } + } + catch (Exception ex) + { + Logger.getLogger(ReportBuilderImplementation.class.getName()).log(Level.SEVERE, null, ex); + } + m_documentDefinition = null; + m_reportDocument = null; + } + + public void dispose() + { + getReportBuilderLayouter().dispose(); + closeReportDefinition(); + } + + public XComponent getComponent() + { + return null; + } + + public void liveupdate_changeUserFieldContent(String fieldName, String titlename) + { + } + + public void liveupdate_updateReportTitle(String _sTitleName) + { + } + + public void addReportToDBView() + { + } + + private XComponent loadReport(final String i_reportName) + { + try + { + return m_documentUI.loadComponent(DatabaseObject.REPORT, i_reportName, false); + } + catch (Exception ex) + { + Logger.getLogger(ReportBuilderImplementation.class.getName()).log(Level.SEVERE, null, ex); + } + return null; + } + + private XComponent loadReportFromDocumentDefinition() + { + final XCommandProcessor commandProcessor = UnoRuntime.queryInterface(XCommandProcessor.class, m_documentDefinition); + + com.sun.star.ucb.Command aCommand = new com.sun.star.ucb.Command(); + aCommand.Name = "open"; + try + { + final Object result = commandProcessor.execute(aCommand, commandProcessor.createCommandIdentifier(), null); + return UnoRuntime.queryInterface(XComponent.class, result); + } + catch (Exception ex) + { + Logger.getLogger(ReportBuilderImplementation.class.getName()).log(Level.SEVERE, null, ex); + } + return null; + } + + public void createAndOpenReportDocument(String i_name, boolean i_asTemplate, boolean i_openForEditing) + { + if (i_openForEditing) + { + // we won't destroy the report builder window, also don't create a document + // Do we need to reopen the report builder with the known name? + switchOnAddFieldWindow(); + switchOnPropertyBrowser(); + return; + } + + if (i_asTemplate) + { + // don't need the report definition anymore - the document it represents has already been stored + closeReportDefinition(); + + // open the report, again, this time not in design, but containing data + loadReport(i_name); + } + else + { + // execute the report from the (yet unsaved) report definition + XComponent document = loadReportFromDocumentDefinition(); + + // don't need the report definition anymore + closeReportDefinition(); + + // store the generated report + if (getRecordParser().storeDatabaseDocumentToTempPath(document, i_name)) + { + getRecordParser().addReportDocument(document, false); + } + } + + dispose(); + } + + public void initializeFieldColumns(final int _nType, final String TableName, final String[] FieldNames) + { + getRecordParser().initializeFieldColumns(FieldNames, TableName); + + final com.sun.star.wizards.db.RecordParser a = getRecordParser(); + int[] FieldTypes = new int[FieldNames.length]; + int[] FieldWidths = new int[FieldNames.length]; + for (int i = 0; i < FieldNames.length; i++) + { + FieldTypes[i] = a.FieldColumns[i].getFieldType(); + FieldWidths[i] = a.FieldColumns[i].getFieldWidth(); + } + getReportBuilderLayouter().setTableName(_nType, TableName); + getReportBuilderLayouter().insertFieldNames(FieldNames); + getReportBuilderLayouter().insertFieldTypes(FieldTypes); + getReportBuilderLayouter().insertFieldWidths(FieldWidths); + + getReportBuilderLayouter().layout(); + } + + public void setFieldTitles(String[] _aFieldTitles) + { + getRecordParser().setFieldTitles(_aFieldTitles); + + getReportBuilderLayouter().insertFieldTitles(_aFieldTitles); + getReportBuilderLayouter().layout(); + } + + public void setSorting(String[][] _aSortFieldNames) + { + getRecordParser().setSortFieldNames(_aSortFieldNames); + if (groupNames != null) + { + getRecordParser().prependSortFieldNames(groupNames); + } + getReportBuilderLayouter().insertSortingNames(_aSortFieldNames); + getReportBuilderLayouter().layout(); + } + + public void setGrouping(String[] _aGroupFieldNames) + { + groupNames = _aGroupFieldNames; + getRecordParser().prependSortFieldNames(_aGroupFieldNames); + + getReportBuilderLayouter().insertGroupNames(_aGroupFieldNames); + getReportBuilderLayouter().layout(); + } + + public String getLayoutPath() + { + return "default"; + } + private ArrayList<String> m_aReportPath; + + public ArrayList<String> getReportPath() + { + if (m_aReportPath == null) + { + // Check general availability of office paths + m_aReportPath = FileAccess.getOfficePaths(getMSF(), "Template"); + FileAccess.combinePaths(getMSF(), m_aReportPath, "/wizard/report"); + } + return m_aReportPath; + } + + public String getContentPath() + { + return PropertyNames.EMPTY_STRING; + } + + public int getDefaultPageOrientation() + { + return m_nDefaultPageOrientation; + } + + private LinkedHashMap<String, IReportBuilderLayouter> m_aLayoutMap = null; + + private void insertIntoLayoutMap(IReportBuilderLayouter _aLayout) + { + insertIntoLayoutMap(_aLayout, false); + } + + private void insertIntoLayoutMap(IReportBuilderLayouter _aLayout, boolean _bDefault) + { + if (_aLayout != null) + { + final String sName = _aLayout.getName(); + if (_bDefault) + { + m_sReportBuilderLayoutName = sName; // here we set the default layout name! + } + m_aLayoutMap.put(sName, _aLayout); + } + } + + /** + * Initialize all well known com.sun.star.wizards.report.layout.ReportBuilderLayouter Objects and create exact one instance. + */ + private LinkedHashMap<String, IReportBuilderLayouter> getLayoutMap() + { + if (m_aLayoutMap == null) + { + // The LayoutMap is empty, so we create a new LinkedHashMap + m_aLayoutMap = new LinkedHashMap<String, IReportBuilderLayouter>(); + + // TODO: We must know the name of a layouts, There should be a way to say where to find, not the names. + IReportBuilderLayouter aLayout = new com.sun.star.wizards.reportbuilder.layout.Tabular(this, m_resource); + insertIntoLayoutMap(aLayout, true); + aLayout = new com.sun.star.wizards.reportbuilder.layout.ColumnarSingleColumn(this, m_resource); + insertIntoLayoutMap(aLayout); + aLayout = new com.sun.star.wizards.reportbuilder.layout.ColumnarTwoColumns(this, m_resource); + insertIntoLayoutMap(aLayout); + aLayout = new com.sun.star.wizards.reportbuilder.layout.ColumnarThreeColumns(this, m_resource); + insertIntoLayoutMap(aLayout); + aLayout = new com.sun.star.wizards.reportbuilder.layout.InBlocksLabelsAbove(this, m_resource); + insertIntoLayoutMap(aLayout); + aLayout = new com.sun.star.wizards.reportbuilder.layout.InBlocksLabelsLeft(this, m_resource); + insertIntoLayoutMap(aLayout); + + } + return m_aLayoutMap; + } + + /** + * Return a string array array with all found layouts + * At the moment these layout are hard coded + */ + public String[][] getDataLayout() + { + String[][] ContentFiles; + ContentFiles = new String[2][]; + String[] a = new String[getLayoutMap().size()]; + String[] b = new String[getLayoutMap().size()]; + + // run through the whole layoutmap and + final Set<String> aKeys = getLayoutMap().keySet(); + final Iterator<String> aKeyIterator = aKeys.iterator(); + int i = 0; + while (aKeyIterator.hasNext()) + { + final String sKey = aKeyIterator.next(); + a[i] = sKey; + final IReportBuilderLayouter aLayouter = m_aLayoutMap.get(sKey); + b[i++] = aLayouter.getLocalizedName(); + } + + ContentFiles[1] = a; + ContentFiles[0] = b; + return ContentFiles; + } + private String m_sDefaultHeaderLayoutPath; + + public String[][] getHeaderLayout() + { + String[][] LayoutFiles; + try + { + // TODO: check different languages in header layouts + ArrayList<String> aReportPath = FileAccess.getOfficePaths(getMSF(), "Template"); + FileAccess.combinePaths(getMSF(), aReportPath, "/wizard/report"); + + LayoutFiles = FileAccess.getFolderTitles(getMSF(), null, aReportPath, ".otr"); + } + catch (com.sun.star.wizards.common.NoValidPathException e) + { + // if there are problems, don't show anything is a little bit hard. + LayoutFiles = new String[2][]; + String[] a = new String[] { "DefaultLayoutOfHeaders" }; + String[] b = new String[] { "default" }; + LayoutFiles[1] = a; + LayoutFiles[0] = b; + } + for (int i = 0; i < LayoutFiles[0].length; i++) + { + if (LayoutFiles[0][i].equals("default")) + { + m_sDefaultHeaderLayoutPath = LayoutFiles[1][i]; + break; + } + } + exchangeLayoutTitlesWithLocalisedOnes(LayoutFiles); + return LayoutFiles; + } + + private void exchangeLayoutTitlesWithLocalisedOnes(String[][] LayoutFiles) + { + for(int i = 0; i < LayoutFiles[0].length; ++i) + { + if( LayoutFiles[0][i] == null) { break;} + if( LayoutFiles[0][i].equals("default") ) + { + LayoutFiles[0][i] = m_resource.getResText("RID_REPORT_100"); + } + } + } + + public XReportDefinition getReportDefinition() + { + if (m_reportDocument == null) + { + throw new NullPointerException("Report Definition is not already initialized, check if you too early access the report definition."); + } + return m_reportDocument; + } + + public XMultiServiceFactory getGlobalMSF() + { + return getMSF(); + } + + public void importReportData(ReportWizard aWizard) + { + } + + public String getDefaultHeaderLayout() + { + return m_sDefaultHeaderLayoutPath; + } + + public void setCommand(String _sCommand) + { + getRecordParser().Command = _sCommand; + getReportDefinition().setCommand(_sCommand); + } + + public void setCommandType(int _nCommand) + { + getReportDefinition().setCommandType(_nCommand); + } + + public void checkInvariants() throws java.lang.Exception + { + final String sDefaultHeaderLayoutPath = getDefaultHeaderLayout(); + if (sDefaultHeaderLayoutPath == null) + { + throw new java.io.IOException("default.otr"); + } + + FileAccess aAccess = new FileAccess(getGlobalMSF()); + if (!aAccess.exists(sDefaultHeaderLayoutPath, true)) + { + throw new java.io.IOException("default.otr"); + } + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarSingleColumn.java b/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarSingleColumn.java new file mode 100644 index 000000000..e31e6cc96 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarSingleColumn.java @@ -0,0 +1,91 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.Rectangle; +import com.sun.star.report.XSection; +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.ui.UIConsts; + +public class ColumnarSingleColumn extends ReportBuilderLayouter +{ + + public ColumnarSingleColumn(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource) + { + super(_xDefinitionAccess, _aResource); + } + + public String getName() + { + return "ColumnarSingleColumnLayoutOfData"; + } + + public String getLocalizedName() + { + return getResource().getResText("RID_REPORT_81"); + } + + @Override + protected void insertDetailFields() + { + copyDetailProperties(); + + final String[] aFieldTitleNames = getFieldTitleNames(); + if (aFieldTitleNames == null) + { + return; + } + final String[] aFieldNames = getFieldNames(); + if (aFieldNames == null) + { + return; + } + + final XSection xSection = getReportDefinition().getDetail(); + + Rectangle aRect = new Rectangle(); + + final int nLabelWidth = getMaxLabelWidth(); + final SectionObject aSOLabel = getDesignTemplate().getDetailLabel(); + aSOLabel.setFontToBold(); + final SectionObject aSOTextField = getDesignTemplate().getDetailTextField(); + + final int nWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - getLeftGroupIndent(getCountOfGroups()) - nLabelWidth; + + for (int i = 0; i < aFieldNames.length; i++) + { + aRect.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + final String sLabel = aFieldTitleNames[i]; + aRect = insertLabel(xSection, sLabel, aRect, nLabelWidth, aSOLabel); + final String sFieldName = convertToFieldName(aFieldNames[i]); + aRect = insertFormattedField(xSection, sFieldName, aRect, nWidth, aSOTextField); + int nHeight = aRect.Height; + aRect.Y += Math.max(aSOLabel.getHeight(LayoutConstants.LabelHeight), nHeight); + } + aRect.Y += aSOLabel.getHeight(LayoutConstants.EmptyLineHeight); // one empty line + xSection.setHeight(aRect.Y); + doNotBreakInTable(xSection); + } + + @Override + protected void insertDetailFieldTitles(int lastGroupPosition) + { + // we won't extra field titles + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarThreeColumns.java b/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarThreeColumns.java new file mode 100644 index 000000000..81d4ad50a --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarThreeColumns.java @@ -0,0 +1,49 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.ui.*; + +public class ColumnarThreeColumns extends ColumnarTwoColumns +{ + + public ColumnarThreeColumns(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource) + { + super(_xDefinitionAccess, _aResource); + } + + @Override + public String getName() + { + return "ColumnarThreeColumnsLayoutOfData"; + } + + @Override + public String getLocalizedName() + { + return getResource().getResText("RID_REPORT_83"); + } + + @Override + protected void insertDetailFields() + { + insertDetailFields(3); + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarTwoColumns.java b/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarTwoColumns.java new file mode 100644 index 000000000..6d21dce05 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/ColumnarTwoColumns.java @@ -0,0 +1,123 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.Rectangle; +import com.sun.star.report.XSection; +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.ui.UIConsts; + +public class ColumnarTwoColumns extends ReportBuilderLayouter +{ + + public ColumnarTwoColumns(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource) + { + super(_xDefinitionAccess, _aResource); + } + + public String getName() + { + return "ColumnarTwoColumnsLayoutOfData"; + } + + public String getLocalizedName() + { + return getResource().getResText("RID_REPORT_82"); + } + + @Override + protected void insertDetailFields() + { + insertDetailFields(2); + } + + protected void insertDetailFields(int _nColumns) + { + copyDetailProperties(); + + if (_nColumns < 1) + { + return; + } + final String[] aFieldTitleNames = getFieldTitleNames(); + if (aFieldTitleNames == null) + { + return; + } + final String[] aFieldNames = getFieldNames(); + if (aFieldNames == null) + { + return; + } + + final XSection xSection = getReportDefinition().getDetail(); + + Rectangle aRect = new Rectangle(); + + final int nLabelWidth = getMaxLabelWidth(); // 3000; + + final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - getLeftGroupIndent(getCountOfGroups()); + int i = 0; + int nRows = aFieldNames.length / _nColumns; + if ((aFieldNames.length % _nColumns) != 0) + { + ++nRows; + } + final int nWidth = (nUsablePageWidth - nLabelWidth * _nColumns) / _nColumns; + if (nWidth < 0) + { + // TODO: error message in logging + return; + } + + final SectionObject aSOLabel = getDesignTemplate().getDetailLabel(); + aSOLabel.setFontToBold(); + final SectionObject aSOTextField = getDesignTemplate().getDetailTextField(); + int nMaxHeight = 0; + for (int x = 0; x < _nColumns; x++) + { + aRect.Y = 0; + for (int y = 0; y < nRows; y++) + { + aRect.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()) + x * (nWidth + nLabelWidth); + if (i < aFieldNames.length) + { + final String sLabel = aFieldTitleNames[i]; + aRect = insertLabel(xSection, sLabel, aRect, nLabelWidth, aSOLabel); + final String sFieldName = convertToFieldName(aFieldNames[i]); + aRect = insertFormattedField(xSection, sFieldName, aRect, nWidth, aSOTextField); + + aRect.Y += Math.max(aSOLabel.getHeight(LayoutConstants.LabelHeight), aRect.Height); + ++i; + } + } + nMaxHeight = Math.max(aRect.Y, nMaxHeight); + } + aRect.Y = Math.max(aSOLabel.getHeight(LayoutConstants.LabelHeight) * nRows, nMaxHeight); + aRect.Y += aSOLabel.getHeight(LayoutConstants.EmptyLineHeight); // one empty line + xSection.setHeight(aRect.Y); + doNotBreakInTable(xSection); + } + + @Override + protected void insertDetailFieldTitles(int lastGroupPosition) + { + // we won't extra field titles + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/DesignTemplate.java b/wizards/com/sun/star/wizards/reportbuilder/layout/DesignTemplate.java new file mode 100644 index 000000000..a7343d901 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/DesignTemplate.java @@ -0,0 +1,302 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.beans.PropertyValue; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.report.XFixedText; +import com.sun.star.report.XFormattedField; +import com.sun.star.report.XGroup; +import com.sun.star.report.XGroups; +import com.sun.star.report.XReportDefinition; +import com.sun.star.report.XSection; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.wizards.common.Properties; +import com.sun.star.wizards.common.PropertyNames; + +public class DesignTemplate +{ + + private XReportDefinition m_xReportDefinition; + + private DesignTemplate() + { + } + + // All functions from XReportDefinition, we use + + XGroups getGroups() + { + return m_xReportDefinition.getGroups(); + } + + XSection getDetail() + { + return m_xReportDefinition.getDetail(); + } + + boolean getReportHeaderOn() + { + return m_xReportDefinition.getReportHeaderOn(); + } + + XSection getReportHeader() throws com.sun.star.container.NoSuchElementException + { + return m_xReportDefinition.getReportHeader(); + } + + boolean getReportFooterOn() + { + return m_xReportDefinition.getReportFooterOn(); + } + + XSection getReportFooter() throws com.sun.star.container.NoSuchElementException + { + return m_xReportDefinition.getReportFooter(); + } + + boolean getPageHeaderOn() + { + return m_xReportDefinition.getPageHeaderOn(); + } + + XSection getPageHeader() throws com.sun.star.container.NoSuchElementException + { + return m_xReportDefinition.getPageHeader(); + } + + boolean getPageFooterOn() + { + return m_xReportDefinition.getPageFooterOn(); + } + + XSection getPageFooter() throws com.sun.star.container.NoSuchElementException + { + return m_xReportDefinition.getPageFooter(); + } + private SectionObject m_aDetailLabel; + private SectionObject m_aDetailTextField; + private SectionObject[] m_aGroupLabel; + private SectionObject[] m_aGroupTextField; + + SectionObject getDetailLabel() + { + if (m_aDetailLabel == null) + { + return SectionEmptyObject.create(); + } + return m_aDetailLabel; + } + + SectionObject getDetailTextField() + { + if (m_aDetailTextField == null) + { + return SectionEmptyObject.create(); + } + return m_aDetailTextField; + } + + SectionObject getGroupTextField(int _nGroup) + { + return getGroupSectionObject(m_aGroupTextField, _nGroup); + } + + SectionObject getGroupLabel(int _nGroup) + { + return getGroupSectionObject(m_aGroupLabel, _nGroup); + } + + private SectionObject getGroupSectionObject(SectionObject _aGroupList[], int _nGroup) + { + SectionObject a = null; + if (_nGroup < _aGroupList.length) + { + a = _aGroupList[_nGroup]; + } + else + { + // if there are not enough groups, the last one will win + if (_aGroupList.length > 0) + { + a = _aGroupList[_aGroupList.length - 1]; + } + } + // we show if the group is null + if (a == null) + { + a = SectionEmptyObject.create(); + // an empty group has to use bold font + a.setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.BOLD)); + } + return a; + } + + // we analyse the loaded ReportDefinition, we want to know the FontDescriptor of all XSections + private void analyseReportDefinition() + { + final XSection xDetailSection = m_xReportDefinition.getDetail(); + final int nDetailCount = xDetailSection.getCount(); + for (int i = 0; i < nDetailCount; i++) + { + try + { + Object aObj = xDetailSection.getByIndex(i); + // is aObj a label + // is aObj a textfield + // m_aDetailLabel_FD + // m_aDetailTextField_FD + XFixedText aFixedText = UnoRuntime.queryInterface(XFixedText.class, aObj); + if (aFixedText != null && + m_aDetailLabel == null) + { + m_aDetailLabel = SectionLabel.create(aFixedText); + } + else + { + XFormattedField aFormattedField = UnoRuntime.queryInterface(XFormattedField.class, aObj); + if (aFormattedField != null && + m_aDetailTextField == null) + { + m_aDetailTextField = SectionTextField.create(aFormattedField); + } + } + } + catch (com.sun.star.lang.IndexOutOfBoundsException ex) + { + } + catch (com.sun.star.lang.WrappedTargetException ex) + { + } + } + + final XGroups xGroups = m_xReportDefinition.getGroups(); + final int nGroupCount = xGroups.getCount(); + // create a m_aGroupLabel_FD[] + // create a m_aGroupTextField_FD[] + m_aGroupLabel = new SectionObject[nGroupCount]; + m_aGroupTextField = new SectionObject[nGroupCount]; + + for (int nGroup = 0; nGroup < nGroupCount; nGroup++) + { + try + { + Object aGroup = xGroups.getByIndex(nGroup); + XGroup xGroup = UnoRuntime.queryInterface(XGroup.class, aGroup); + XSection xGroupSection = xGroup.getHeader(); + + final int nCount = xGroupSection.getCount(); + for (int i = 0; i < nCount; i++) + { + try + { + Object aObj = xGroupSection.getByIndex(i); + XFixedText aFixedText = UnoRuntime.queryInterface(XFixedText.class, aObj); + // is aObj a label + // is aObj a textfield + if (aFixedText != null && + m_aGroupLabel[nGroup] == null) + { + m_aGroupLabel[nGroup] = SectionLabel.create(aFixedText); + } + else + { + XFormattedField aFormattedField = UnoRuntime.queryInterface(XFormattedField.class, aObj); + if (aFormattedField != null && + m_aGroupTextField[nGroup] == null) + { + m_aGroupTextField[nGroup] = SectionTextField.create(aFormattedField); + } + } + } + catch (com.sun.star.lang.IndexOutOfBoundsException ex) + { + } + catch (com.sun.star.lang.WrappedTargetException ex) + { + } + } + } + catch (com.sun.star.container.NoSuchElementException ex) + { + } + catch (com.sun.star.lang.IndexOutOfBoundsException ex) + { + } + catch (com.sun.star.lang.WrappedTargetException ex) + { + } + } + } + + /** + * close our current ReportDefinition + */ + void close() + { + try + { + m_xReportDefinition.close(true); + } + catch (com.sun.star.util.CloseVetoException e) + { + } + } + + /** + * create a new DesignTemplate by try to load an otr file from the given path. + * Internally we store the loaded ReportDefinition. + */ + public static DesignTemplate create(XMultiServiceFactory _xMSF, String _sPath) + { + DesignTemplate a = new DesignTemplate(); + try + { + a.load(_xMSF, _sPath); + } + catch (com.sun.star.lang.WrappedTargetRuntimeException e) + { + // this should not happen + a = null; + throw new java.lang.RuntimeException(e); + } + catch (com.sun.star.uno.Exception e) + { + a = null; + } + catch (Exception e) + { + a = null; + } + return a; + } + + private void load(XMultiServiceFactory _xMSF, String _sPath) throws com.sun.star.uno.Exception + { + final Object aObj = _xMSF.createInstance("com.sun.star.report.ReportDefinition"); + m_xReportDefinition = UnoRuntime.queryInterface(XReportDefinition.class, aObj); + + PropertyValue[] aLoadProps = new PropertyValue[2]; + aLoadProps[0] = Properties.createProperty(PropertyNames.URL, _sPath); + aLoadProps[1] = Properties.createProperty(PropertyNames.READ_ONLY, Boolean.TRUE); + + m_xReportDefinition.load(aLoadProps); + analyseReportDefinition(); + } + +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/InBlocksLabelsAbove.java b/wizards/com/sun/star/wizards/reportbuilder/layout/InBlocksLabelsAbove.java new file mode 100644 index 000000000..08dbc2db5 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/InBlocksLabelsAbove.java @@ -0,0 +1,148 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.Rectangle; +import com.sun.star.report.XSection; +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.ui.*; + +public class InBlocksLabelsAbove extends ColumnarTwoColumns +{ + + public InBlocksLabelsAbove(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource) + { + super(_xDefinitionAccess, _aResource); + } + + @Override + public String getName() + { + return "InBlocksLabelsAboveLayoutOfData"; + } + + @Override + public String getLocalizedName() + { + return getResource().getResText("RID_REPORT_85"); + } + + @Override + protected void insertDetailFields() + { + copyDetailProperties(); + + final String[] aFieldTitleNames = getFieldTitleNames(); + if (aFieldTitleNames == null) + { + return; + } + final String[] aFieldNames = getFieldNames(); + if (aFieldNames == null) + { + return; + } + + final XSection xSection = getReportDefinition().getDetail(); + + Rectangle aRectLabels = new Rectangle(); + Rectangle aRectFields = new Rectangle(); + + + final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - getLeftGroupIndent(getCountOfGroups()); + + int i = 0; + int nCount = aFieldTitleNames.length; + aRectLabels.Y = 0; + aRectLabels.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + + aRectFields.Y = LayoutConstants.LabelHeight; + aRectFields.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + + // first run only calculates the width. + int nDelta = 0; + int nFieldWidth = 3000; + while (nCount > 0) + { + aRectFields.X += nFieldWidth; + + final int nNextX = aRectFields.X + nFieldWidth; + if (nNextX > (getPageWidth() - getRightPageIndent())) + { + // all other values are not from interest. + break; + } + + ++i; + --nCount; + } + final int nDeltaTotal = nUsablePageWidth - i * nFieldWidth; + nDelta = nDeltaTotal; + if (i > 0) + { + nDelta = nDeltaTotal / i; + } + + aRectLabels.Y = 0; + aRectLabels.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + + final SectionObject aSOLabel = getDesignTemplate().getDetailLabel(); + aSOLabel.setFontToBold(); + final SectionObject aSOTextField = getDesignTemplate().getDetailTextField(); + + aRectFields.Y = aSOLabel.getHeight(LayoutConstants.LabelHeight); + aRectFields.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + i = 0; + nCount = aFieldTitleNames.length; + int nLastHeight = 0; + while (nCount > 0) + { + final String sLabel = aFieldTitleNames[i]; + final int nLabelWidth = 3000 + nDelta; + aRectLabels = insertLabel(xSection, sLabel, aRectLabels, nLabelWidth, aSOLabel); + final String sFieldName = convertToFieldName(aFieldNames[i]); + nFieldWidth = 3000 + nDelta; + aRectFields = insertFormattedField(xSection, sFieldName, aRectFields, nFieldWidth, aSOTextField); + nLastHeight = Math.max(nLastHeight, aRectFields.Height); + int nNextX = aRectFields.X + nFieldWidth; + if ((nNextX > (getPageWidth() - getRightPageIndent())) && nCount > 1) + { + int nHeight = (aSOLabel.getHeight(LayoutConstants.LabelHeight) + Math.max(aSOTextField.getHeight(LayoutConstants.FormattedFieldHeight), nLastHeight)); + nLastHeight = 0; + aRectLabels.Y += nHeight; // 2 * label height + aRectLabels.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + + aRectFields.Y += nHeight; + aRectFields.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + } + ++i; + --nCount; + } + aRectFields.Y += Math.max(aSOTextField.getHeight(LayoutConstants.FormattedFieldHeight), nLastHeight); + aRectFields.Y += aSOTextField.getHeight(LayoutConstants.EmptyLineHeight); // one empty line + xSection.setHeight(aRectFields.Y); + doNotBreakInTable(xSection); + } + + @Override + protected void insertDetailFieldTitles(int lastGroupPosition) + { + // we won't extra field titles + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/InBlocksLabelsLeft.java b/wizards/com/sun/star/wizards/reportbuilder/layout/InBlocksLabelsLeft.java new file mode 100644 index 000000000..cf88cb29a --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/InBlocksLabelsLeft.java @@ -0,0 +1,119 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.Rectangle; +import com.sun.star.report.XSection; +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.ui.*; + +public class InBlocksLabelsLeft extends ColumnarTwoColumns +{ + + public InBlocksLabelsLeft(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource) + { + super(_xDefinitionAccess, _aResource); + } + + @Override + public String getName() + { + return "InBlocksLabelsLeftLayoutOfData"; + } + + @Override + public String getLocalizedName() + { + return getResource().getResText("RID_REPORT_84"); + } + + @Override + protected void insertDetailFields() + { + copyDetailProperties(); + + final String[] aFieldTitleNames = getFieldTitleNames(); + if (aFieldTitleNames == null) + { + return; + } + final String[] aFieldNames = getFieldNames(); + if (aFieldNames == null) + { + return; + } + + final XSection xSection = getReportDefinition().getDetail(); + + Rectangle aRectLabelFields = new Rectangle(); + + final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - getLeftGroupIndent(getCountOfGroups()); + + final int nLabelWidth = getMaxLabelWidth(); // 3000; + int nFieldWidth = 3000; + + final int nFactor = nUsablePageWidth / (nLabelWidth + nFieldWidth); + int nDeltaTotal = 0; + int nDelta = 0; + if (nFactor > 0) + { + nDeltaTotal = nUsablePageWidth - (nFactor * (nLabelWidth + nFieldWidth)); + nDelta = nDeltaTotal / nFactor; + } + + int i = 0; + int nCount = aFieldTitleNames.length; + aRectLabelFields.Y = 0; + aRectLabelFields.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + + SectionObject aSOLabel = getDesignTemplate().getDetailLabel(); + aSOLabel.setFontToBold(); + SectionObject aSOTextField = getDesignTemplate().getDetailTextField(); + int nLastHeight = 0; + while (nCount > 0) + { + final String sLabel = aFieldTitleNames[i]; + aRectLabelFields = insertLabel(xSection, sLabel, aRectLabelFields, nLabelWidth, aSOLabel); + final String sFieldName = convertToFieldName(aFieldNames[i]); + nFieldWidth = 3000 + nDelta; + aRectLabelFields = insertFormattedField(xSection, sFieldName, aRectLabelFields, nFieldWidth, aSOTextField); + nLastHeight = Math.max(aRectLabelFields.Height, nLastHeight); + final int nNextX = aRectLabelFields.X + nLabelWidth + nFieldWidth; + if (nNextX > (getPageWidth() - getRightPageIndent())) + { + // TODO: label height is fix + aRectLabelFields.Y += Math.max(aSOTextField.getHeight(LayoutConstants.FormattedFieldHeight), nLastHeight); + nLastHeight = 0; + aRectLabelFields.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + } + ++i; + --nCount; + } + aRectLabelFields.Y += Math.max(aSOLabel.getHeight(LayoutConstants.EmptyLineHeight), nLastHeight); // one empty line + xSection.setHeight(aRectLabelFields.Y); + doNotBreakInTable(xSection); + } + + @Override + protected void insertDetailFieldTitles(int lastGroupPosition) + { + // we won't extra field titles + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/LayoutConstants.java b/wizards/com/sun/star/wizards/reportbuilder/layout/LayoutConstants.java new file mode 100644 index 000000000..9b294a12d --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/LayoutConstants.java @@ -0,0 +1,37 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.wizards.reportbuilder.layout; + +public class LayoutConstants +{ + public static final int LabelHeight = 500; + public static final int FormattedFieldHeight = 500; + public static final int EmptyLineHeight = 500; + + public static final int BinaryHeight = 4000; + public static final int MemoFieldHeight = 4000; + + public static final int LineHeight = 250; + + /** + * Groups will indent + * This is the factor (5mm) which will multiply with the current indent + */ + public static final int IndentFactorWidth = 500; +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/ReportBuilderLayouter.java b/wizards/com/sun/star/wizards/reportbuilder/layout/ReportBuilderLayouter.java new file mode 100644 index 000000000..cfa2071a3 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/ReportBuilderLayouter.java @@ -0,0 +1,1582 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.FontDescriptor; +import com.sun.star.awt.Rectangle; +import com.sun.star.awt.Size; +import com.sun.star.awt.XControl; +import com.sun.star.awt.XControlModel; +import com.sun.star.awt.XLayoutConstrains; +import com.sun.star.awt.XUnitConversion; +import com.sun.star.awt.XWindow; +import com.sun.star.awt.XWindowPeer; +import com.sun.star.beans.Property; +import com.sun.star.beans.PropertyAttribute; +import com.sun.star.beans.XPropertySet; +import com.sun.star.beans.XPropertySetInfo; +import com.sun.star.container.XEnumeration; +import com.sun.star.container.XNameAccess; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.report.XFixedLine; +import com.sun.star.report.XFixedText; +import com.sun.star.report.XFormattedField; +import com.sun.star.report.XGroup; +import com.sun.star.report.XGroups; +import com.sun.star.report.XImageControl; +import com.sun.star.report.XReportComponent; +import com.sun.star.report.XReportControlModel; +import com.sun.star.report.XReportDefinition; +import com.sun.star.report.XSection; +import com.sun.star.drawing.XShape; +import com.sun.star.sdbc.DataType; +import com.sun.star.style.XStyle; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.util.XNumberFormatTypes; +import com.sun.star.util.XNumberFormats; +import com.sun.star.util.XNumberFormatsSupplier; +import com.sun.star.wizards.common.Configuration; +import com.sun.star.wizards.common.FileAccess; +import com.sun.star.wizards.common.Helper; +import com.sun.star.wizards.common.PropertyNames; +import com.sun.star.wizards.common.PropertySetHelper; +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.report.IReportBuilderLayouter; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.ui.UIConsts; + +import java.util.HashMap; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class is abstract and more like a helper for create different layouts for Report Builder Wizard. + */// TODO: let a little bit place between 2 formatted fields +// TODO: move all sectionobjects which have a connect to the right max page width to left if there is a orientation change. +abstract public class ReportBuilderLayouter implements IReportBuilderLayouter +{ + + private IReportDefinitionReadAccess m_xReportDefinitionReadAccess; + private final Resource m_aResource; + private String[][] m_aSortNames; + + /** + * dispose the ReportBuilderLayouter + */ + public void dispose() + { + closeDesignTemplate(); + m_xReportDefinitionReadAccess = null; + } + + /** + * The Constructor is protected, this is an abstract class, use Tabular or other to create an instance. + * @param _xDefinitionAccess + * @param _aResource + */ + protected ReportBuilderLayouter(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource) + { + m_xReportDefinitionReadAccess = _xDefinitionAccess; + m_aResource = _aResource; + } + + /** + * Access to the current ReportDefinition + * @return the ReportDefinition + */ + public XReportDefinition getReportDefinition() + { + // we have to ask our parent for this value + return m_xReportDefinitionReadAccess.getReportDefinition(); + } + + /** + * Access to the global MultiServiceFactory + * @return the global Service Factory + */ + private XMultiServiceFactory getGlobalMSF() + { + return m_xReportDefinitionReadAccess.getGlobalMSF(); + } + + /** + * Layout the complete report new, by all information we know until this time. + * + * If there are some information less, it is no problem for this function, they will be leaved out. + * It is possible to call this function after every change, but be careful, could take a little bit longer. + */ + public synchronized void layout() + { + try + { + // we bring the clear and insert methods together, this should be a little bit smoother + clearReportHeader(); + insertReportHeader(); + + clearReportFooter(); + insertReportFooter(); + + clearPageHeader(); + insertPageHeader(); + + clearPageFooter(); + insertPageFooter(); + + clearGroups(); + int lastGroupPosition = insertGroups(); + + clearDetails(); + insertDetailFieldTitles(lastGroupPosition); + insertDetailFields(); + } + catch (java.lang.ArrayIndexOutOfBoundsException e) + { + // could happen, if you change the count of values + } + catch (java.lang.RuntimeException e) + { + throw e; + } + catch (Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + + + /** + * Remove all Groups + */ + private void clearGroups() + { + final XGroups xGroups = getReportDefinition().getGroups(); + while (xGroups.hasElements()) + { + try + { + xGroups.removeByIndex(0); + } + catch (com.sun.star.uno.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + + /** + * Remove all fields + * @param _xSectionToClear + */ + private void emptySection(XSection _xSectionToClear) + { + if (_xSectionToClear == null) + { + return; + } + while (_xSectionToClear.hasElements()) + { + try + { + final Object aObj = _xSectionToClear.getByIndex(0); + final XShape aShape = UnoRuntime.queryInterface(XShape.class, aObj); + _xSectionToClear.remove(aShape); + } + catch (com.sun.star.uno.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + + } + } + + private void clearDetails() + { + final XSection xSection = getReportDefinition().getDetail(); + emptySection(xSection); + } + + /** + * @param _nGroupCount + * @return the left indent in 1/100mm + */ + protected int getLeftGroupIndent(int _nGroupCount) + { +// TODO: Fix values for group indent (1/2cm) only the first 2 groups + int nIndent = 0; + final int MAX_INDENT = 2; + if (_nGroupCount <= MAX_INDENT) + { + nIndent = _nGroupCount * LayoutConstants.IndentFactorWidth; + } + else + { + nIndent = MAX_INDENT * LayoutConstants.IndentFactorWidth; + } + return nIndent; + } + + private int m_nLeftIndent = -1; + + /** + * Get left page indent. + * The left indent is the area on the left side which will no be printed. + * The default is 2000 1/100mm what is 2cm of DIN A4. + * @return the left indent in 1/100mm + */ + protected int getLeftPageIndent() + { + if (m_nLeftIndent < 0) + { + m_nLeftIndent = getFromPageStyles("LeftMargin", 2000); + } + return m_nLeftIndent; + } + + private int m_nRightIndent = -1; + + /** + * Get right page indent. + * The right indent is the area on the right side which will no be printed. + * The default is 2000 1/100mm what is 2cm of DIN A4. + * @return the right indent in 1/100mm + */ + protected int getRightPageIndent() + { + if (m_nRightIndent < 0) + { + m_nRightIndent = getFromPageStyles("RightMargin", 2000); + } + return m_nRightIndent; + } + + private XStyle getUsedStyle(String _sStyleName) + { + XStyle aUsedStyle = null; + final XNameAccess xNameAccess = getReportDefinition().getStyleFamilies(); + try + { + // get all Page Styles + final Object aPageStylesObj = xNameAccess.getByName(_sStyleName); + final XNameAccess xContainer = UnoRuntime.queryInterface(XNameAccess.class, aPageStylesObj); + + // step over all Page Styles, search the one which is in use + final String[] aElementNames = xContainer.getElementNames(); + for (int i = 0; i < aElementNames.length; i++) + { + final String sName = aElementNames[i]; + final Object aObj = xContainer.getByName(sName); + final XStyle xStyle = UnoRuntime.queryInterface(XStyle.class, aObj); + if (xStyle.isInUse()) + { + aUsedStyle = xStyle; + break; + } + } + } + catch (com.sun.star.uno.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + return aUsedStyle; + } + + private int getFromPageStyles(String _sStyleName, int _nDefault) + { + int nValue = _nDefault; + final XStyle xStyle = getUsedStyle("PageStyles"); + if (xStyle != null) + { + // we found the page style which is in use + final PropertySetHelper aHelper = new PropertySetHelper(xStyle); + nValue = aHelper.getPropertyValueAsInteger(_sStyleName, nValue); + } + return nValue; + } + + private void setToPageStyles(String _sStyleName, Object _aObj) + { + final XStyle xStyle = getUsedStyle("PageStyles"); + if (xStyle != null) + { + final PropertySetHelper aHelper = new PropertySetHelper(xStyle); + aHelper.setPropertyValueDontThrow(_sStyleName, _aObj); + } + } + + private int m_nPageWidth = -1; + + /** + * Get page width. The default is 21000 1/100mm what is 21cm of DIN A4. + * @return the Width of the page in 1/100mm + */ + protected int getPageWidth() + { + if (m_nPageWidth < 0) + { + m_nPageWidth = getFromPageStyles(PropertyNames.PROPERTY_WIDTH, 21000); + } + return m_nPageWidth; + } + + + /** + * Stores the Group names. To insert/create a report with such group names, call layout() + */ + public void insertGroupNames(String[] _aGroupNames) + { + m_aGroupNames = _aGroupNames; + } + + public void insertSortingNames(String[][] _aSortFieldNames) + { + m_aSortNames = _aSortFieldNames; + } + + protected void copyGroupProperties(int _nGroup) + { + if (getDesignTemplate() != null) + { + try + { + final XGroups xForeignGroups = getDesignTemplate().getGroups(); + if (_nGroup < xForeignGroups.getCount()) + { + XGroup xForeignGroup = UnoRuntime.queryInterface(XGroup.class, xForeignGroups.getByIndex(_nGroup)); + XSection xForeignGroupSection = xForeignGroup.getHeader(); + + if (xForeignGroupSection != null) + { + final XGroups xGroups = getReportDefinition().getGroups(); + Object aGroup = xGroups.getByIndex(_nGroup); + XGroup xGroup = UnoRuntime.queryInterface(XGroup.class, aGroup); + XSection xGroupSection = xGroup.getHeader(); + + // copy Properties + copyProperties(xForeignGroupSection, xGroupSection); + } + } + } + catch (Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + + private int insertGroups() + { + final XGroups xGroups = getReportDefinition().getGroups(); + int lastGroupPosition = -1; + + if (m_aGroupNames != null) + { + final int nLeftPageIndent = getLeftPageIndent(); + final int nLabelWidth = getMaxLabelWidth(); // 3000; + final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - getLeftGroupIndent(getCountOfGroups()); + final int nFieldWidth = nUsablePageWidth - nLabelWidth; + + XGroup aLastGroup = null; + // after done with all groups, we need access to the last group, for set property 'KeepTogether' so we remember it. + + for (int i = 0; i < m_aGroupNames.length; i++) + { + lastGroupPosition = i; + final XGroup xGroup = xGroups.createGroup(); + aLastGroup = xGroup; + + xGroup.setExpression(m_aGroupNames[i]); + xGroup.setHeaderOn(true); + + try + { + int nCount = xGroups.getCount(); + xGroups.insertByIndex(nCount, xGroup); + final XSection xGroupSection = xGroup.getHeader(); + copyGroupProperties(nCount); + + Rectangle aRect = new Rectangle(); + aRect.X = nLeftPageIndent + getLeftGroupIndent(i); + SectionObject aSO = getDesignTemplate().getGroupLabel(i); + aRect = insertLabel(xGroupSection, getTitleFromFieldName(m_aGroupNames[i]), aRect, nLabelWidth, aSO); + final String sGroupName = convertToFieldName(m_aGroupNames[i]); + aSO = getDesignTemplate().getGroupTextField(i); + aRect = insertFormattedField(xGroupSection, sGroupName, aRect, nFieldWidth, aSO); + int height = aRect.Height; + + // draw a line under the label/formattedfield + aRect.X = nLeftPageIndent + getLeftGroupIndent(i); + aRect.Y = aRect.Height; + final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X; + final int nLineHeight = LayoutConstants.LineHeight; + insertHorizontalLine(xGroupSection, aRect, nLineWidth, nLineHeight); + xGroupSection.setHeight(height + nLineHeight); + } + catch (com.sun.star.uno.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + + // hold the inner group together + if (aLastGroup != null) + { + doNotBreakInTable(aLastGroup); + } + } + if (m_aSortNames != null) + { + for (String[] sortFieldName : m_aSortNames) + { + try + { + final XGroup xGroup = xGroups.createGroup(); + xGroup.setExpression(sortFieldName[0]); + xGroup.setSortAscending(PropertyNames.ASC.equals(sortFieldName[1])); + xGroup.setHeaderOn(false); + int nCount = xGroups.getCount(); + xGroups.insertByIndex(nCount, xGroup); + } + catch (java.lang.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + return lastGroupPosition; + } + + + /** + * Give a list off all field title names to insert the field title names, call layout() + */ + public void insertFieldTitles(String[] _aFieldTitleNames) + { + m_aFieldTitleNames = _aFieldTitleNames; + } + + + private String getTitleFromFieldName(String _sField) + { + for (int i = 0; i < m_aFieldNames.length; i++) + { + if (m_aFieldNames[i].equals(_sField)) + { + return m_aFieldTitleNames[i]; + } + } + return PropertyNames.EMPTY_STRING; + } + + private int getTypeFromFieldName(String _sField) + { + for (int i = 0; i < m_aFieldNames.length; i++) + { + if (m_aFieldNames[i].equals(_sField)) + { + return m_aFieldTypes[i]; + } + } + return 0; + } + + private boolean listContains(String[] _aList, String _aValue) + { + for (int i = 0; i < _aList.length; i++) + { + if (_aList[i].equals(_aValue)) + { + return true; + } + } + return false; + } + + + /** + * Helper to get all field names without the names which are already in the group names + * @param _aList + * @param _aGetResultFrom + * @return + */ + private String[] getNamesWithoutGroupNames(String[] _aList, String[] _aGetResultFrom) + { + if (_aList == null) + { + return new String[] + { + }; /* empty list */ + } + if (getCountOfGroups() == 0) + { + if (_aGetResultFrom != null) + { + return _aGetResultFrom; + } + return _aList; + } + final int nNewLength = _aList.length - getCountOfGroups(); + String[] aNewList = new String[nNewLength]; + int j = 0; + for (int i = 0; i < _aList.length; i++) + { + final String sField = _aList[i]; + if (listContains(m_aGroupNames, sField)) + { + continue; + } + if (_aGetResultFrom != null) + { + aNewList[j++] = _aGetResultFrom[i]; + } + else + { + aNewList[j++] = sField; + } + if (j == nNewLength) + { + break; // Emergency break, we leave the result list. + } + } + return aNewList; + } + + + protected int calculateFieldWidth(int _nLeftIndent, int _nFieldCount) + { + int nWidth = 3000; + if (_nFieldCount > 0) + { + nWidth = (getPageWidth() - getLeftPageIndent() - getRightPageIndent() - _nLeftIndent) / _nFieldCount; + } + return nWidth; + } + + protected String[] getFieldTitleNames() + { + return getNamesWithoutGroupNames(m_aFieldNames, m_aFieldTitleNames); + } + + + abstract protected void insertDetailFieldTitles(int lastGroupPosition); + + + /** + * Give a list off all field names to insert the field names, call layout() + */ + public void insertFieldNames(String[] _aFieldNames) + { + m_aFieldNames = _aFieldNames; + } + + public void insertFieldTypes(int[] _aFieldTypes) + { + m_aFieldTypes = _aFieldTypes; + } + + public void insertFieldWidths(int[] _aFieldWidths) + { + m_aFieldWidths = _aFieldWidths; + } + + protected int getCountOfGroups() + { + return ((m_aGroupNames == null) ? 0 : m_aGroupNames.length); + } + + + protected String[] getFieldNames() + { + return getNamesWithoutGroupNames(m_aFieldNames, null); + } + + abstract protected void insertDetailFields(); + + protected void copyDetailProperties() + { + if (getDesignTemplate() != null) + { + try + { + XSection xForeignSection = getDesignTemplate().getDetail(); + if (xForeignSection != null) + { + XSection xSection = getReportDefinition().getDetail(); + + // copy Properties + copyProperties(xForeignSection, xSection); + } + } + catch (Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + + protected Rectangle insertLabel(XSection _xSection, String _sLabel, Rectangle _aRect, int _nWidth, SectionObject _aSO) + { + if (_xSection != null) + { + try + { + final Object aFixedText = getMSFofReportDefinition().createInstance("com.sun.star.report.FixedText"); + final XFixedText xFixedText = UnoRuntime.queryInterface(XFixedText.class, aFixedText); + + + int nHeight = LayoutConstants.LabelHeight; // default height of label is fixed. + if (_aSO != null) + { + if (_aSO instanceof SectionEmptyObject) + { + float fCharWeight = _aSO.getCharWeight(com.sun.star.awt.FontWeight.NORMAL); + if (fCharWeight > 0.1f) + { + xFixedText.setCharWeight(fCharWeight); + } + } + else + { +// TODO: there seems to be some problems with copy all properties from the design template to the current design + final FontDescriptor aFD = _aSO.getFontDescriptor(); + if (aFD != null) + { + xFixedText.setFontDescriptor(aFD); + copyProperties(_aSO.getParent(), xFixedText); + } + nHeight = _aSO.getHeight(LayoutConstants.LabelHeight); + } + } + xFixedText.setLabel(_sLabel); + + xFixedText.setPositionX(_aRect.X); + xFixedText.setPositionY(_aRect.Y); + + // Width will calculate from outside. + // We have to set, because there exist no right default (0) + xFixedText.setWidth(_nWidth); + _aRect.X += _nWidth; + xFixedText.setHeight(nHeight); + _xSection.add(xFixedText); + } + catch (com.sun.star.uno.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + return _aRect; + } + + + protected String convertToFieldName(String _sElementName) + { + final StringBuffer aDataField = new StringBuffer(32); + aDataField.append("field:[").append(_sElementName).append(']'); + return aDataField.toString(); + + } + + private String convertFromFieldName(String _sName) + { + if (_sName.startsWith("field:[")) + { + int nCloseBrace = _sName.lastIndexOf(']'); + return _sName.substring(7, nCloseBrace).trim(); + } + return _sName; + } + + + /** + * Insert an already formatted field name into a given section + * + * Use 'convertToFieldName(dbfield)' to convert a dbfield name in the right. + * + * @param _xSection in which section the formatted field will store + * @param _sFormattedfield as String a dbfield or another function + * @param _aRect .X, .Y are the absolute position (1/100mm) where the formatted field will set + * @param _nWidth the width of the field in 1/100mm + * @param _aSO + * @return a new Rectangle with the new Rect.X position, Rect.Y will not change. + */ + protected Rectangle insertFormattedField(XSection _xSection, String _sFormattedfield, Rectangle _aRect, int _nWidth, SectionObject _aSO) + { + return insertFormattedField(_xSection, _sFormattedfield, _aRect, _nWidth, _aSO, (short) com.sun.star.awt.TextAlign.LEFT); + } + + private Rectangle insertFormattedField(XSection _xSection, String _sFormattedfield, Rectangle _aRect, int _nWidth, SectionObject _aSO, short _nAlignment) + { + if (_xSection != null) + { + try + { + Object aField; + int nHeight = LayoutConstants.FormattedFieldHeight; + + int nType = getTypeFromFieldName(convertFromFieldName(_sFormattedfield)); + if (nType == DataType.BINARY + || nType == DataType.VARBINARY + || nType == DataType.LONGVARBINARY) + { + aField = getMSFofReportDefinition().createInstance("com.sun.star.report.ImageControl"); + nHeight = LayoutConstants.BinaryHeight; + } + else + { + aField = getMSFofReportDefinition().createInstance("com.sun.star.report.FormattedField"); + nHeight = LayoutConstants.FormattedFieldHeight; + if (nType == DataType.LONGVARCHAR) /* memo */ + + { + nHeight = LayoutConstants.MemoFieldHeight; // special case for memo + } + } + _aRect.Height = nHeight; + + final XReportControlModel xReportControlModel = UnoRuntime.queryInterface(XReportControlModel.class, aField); + if (xReportControlModel != null) + { + // #i86907# not documented right in idl description. + xReportControlModel.setDataField(_sFormattedfield); + if (_aSO != null) + { + // TODO: there seems to be some problems with copy all properties from the design template to the current design + final FontDescriptor aFD = _aSO.getFontDescriptor(); + if (aFD != null) + { + xReportControlModel.setFontDescriptor(aFD); + copyProperties(_aSO.getParent(), xReportControlModel); + } + nHeight = _aSO.getHeight(nHeight); + } + xReportControlModel.setPositionX(_aRect.X); + xReportControlModel.setPositionY(_aRect.Y); + xReportControlModel.setWidth(_nWidth); + _aRect.X += _nWidth; + xReportControlModel.setHeight(nHeight); + + if (nType == DataType.BINARY + || nType == DataType.VARBINARY + || nType == DataType.LONGVARBINARY) + { + final XImageControl xImageControl = UnoRuntime.queryInterface(XImageControl.class, xReportControlModel); + if (xImageControl != null) + { + xImageControl.setScaleMode(com.sun.star.awt.ImageScaleMode.ISOTROPIC); + } + } + else + { + try + { + xReportControlModel.setParaAdjust(_nAlignment); + } + catch (com.sun.star.beans.UnknownPropertyException ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + // spezial case rpt:now() (default date format) + if (_sFormattedfield.equals("rpt:now()")) + { + final XFormattedField xFormattedField = UnoRuntime.queryInterface(XFormattedField.class, xReportControlModel); + + XNumberFormatsSupplier x = xFormattedField.getFormatsSupplier(); + XNumberFormats xFormats = x.getNumberFormats(); + XNumberFormatTypes x3 = UnoRuntime.queryInterface(XNumberFormatTypes.class, xFormats); + com.sun.star.lang.Locale aLocale = new com.sun.star.lang.Locale(); + aLocale.Country = Locale.getDefault().getCountry(); + aLocale.Language = Locale.getDefault().getLanguage(); + + int nFormat = x3.getStandardFormat(com.sun.star.util.NumberFormat.DATE, aLocale); + xFormattedField.setFormatKey(nFormat); + } + _xSection.add(xReportControlModel); + } + } + catch (com.sun.star.uno.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + return _aRect; + } + + +// TODO: check with Query, this code will not work with Queries + public void setTableName(int _aType, String _sTableName) + { + m_aCommandType = _aType; + m_sTableName = _sTableName; + + getReportDefinition().setCommandType(_aType); + getReportDefinition().setCommand(_sTableName); + } + private XMultiServiceFactory m_xMSF; + + private XMultiServiceFactory getMSFofReportDefinition() + { + if (m_xMSF == null) + { + m_xMSF = UnoRuntime.queryInterface(XMultiServiceFactory.class, getReportDefinition()); + } + return m_xMSF; + } + + + + + private Rectangle insertHorizontalLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight) + { + return insertLine(_xSection, _aRect, _nWidth, _nHeight, 0); + } + + private Rectangle insertLine(XSection _xSection, Rectangle _aRect, int _nWidth, int _nHeight, int _nOrientation) + { + if (_xSection != null) + { + try + { + final Object aFixedLine = getMSFofReportDefinition().createInstance("com.sun.star.report.FixedLine"); + final XFixedLine xFixedLine = UnoRuntime.queryInterface(XFixedLine.class, aFixedLine); + + xFixedLine.setOrientation(_nOrientation); + // TODO: line width is fixed + xFixedLine.setLineWidth(8); + + xFixedLine.setPositionX(_aRect.X); + xFixedLine.setPositionY(_aRect.Y); + + xFixedLine.setWidth(_nWidth); + _aRect.X += _nWidth; + xFixedLine.setHeight(_nHeight); + _xSection.add(xFixedLine); + } + catch (com.sun.star.uno.Exception ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + return _aRect; + } + + + private void clearReportHeader() + { + XSection xSection; + try + { + if (getReportDefinition().getReportHeaderOn()) + { + xSection = getReportDefinition().getReportHeader(); + emptySection(xSection); + } + } + catch (com.sun.star.container.NoSuchElementException ex) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, ex); + } + } + + private void insertReportHeader() + { + if (getDesignTemplate() != null) + { + if (getDesignTemplate().getReportHeaderOn()) + { + // copy all Section information from Page Header to our Header + try + { + XSection xForeignSection = getDesignTemplate().getReportHeader(); + + if (xForeignSection != null) + { + getReportDefinition().setReportHeaderOn(true); + XSection xSection = getReportDefinition().getReportHeader(); + + // copy Sections + copySection(xForeignSection, xSection); + } + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + else + { + // we won't a page header + getReportDefinition().setReportHeaderOn(false); + } + } + } + + private void clearReportFooter() + { + XSection xSection; + try + { + if (getReportDefinition().getReportFooterOn()) + { + xSection = getReportDefinition().getReportFooter(); + emptySection(xSection); + } + } + catch (com.sun.star.container.NoSuchElementException e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + + private void insertReportFooter() + { + if (getDesignTemplate() != null) + { + if (getDesignTemplate().getReportFooterOn()) + { + // copy all Section information from Page Header to our Header + try + { + XSection xForeignSection = getDesignTemplate().getReportFooter(); + + if (xForeignSection != null) + { + getReportDefinition().setReportFooterOn(true); + XSection xSection = getReportDefinition().getReportFooter(); + + // copy Sections + copySection(xForeignSection, xSection); + } + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + else + { + // we won't a page header + getReportDefinition().setReportFooterOn(false); + } + } + } + + + private void clearPageHeader() + { + XSection xSection; + try + { + if (getReportDefinition().getPageHeaderOn()) + { + xSection = getReportDefinition().getPageHeader(); + emptySection(xSection); + } + } + catch (com.sun.star.container.NoSuchElementException e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + + private void clearPageFooter() + { + XSection xSection; + try + { + if (getReportDefinition().getPageFooterOn()) + { + xSection = getReportDefinition().getPageFooter(); + emptySection(xSection); + } + } + catch (com.sun.star.container.NoSuchElementException e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + + public void setPageOrientation(int _nOrientation) + { + final int nWidth = getFromPageStyles(PropertyNames.PROPERTY_WIDTH, 0); + final int nHeight = getFromPageStyles(PropertyNames.PROPERTY_HEIGHT, 0); + + if (com.sun.star.wizards.report.ReportLayouter.SOOPTLANDSCAPE == _nOrientation) + { + setToPageStyles("IsLandscape", Boolean.TRUE); + if (nWidth < nHeight) + { + setToPageStyles(PropertyNames.PROPERTY_WIDTH, Integer.valueOf(nHeight)); + setToPageStyles(PropertyNames.PROPERTY_HEIGHT, Integer.valueOf(nWidth)); + } + } + else + { + setToPageStyles("IsLandscape", Boolean.FALSE); + if (nHeight < nWidth) + { + setToPageStyles(PropertyNames.PROPERTY_WIDTH, Integer.valueOf(nHeight)); + setToPageStyles(PropertyNames.PROPERTY_HEIGHT, Integer.valueOf(nWidth)); + } + } + // dirty the PageWidth + m_nPageWidth = -1; + } + + /** + * Returns the width and height of a given string (_sText) in 1/100mm drawn in the given font descriptor. + * 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. + * + * @param _sText + * @param _aFont + * @return width of given text in 1/100mm + */ + private Size getPreferredSize(String _sText, FontDescriptor _aFont) + { + Size aSizeMM_100TH = new Size(0, 0); + try + { + + final Object aFixedTextModel = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlFixedTextModel"); + final XControlModel xFixedTextModel = UnoRuntime.queryInterface(XControlModel.class, aFixedTextModel); + + final PropertySetHelper aPropertySetHelper = new PropertySetHelper(xFixedTextModel); + aPropertySetHelper.setPropertyValueDontThrow(PropertyNames.FONT_DESCRIPTOR, _aFont); + + final Object aUnoCtrlFixedText = getGlobalMSF().createInstance("com.sun.star.awt.UnoControlFixedText"); + + final XWindow xWindow = UnoRuntime.queryInterface(XWindow.class, aUnoCtrlFixedText); + xWindow.setVisible(false); + + final XControl xControl = UnoRuntime.queryInterface(XControl.class, aUnoCtrlFixedText); + xControl.setModel(xFixedTextModel); + + final com.sun.star.awt.XFixedText xFixedText = UnoRuntime.queryInterface(com.sun.star.awt.XFixedText.class, aUnoCtrlFixedText); + xFixedText.setText(_sText); + + final XLayoutConstrains xLayoutConstraints = UnoRuntime.queryInterface(XLayoutConstrains.class, aUnoCtrlFixedText); + final Size aSizeInPixel = xLayoutConstraints.getPreferredSize(); + + final XWindowPeer xPeerOfReportDefinition = UnoRuntime.queryInterface(XWindowPeer.class, getReportDefinition().getCurrentController().getFrame().getComponentWindow()); + xControl.createPeer(null, xPeerOfReportDefinition); + + final XWindowPeer x = xControl.getPeer(); + + final XUnitConversion xConversion = UnoRuntime.queryInterface(XUnitConversion.class, x); + aSizeMM_100TH = xConversion.convertSizeToLogic(aSizeInPixel, com.sun.star.util.MeasureUnit.MM_100TH); + // we don't need the created objects any longer + final XComponent xFixedTextDeleter = UnoRuntime.queryInterface(XComponent.class, xFixedText); + xFixedTextDeleter.dispose(); + + final XComponent xFixedTextModelDeleter = UnoRuntime.queryInterface(XComponent.class, aFixedTextModel); + xFixedTextModelDeleter.dispose(); + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + return aSizeMM_100TH; + } + + private String getTableName() + { + if (m_sTableName != null) + { + return m_sTableName; + } + return PropertyNames.EMPTY_STRING; + } + + private String getUserNameFromConfiguration() + { + String sFirstName = PropertyNames.EMPTY_STRING; + String sLastName = PropertyNames.EMPTY_STRING; + try + { + Object oProdNameAccess = Configuration.getConfigurationRoot(getGlobalMSF(), "org.openoffice.UserProfile/Data", false); + sFirstName = (String) Helper.getUnoObjectbyName(oProdNameAccess, "givenname"); + sLastName = (String) Helper.getUnoObjectbyName(oProdNameAccess, "sn"); + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + return sFirstName + PropertyNames.SPACE + sLastName; + } + + /** + * Helper function, to copy all not read only properties of _xFromSection to _xToSection + * @param _aFrom + * @param _aTo + */ + private void copyProperties(Object _aFrom, Object _aTo) + { + XPropertySet xFrom = UnoRuntime.queryInterface(XPropertySet.class, _aFrom); + XPropertySet xTo = UnoRuntime.queryInterface(XPropertySet.class, _aTo); + + + XPropertySetInfo xForeignPropInfo = xFrom.getPropertySetInfo(); + XPropertySetInfo xSectionPropInfo = xTo.getPropertySetInfo(); + Property[] aAllProperties = xForeignPropInfo.getProperties(); + for (int i = 0; i < aAllProperties.length; i++) + { + String sPropertyName = aAllProperties[i].Name; + if (xSectionPropInfo.hasPropertyByName(sPropertyName)) + { + try + { + Property aDestProp = xForeignPropInfo.getPropertyByName(sPropertyName); + if ((aDestProp.Attributes & PropertyAttribute.READONLY) == 0) + { + xTo.setPropertyValue(sPropertyName, xFrom.getPropertyValue(sPropertyName)); + } + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + } + } + + /** + * Helper function to copy the whole content of _xFromSection to the _xToSection + * @param _xFromSection + * @param _xToSection + */ + private void copySection(XSection _xFromSection, XSection _xToSection) + { + copyProperties(_xFromSection, _xToSection); + + try + { + XEnumeration xEnum = _xFromSection.createEnumeration(); + while (xEnum.hasMoreElements()) + { + Object aEnumObj = xEnum.nextElement(); + XReportComponent aComponent = UnoRuntime.queryInterface(XReportComponent.class, aEnumObj); + + if (aComponent != null) + { + Object aClone = aComponent.createClone(); + if (aClone != null) + { + XShape aShape = UnoRuntime.queryInterface(XShape.class, aClone); + + // normally 'createClone' will create a real clone of the component, + // but there seems some problems, we have to control. + copyProperties(aComponent, aClone); + + // aShape.setPosition(aComponent.getPosition()); + // aShape.setSize(aComponent.getSize()); + _xToSection.add(aShape); + } + } + } + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + + private void insertPageHeader() + { + if (getDesignTemplate() != null) + { + if (getDesignTemplate().getPageHeaderOn()) + { + // copy all Section information from Page Header to our Header + try + { + XSection xForeignSection = getDesignTemplate().getPageHeader(); + + if (xForeignSection != null) + { + getReportDefinition().setPageHeaderOn(true); + XSection xSection = getReportDefinition().getPageHeader(); + + // copy Sections + copySection(xForeignSection, xSection); + } + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + else + { + // we won't a page header + // getReportDefinition().setPageHeaderOn(true); + getReportDefinition().setPageHeaderOn(false); + } + } + else + { + if (getReportDefinition() == null) + { + return; + } + // there is no foreign report definition + // TODO: #i86902# rpt:Title() out of the document + + // TODO: #i86902# rpt:Author() can't set with something like rpt:author() + // TODO: #i86902# more fieldnames need. + final String sTitleTitle = getResource().getResText("RID_REPORT_86"); // "Title:" + final String sTitle = getTableName(); // "Default title, this is a first draft report generated by the new report wizard."; + final String sAuthorTitle = getResource().getResText("RID_REPORT_87"); // "Author:" + final String sAuthor = getUserNameFromConfiguration(); // "You"; + final String sDateTitle = getResource().getResText("RID_REPORT_88"); // "Date:" + // TODO: #i86911# Date: we need to set the style of the date. + final String sDate = "rpt:now()"; + + try + { + getReportDefinition().setPageHeaderOn(true); + XSection xSection = null; + xSection = getReportDefinition().getPageHeader(); + + Rectangle aRect = new Rectangle(); + aRect.X = getLeftPageIndent(); + SectionObject aSOLabel = SectionEmptyObject.create(); + aSOLabel.setFontToBold(); + aRect.Y = aSOLabel.getHeight(LayoutConstants.LabelHeight); + + final int nWidth = 3000; + + aRect = insertLabel(xSection, sTitleTitle, aRect, nWidth, aSOLabel); + + final int nTitleWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent() - 3000; + aRect = insertLabel(xSection, sTitle, aRect, nTitleWidth, aSOLabel); + + aRect.Y += aSOLabel.getHeight(LayoutConstants.LabelHeight) + LayoutConstants.LineHeight; + + aRect.X = getLeftPageIndent(); + aRect = insertLabel(xSection, sAuthorTitle, aRect, nWidth, aSOLabel); + aRect = insertLabel(xSection, sAuthor, aRect, nTitleWidth, aSOLabel); + + aRect.Y += aSOLabel.getHeight(LayoutConstants.LabelHeight); + + aRect.X = getLeftPageIndent(); + aRect = insertLabel(xSection, sDateTitle, aRect, nWidth, aSOLabel); + aRect = insertFormattedField(xSection, sDate, aRect, nTitleWidth, aSOLabel); + + aRect.Y += aSOLabel.getHeight(LayoutConstants.FormattedFieldHeight) + LayoutConstants.LineHeight; + + // draw a line under the label/formattedfield + aRect.X = getLeftPageIndent(); + final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X; + final int nLineHeight = LayoutConstants.LineHeight; + insertHorizontalLine(xSection, aRect, nLineWidth, nLineHeight); + + aRect.Y += nLineHeight; + + xSection.setHeight(aRect.Y); + } + catch (com.sun.star.uno.Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + } + + private void insertPageFooter() + { + if (getDesignTemplate() != null) + { + if (getDesignTemplate().getPageFooterOn()) + { + try + { + XSection xForeignSection = getDesignTemplate().getPageFooter(); + + if (xForeignSection != null) + { + getReportDefinition().setPageFooterOn(true); + XSection xSection = getReportDefinition().getPageFooter(); + + // copy Sections + copySection(xForeignSection, xSection); + } + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + else + { + getReportDefinition().setPageFooterOn(false); + } + } + else + { + if (getReportDefinition() == null) + { + return; + } + + // TODO: how should we arrive this code (set page and pagecount in the middle of the page footer) + // If there exists a design template, don't use it. + + // we don't have a default report definition + final String sPageOf = getResource().getResText("RID_REPORT_89"); // 'Page #page# of #count#' + + // Convert + // 'Page #page# of #count#' + // to something like + // '\"Page \" & PageNumber() & \" of \" & PageCount()' + // due to the fact that it is not fixed, where #page# or #count# occurs, we make it + // a little bit trickier. + // we first surround the string with double quotes, + // second, replace the #...# + // last, we remove double 'double quotes'. + final String sSurroundDoubleQuotes = "\"" + sPageOf + "\""; + final String sPageNumber = sSurroundDoubleQuotes.replaceAll("#page#", "\" & PageNumber() & \""); + final String sPageCount = sPageNumber.replaceAll("#count#", "\" & PageCount() & \""); + final String sNoLastUnusedQuotes = sPageCount.replaceAll(" & \\\"\\\"", PropertyNames.EMPTY_STRING); + final String sNoFirstUnusedQuotes = sNoLastUnusedQuotes.replaceAll("\\\"\\\" & ", PropertyNames.EMPTY_STRING); + + final int nUsablePageWidth = getPageWidth() - getLeftPageIndent() - getRightPageIndent(); + + try + { + getReportDefinition().setPageFooterOn(true); + XSection xSection = null; + xSection = getReportDefinition().getPageFooter(); + + Rectangle aRect = new Rectangle(); + aRect.X = getLeftPageIndent(); + + // draw a line over the label/formattedfield + final int nLineWidth = getPageWidth() - getRightPageIndent() - aRect.X; + final int nLineHeight = LayoutConstants.LineHeight; + insertHorizontalLine(xSection, aRect, nLineWidth, nLineHeight); + + aRect.Y += nLineHeight; + aRect.Y += LayoutConstants.LabelHeight; + + aRect.X = getLeftPageIndent(); + + aRect = insertFormattedField(xSection, "rpt:" + sNoFirstUnusedQuotes, aRect, nUsablePageWidth, null, (short) com.sun.star.awt.TextAlign.CENTER); + + aRect.Y += LayoutConstants.FormattedFieldHeight + LayoutConstants.LineHeight; + xSection.setHeight(aRect.Y); + } + catch (Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + } + + protected Resource getResource() + { + return m_aResource; + } + private int m_aCommandType; // Table or Query + private String m_sTableName; + private String[] m_aGroupNames; + private String[] m_aFieldNames; + private String[] m_aFieldTitleNames; + private int[] m_aFieldWidths; + private int[] m_aFieldTypes; + private DesignTemplate m_xDesignTemplate = null; + + public void initializeData(IReportBuilderLayouter _aOther) + { + if (_aOther instanceof ReportBuilderLayouter) + { + final ReportBuilderLayouter aOther = (ReportBuilderLayouter) _aOther; + m_aCommandType = aOther.m_aCommandType; + m_sTableName = aOther.m_sTableName; + m_aGroupNames = aOther.m_aGroupNames; + m_aFieldNames = aOther.m_aFieldNames; + m_aFieldTitleNames = aOther.m_aFieldTitleNames; + m_aFieldWidths = aOther.m_aFieldWidths; + m_aFieldTypes = aOther.m_aFieldTypes; + m_xDesignTemplate = aOther.m_xDesignTemplate; + + // dirty PageWidth + m_nPageWidth = -1; + } + } + + /** + * Get the maximal label width of all labels + * @return the width in 1/100mm + */ + protected int getMaxLabelWidth() + { + int nWidth = 0; + final String[] aFieldTitles = m_aFieldTitleNames; // we want all Field Titles here // getFieldTitleNames(); + for (int i = 0; i < aFieldTitles.length; i++) + { + final String sLabel = aFieldTitles[i]; + nWidth = Math.max(nWidth, getLabelWidth(sLabel)); + } + for (int i = 0; i < m_aGroupNames.length; i++) + { + final String sGroupName = m_aGroupNames[i]; + final SectionObject a = getDesignTemplate().getGroupLabel(i); + final FontDescriptor aFD = a.getFontDescriptor(); + nWidth = Math.max(nWidth, getLabelWidth(sGroupName, aFD)); + } + + if (nWidth == 0) + { + nWidth = 3000; + } + else + { + nWidth += 500; + } + return nWidth; + } + + /** + * Get width of a given string (Label) in 1/100mm + * @param _sLabel + * @return the width in 1/100mm + */ + private int getLabelWidth(String _sLabel) + { + return getLabelWidth(_sLabel, 0.0f, 0.0f); + } + private XFixedText m_aFixedTextHelper = null; + private HashMap<String, Integer> m_aLabelWidthMap; + + private int getLabelWidth(String _sLabel, FontDescriptor _aFD) + { + float fCharWeight = 0.0f; + float fCharHeight = 0.0f; + if (_aFD != null) + { + fCharWeight = _aFD.Weight; + fCharHeight = _aFD.Height; + } + return getLabelWidth(_sLabel, fCharWeight, fCharHeight); + } + + private int getLabelWidth(String _sLabel, float _nCharWeight, float _nCharHeight) + { + int nWidth = 0; + + if (m_aLabelWidthMap == null) + { + m_aLabelWidthMap = new HashMap<String, Integer>(); + } + // At first, try to get the Width out of a HashMap (Cache) + StringBuffer aKey = new StringBuffer(40); + final String sKey = aKey.append(_sLabel).append(_nCharWeight).append(_nCharHeight).toString(); + if (m_aLabelWidthMap.containsKey(sKey)) + { + final Object aWidth = m_aLabelWidthMap.get(sKey); + final Integer aIntegerWidth = (Integer) aWidth; + nWidth = aIntegerWidth.intValue(); + } + else + { + try + { + if (m_aFixedTextHelper == null) + { + final Object aFixedText = getMSFofReportDefinition().createInstance("com.sun.star.report.FixedText"); + m_aFixedTextHelper = UnoRuntime.queryInterface(XFixedText.class, aFixedText); + } + + m_aFixedTextHelper.setLabel(_sLabel); + if (_nCharWeight > 0.1f) + { + m_aFixedTextHelper.setCharWeight(_nCharWeight); + } + if (_nCharHeight > 0.1f) + { + m_aFixedTextHelper.setCharHeight(_nCharHeight); + } + + final FontDescriptor xFont = m_aFixedTextHelper.getFontDescriptor(); + final Size aSize = getPreferredSize(_sLabel, xFont); + nWidth = aSize.Width; + // cache the found width + m_aLabelWidthMap.put(sKey, Integer.valueOf(nWidth)); + } + catch (com.sun.star.uno.Exception e) + { + Logger.getLogger(ReportBuilderLayouter.class.getName()).log(Level.SEVERE, null, e); + } + } + return nWidth; + } + + protected void doNotBreakInTable(Object _xSectionOrGroup) + { + final PropertySetHelper aHelper = new PropertySetHelper(_xSectionOrGroup); + aHelper.setPropertyValueDontThrow("KeepTogether", Boolean.TRUE); + } + + protected DesignTemplate getDesignTemplate() + { + if (m_xDesignTemplate == null) + { + // initialise the report definition. + String sDefaultHeaderLayout = m_xReportDefinitionReadAccess.getDefaultHeaderLayout(); + loadAndSetBackgroundTemplate(sDefaultHeaderLayout); + } + return m_xDesignTemplate; + } + + /** + * If there already exists a foreign report definition, which we use to get the layout from + * close it. + * Veto is not allowed here. + */ + private void closeDesignTemplate() + { + if (m_xDesignTemplate != null) + { + m_xDesignTemplate.close(); + m_xDesignTemplate = null; + } + } + + /** + * load the given string as a template and use its content to paint the other + */ + public void loadAndSetBackgroundTemplate(String LayoutTemplatePath) + { + closeDesignTemplate(); + + String sName = FileAccess.getFilename(LayoutTemplatePath); + if (sName.equalsIgnoreCase("default.otr_") + || LayoutTemplatePath.equals("DefaultLayoutOfHeaders")) + { + // this is the default layout, we don't want to have a layout for this. + } + else + { + XMultiServiceFactory xMSF = getGlobalMSF(); + m_xDesignTemplate = DesignTemplate.create(xMSF, LayoutTemplatePath); + } + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/SectionEmptyObject.java b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionEmptyObject.java new file mode 100644 index 000000000..f8f03c4c0 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionEmptyObject.java @@ -0,0 +1,40 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.FontDescriptor; + +public class SectionEmptyObject extends SectionObject +{ + + protected SectionEmptyObject() + { + m_aParentObject = null; + } + + public static SectionObject create() + { + return new SectionEmptyObject(); + } + + @Override + public FontDescriptor getFontDescriptor() + { + return null; + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/SectionLabel.java b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionLabel.java new file mode 100644 index 000000000..8a4027033 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionLabel.java @@ -0,0 +1,55 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.FontDescriptor; +import com.sun.star.report.XFixedText; + +public class SectionLabel extends SectionObject +{ + + private SectionLabel(XFixedText _aFixedText) + { + m_aParentObject = _aFixedText; + } + + public static SectionObject create(XFixedText _aFixedText) + { + return new SectionLabel(_aFixedText); + } + + /** + * Return the current FontDescriptor + */ + @Override + public FontDescriptor getFontDescriptor() + { + FontDescriptor a = null; + try + { + final XFixedText aLabel = (XFixedText) getParent(); + a = aLabel.getFontDescriptor(); + } + catch (com.sun.star.beans.UnknownPropertyException e) + { + } + return a; + } +} + + diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/SectionObject.java b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionObject.java new file mode 100644 index 000000000..c6d3887cc --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionObject.java @@ -0,0 +1,70 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.FontDescriptor; +import com.sun.star.wizards.common.PropertyNames; +import com.sun.star.wizards.common.PropertySetHelper; + +abstract public class SectionObject +{ + + Object m_aParentObject; // this could be FixedText or FormattedField or null + private PropertySetHelper m_aPropertySetHelper; + + public SectionObject() + { + m_aParentObject = null; + } + + protected Object getParent() + { + return m_aParentObject; + } + + abstract public FontDescriptor getFontDescriptor(); + + private PropertySetHelper getPropertySetHelper() + { + if (m_aPropertySetHelper == null) + { + m_aPropertySetHelper = new PropertySetHelper(getParent()); + } + return m_aPropertySetHelper; + } + + public int getHeight(int _nDefault) + { + return getPropertySetHelper().getPropertyValueAsInteger(PropertyNames.PROPERTY_HEIGHT, _nDefault); + } + + public float getCharWeight(float _nDefault) + { + return(float) getPropertySetHelper().getPropertyValueAsDouble("CharWeight", _nDefault); + } + + public void setFontToBold() + { + setPropertyValue("CharWeight", new Float(com.sun.star.awt.FontWeight.BOLD)); + } + + public void setPropertyValue(String _sKey, Object _nValue) + { + getPropertySetHelper().setPropertyValueDontThrow(_sKey, _nValue); + } +} diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/SectionTextField.java b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionTextField.java new file mode 100644 index 000000000..bc7be4e88 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/SectionTextField.java @@ -0,0 +1,52 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.FontDescriptor; +import com.sun.star.report.XFormattedField; + +public class SectionTextField extends SectionObject +{ + + private SectionTextField(XFormattedField _aFormattedField) + { + m_aParentObject = _aFormattedField; + // We would like to know, what properties are in this object. + } + + public static SectionObject create(XFormattedField _aFormattedField) + { + return new SectionTextField(_aFormattedField); + } + + @Override + public FontDescriptor getFontDescriptor() + { + FontDescriptor a = null; + try + { + XFormattedField aField = (XFormattedField) getParent(); + a = aField.getFontDescriptor(); + } + catch (com.sun.star.beans.UnknownPropertyException e) + { + } + return a; + } +} + diff --git a/wizards/com/sun/star/wizards/reportbuilder/layout/Tabular.java b/wizards/com/sun/star/wizards/reportbuilder/layout/Tabular.java new file mode 100644 index 000000000..814de5a93 --- /dev/null +++ b/wizards/com/sun/star/wizards/reportbuilder/layout/Tabular.java @@ -0,0 +1,139 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +package com.sun.star.wizards.reportbuilder.layout; + +import com.sun.star.awt.Rectangle; +import com.sun.star.report.XGroup; +import com.sun.star.report.XGroups; +import com.sun.star.report.XSection; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.wizards.common.Resource; +import com.sun.star.wizards.report.IReportDefinitionReadAccess; +import com.sun.star.wizards.ui.UIConsts; + +public class Tabular extends ReportBuilderLayouter +{ + + public Tabular(IReportDefinitionReadAccess _xDefinitionAccess, Resource _aResource) + { + super(_xDefinitionAccess, _aResource); + } + + public String getName() + { + return "DefaultLayoutOfData"; + } + + public String getLocalizedName() + { + return getResource().getResText("RID_REPORT_80"); + } + + @Override + protected void insertDetailFields() + { + copyDetailProperties(); + + String[] aFieldNames = getFieldNames(); + if (aFieldNames == null) + { + return; + } + if (aFieldNames.length == 0) + { + return; + } + + final XSection xSection = getReportDefinition().getDetail(); + + Rectangle aRect = new Rectangle(); + aRect.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + + final int nWidth = calculateFieldWidth(getLeftGroupIndent(getCountOfGroups()), aFieldNames.length); + final SectionObject aSO = getDesignTemplate().getDetailTextField(); + int nHeight = LayoutConstants.FormattedFieldHeight; + for (int i = 0; i < aFieldNames.length; i++) + { + final String sFieldName = convertToFieldName(aFieldNames[i]); + aRect = insertFormattedField(xSection, sFieldName, aRect, nWidth, aSO); + nHeight = Math.max(aRect.Height, nHeight); + } + nHeight = Math.max(aSO.getHeight(nHeight), nHeight); + xSection.setHeight(nHeight); + } + + @Override + protected void insertDetailFieldTitles(int lastGroupPosition) + { + final String[] aFieldTitleNames = getFieldTitleNames(); + if (aFieldTitleNames == null || aFieldTitleNames.length == 0) + { + return; + } + try + { + SectionObject aSO = null; + final XGroups xGroups = getReportDefinition().getGroups(); + final XGroup xGroup; + if (lastGroupPosition == -1) + { + // Spezial case, there is no Group. + xGroup = xGroups.createGroup(); + xGroup.setHeaderOn(true); + + xGroups.insertByIndex(xGroups.getCount(), xGroup); + copyGroupProperties(0); + aSO = getDesignTemplate().getDetailLabel(); + aSO.setFontToBold(); + } + else + { + // we insert the titles in the last group + xGroup = UnoRuntime.queryInterface(XGroup.class, xGroups.getByIndex(lastGroupPosition)); + + // We don't need to copy the GroupProperties, because this is done in the insertGroup() member function + // copyGroupProperties(0); + aSO = getDesignTemplate().getGroupLabel(lastGroupPosition); + } + + XSection xSection = xGroup.getHeader(); + Rectangle aRect = new Rectangle(); + aRect.X = getLeftPageIndent() + getLeftGroupIndent(getCountOfGroups()); + if (lastGroupPosition == -1) + { + xSection.setHeight(0); // group height + a little empty line) + aRect.Y = 0; + } + else + { + aRect.Y = xSection.getHeight() + LayoutConstants.LineHeight; + } + + final int nWidth = calculateFieldWidth(getLeftGroupIndent(getCountOfGroups()), aFieldTitleNames.length); + + for (int i = 0; i < aFieldTitleNames.length; i++) + { + aRect = insertLabel(xSection, aFieldTitleNames[i], aRect, nWidth, aSO); + } + xSection.setHeight(xSection.getHeight() + aSO.getHeight(LayoutConstants.LabelHeight)); + } + catch (com.sun.star.uno.Exception e) + { + } + } +} |