/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ package com.sun.star.wizards.form; import com.sun.star.awt.Point; import com.sun.star.awt.Size; import com.sun.star.container.XNameContainer; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.sdbc.DataType; import com.sun.star.task.XStatusIndicator; import com.sun.star.uno.AnyConverter; import com.sun.star.uno.Exception; import com.sun.star.wizards.common.Helper; import com.sun.star.wizards.common.Resource; import com.sun.star.wizards.db.*; import com.sun.star.wizards.document.Control; import com.sun.star.wizards.document.DatabaseControl; import com.sun.star.wizards.document.FormHandler; import com.sun.star.wizards.document.Shape; import com.sun.star.wizards.document.TimeStampControl; public class FormControlArranger { protected DatabaseControl[] DBControlList = null; private XNameContainer xFormName; private XMultiServiceFactory xMSF; private Control[] LabelControlList = null; private XStatusIndicator xProgressBar; private FieldColumn[] FieldColumns; private DatabaseControl curDBControl; // Control curLabelControl; private int icurArrangement; private boolean bIsFirstRun; private boolean bIsVeryFirstRun; private boolean bControlsareCreated; private int cXOffset; private int cYOffset; private static final int cVertDistance = 200; private static final int cHoriDistance = 300; private static final int cLabelGap = 100; private static final double CMAXREDUCTION = 0.7; private FormHandler oFormHandler; private int iReduceWidth; private int nXTCPos; private int nYTCPos; private int nXDBPos; private int nYDBPos; private int nTCHeight; private int nTCWidth; private int nDBHeight; private int nDBWidth; private int nMaxTCWidth; private int nFormWidth; private int nFormHeight; private int nMaxRowY; private int nSecMaxRowY; private int nMaxColRightX; private int a; private int StartA; private int nMaxDBYPos = 0; //the maximum YPosition of a DBControl in the form private Short NBorderType = new Short((short) 1); //3-D Border public FormControlArranger(FormHandler _oFormHandler, XNameContainer _xFormName, CommandMetaData oDBMetaData, XStatusIndicator _xProgressBar, Point _StartPoint, Size _FormSize) { FieldColumns = oDBMetaData.FieldColumns; xMSF = oDBMetaData.xMSF; xFormName = _xFormName; xProgressBar = _xProgressBar; LabelControlList = new Control[FieldColumns.length]; DBControlList = new DatabaseControl[FieldColumns.length]; oFormHandler = _oFormHandler; cXOffset = _StartPoint.X; cYOffset = _StartPoint.Y; setFormSize(_FormSize); } // Note: on all Controls except for the checkbox the Label has to be set // a bit under the DBControl because its Height is also smaller private int getLabelDiffHeight(int _index) { if (curDBControl != null) { if (curDBControl.getControlType() == FormHandler.SOCHECKBOX) { return getCheckBoxDiffHeight(_index); } } return oFormHandler.getBasicLabelDiffHeight(); } public void setBorderType(short _nBorderType) { NBorderType = new Short(_nBorderType); } public Control[] getLabelControlList() { return LabelControlList; } private int getCheckBoxDiffHeight(int LastIndex) { if ((LastIndex < DBControlList.length)) { if (DBControlList[LastIndex].getControlType() == FormHandler.SOCHECKBOX) { return (int) ((oFormHandler.getControlReferenceHeight() - DBControlList[LastIndex].getControlHeight()) / 2); } } return 0; } private boolean isReducable(int _index) { boolean bisreducable = false; int ntype = this.FieldColumns[_index].getFieldType(); switch (ntype) { case DataType.TINYINT: case DataType.SMALLINT: case DataType.INTEGER: case DataType.FLOAT: case DataType.DATE: case DataType.TIME: case DataType.TIMESTAMP: case DataType.REAL: case DataType.DOUBLE: case DataType.NUMERIC: case DataType.DECIMAL: case DataType.BIT: case DataType.BOOLEAN: bisreducable = false; break; case DataType.VARCHAR: short nTextLen; try { nTextLen = AnyConverter.toShort(DBControlList[_index].xPropertySet.getPropertyValue("MaxTextLen")); if ((nTextLen == 0) || (nTextLen > 20)) { bisreducable = true; } } catch (Exception e) { e.printStackTrace(System.out); } break; case DataType.BIGINT: bisreducable = true; break; default: bisreducable = true; } if (nTCWidth > 0.9 * CMAXREDUCTION * nDBWidth) { bisreducable = false; } return bisreducable; } private int getControlGroupWidth() { if (nDBWidth > nTCWidth) { return nDBWidth; } else { return nTCWidth; } } private void checkJustifiedPosition(int a) { int nBaseWidth = nFormWidth + cXOffset; int nLeftDist = nMaxColRightX - nBaseWidth; int nRightDist = nBaseWidth - (DBControlList[a].getPosition().X - this.cHoriDistance); if (nLeftDist < 0.5 * nRightDist) { // Fieldwidths in the line can be made smaller.. adjustLineWidth(StartA, a, nLeftDist, -1); nYTCPos = nMaxRowY + cVertDistance; nYDBPos = nYTCPos + nTCHeight; // if ((nYDBPos + nDBHeight) > nMaxDBYPos) // nMaxDBYPos = nYDBPos + nDBHeight; nXTCPos = cXOffset; nXDBPos = cXOffset; bIsFirstRun = true; StartA = a + 1; } else { // FieldWidths in the line can be made wider... if (nYDBPos + nDBHeight == nMaxRowY) { // The last Control was the highest in the row nYTCPos = nSecMaxRowY + cVertDistance; } else { nYTCPos = nMaxRowY + cVertDistance; } nYDBPos = nYTCPos + nTCHeight; nXDBPos = cXOffset; nXTCPos = cXOffset; this.LabelControlList[a].setPosition(new Point(cXOffset, nYTCPos)); this.DBControlList[a].setPosition(new Point(cXOffset, nYDBPos)); bIsFirstRun = true; if (nDBWidth > nTCWidth) { checkOuterPoints(nXDBPos, nDBWidth, nYDBPos, nDBHeight, true); } else { checkOuterPoints(nXDBPos, nTCWidth, nYDBPos, nDBHeight, true); } nXTCPos = nMaxColRightX + cHoriDistance; nXDBPos = nXTCPos; adjustLineWidth(StartA, a - 1, nRightDist, 1); StartA = a; } } private int getCorrWidth(int StartIndex, int EndIndex, int nDist, int Widthfactor) { int ShapeCount; if (Widthfactor > 0) { // shapes are made wide ShapeCount = EndIndex - StartIndex + 1; } else { // shapes are made more narrow ShapeCount = iReduceWidth; } return (nDist) / ShapeCount; } /** * * @param StartIndex * @param EndIndex * @param nDist * @param WidthFactor is either '+1' or '-1' and determines whether the control shapes widths are to be made smaller or larger */ private void adjustLineWidth(int StartIndex, int EndIndex, int nDist, int WidthFactor) { int CorrWidth = getCorrWidth(StartIndex, EndIndex, nDist, WidthFactor); int iLocTCPosX = cXOffset; for (int i = StartIndex; i <= EndIndex; i++) { int nControlBaseWidth = 0; curDBControl = this.DBControlList[i]; Control curLabelControl = this.LabelControlList[i]; if (i != StartIndex) { curLabelControl.setPosition(new Point(iLocTCPosX, curLabelControl.getPosition().Y)); curDBControl.setPosition(new Point(iLocTCPosX, curLabelControl.getPosition().Y + nTCHeight)); } if (((curLabelControl.getSize().Width > curDBControl.getSize().Width)) && (WidthFactor > 0)) { nControlBaseWidth = curLabelControl.getSize().Width; } else { nControlBaseWidth = curDBControl.getSize().Width; } if (FieldColumns[i].getFieldType() == DataType.TIMESTAMP) { TimeStampControl oDBTimeStampControl = (TimeStampControl) curDBControl; nControlBaseWidth = oDBTimeStampControl.getSize().Width; if (this.isReducable(i) || WidthFactor > 0) { oDBTimeStampControl.setSize(new Size(nControlBaseWidth + WidthFactor * CorrWidth, oDBTimeStampControl.getSize().Height)); } } else { if (this.isReducable(i) || WidthFactor > 0) { curDBControl.setSize(new Size(nControlBaseWidth + WidthFactor * CorrWidth, curDBControl.getSize().Height)); } } iLocTCPosX = curDBControl.getPosition().X + curDBControl.getSize().Width + cHoriDistance; if (curLabelControl.getSize().Width > curDBControl.getSize().Width) { iLocTCPosX = curLabelControl.getPosition().X + curLabelControl.getSize().Width + cHoriDistance; } } if (WidthFactor > 0) { iReduceWidth = 1; } else { iReduceWidth = 0; } } private void checkOuterPoints(int nXPos, int nWidth, int nYPos, int nHeight, boolean bIsDBField) { int nColRightX; if (icurArrangement == FormWizard.SOTOPJUSTIFIED) { if (bIsDBField) { // Only at DBControls you can measure the Value of nMaxRowY if (bIsFirstRun) { nMaxRowY = nYPos + nHeight; nSecMaxRowY = nMaxRowY; } else { int nRowY = nYPos + nHeight; if (nRowY >= nMaxRowY) { int nOldMaxRowY = nMaxRowY; nSecMaxRowY = nOldMaxRowY; nMaxRowY = nRowY; } } } } // Find the outer right point if (bIsFirstRun) { nMaxColRightX = nXPos + nWidth; bIsFirstRun = false; } else { nColRightX = nXPos + nWidth; if (nColRightX > nMaxColRightX) { nMaxColRightX = nColRightX; } } } public void positionControls(int _icurArrangement, Point _aStartPoint, Size _aFormSize, short _iAlign, Short _NBorderType) { try { this.NBorderType = _NBorderType; this.setStartPoint(_aStartPoint); icurArrangement = _icurArrangement; initializePosSizes(); initializeControlColumn(-1); bIsVeryFirstRun = true; nMaxRowY = 0; nSecMaxRowY = 0; this.nMaxColRightX = 0; xProgressBar.start("", FieldColumns.length); for (int i = 0; i < FieldColumns.length; i++) { try { insertLabel(i, _iAlign); insertDBControl(i); bIsVeryFirstRun = false; DBControlList[i].setPropertyValue("LabelControl", LabelControlList[i].xPropertySet); resetPosSizes(i); xProgressBar.setValue(i + 1); } catch (RuntimeException e) { int dummy = 0; } } xProgressBar.end(); bControlsareCreated = true; } catch (Exception e) { e.printStackTrace(System.out); } } public boolean areControlsexisting() { if (DBControlList != null) { if (DBControlList.length > 0) { return (DBControlList[0] != null); } } return false; } private void initializeControlColumn(int LastIndex) { bIsFirstRun = true; StartA = LastIndex + 1; a = 0; } private void resetPosSizes(int LastIndex) { int nYRefPos = nYDBPos; switch (icurArrangement) { case FormWizard.SOCOLUMNARLEFT: nYDBPos = nYDBPos + nDBHeight + cVertDistance + getCheckBoxDiffHeight(LastIndex); nYRefPos = nYDBPos; if ((nYDBPos > cYOffset + nFormHeight) || (LastIndex == (FieldColumns.length - 1))) { repositionColumnarLeftControls(LastIndex); nXTCPos = nMaxColRightX + 2 * cHoriDistance; nXDBPos = nXTCPos + this.cLabelGap + nMaxTCWidth; nYDBPos = cYOffset; nYRefPos = nYDBPos; initializeControlColumn(LastIndex); } else { /*a = a + 1;*/ /* a += 1;*/ ++a; } nYTCPos = nYDBPos + this.getLabelDiffHeight(LastIndex); if ((nYRefPos + nDBHeight) > nMaxDBYPos) { nMaxDBYPos = nYRefPos + nDBHeight; } break; case FormWizard.SOCOLUMNARTOP: nYTCPos = nYDBPos + nDBHeight + cVertDistance + getCheckBoxDiffHeight(LastIndex); ; if ((nYTCPos > cYOffset + nFormHeight) || (LastIndex == (FieldColumns.length - 1))) { nXDBPos = nMaxColRightX + cHoriDistance; nXTCPos = nXDBPos; nYRefPos = nYDBPos; nYDBPos = cYOffset + nTCHeight + cVertDistance; nYTCPos = cYOffset; initializeControlColumn(LastIndex); } else { a = a + 1; } if ((nYRefPos + nDBHeight + cVertDistance) > nMaxDBYPos) { nMaxDBYPos = nYRefPos + nDBHeight + cVertDistance; } break; case FormWizard.SOTOPJUSTIFIED: if (this.isReducable(a)) { iReduceWidth = iReduceWidth + 1; } if (nMaxColRightX > cXOffset + nFormWidth) { int nOldYTCPos = nYTCPos; checkJustifiedPosition(a); nYRefPos = nYDBPos; } else { nXTCPos = nMaxColRightX + cHoriDistance; } a = a + 1; if ((nYRefPos + nDBHeight) > nMaxDBYPos) { nMaxDBYPos = nYRefPos + nDBHeight; } break; } // if ((nYRefPos + nDBHeight) > nMaxDBYPos) // nMaxDBYPos = nYRefPos + nDBHeight; } private void repositionColumnarLeftControls(int LastIndex) { bIsFirstRun = true; for (int i = StartA; i <= LastIndex; i++) { if (i == StartA) { nXTCPos = LabelControlList[i].getPosition().X; nXDBPos = nXTCPos + nMaxTCWidth + cHoriDistance; } LabelControlList[i].setSize(new Size(nMaxTCWidth, nTCHeight)); resetDBShape(DBControlList[i], nXDBPos); checkOuterPoints(nXDBPos, nDBWidth, nYDBPos, nDBHeight, true); } } private void resetDBShape(Shape _curDBControl, int iXPos) { int nYDBPos = _curDBControl.getPosition().Y; nDBWidth = _curDBControl.getSize().Width; nDBHeight = _curDBControl.getSize().Height; _curDBControl.setPosition(new Point(iXPos, nYDBPos)); } private void initializePosSizes() { this.nMaxDBYPos = 0; nXTCPos = cXOffset; nTCWidth = 2000; nDBWidth = 2000; nDBHeight = oFormHandler.getControlReferenceHeight(); nTCHeight = oFormHandler.getLabelHeight(); iReduceWidth = 0; if (icurArrangement == FormWizard.SOCOLUMNARLEFT) { nYTCPos = cYOffset + this.getLabelDiffHeight(0); nXDBPos = cXOffset + 3050; nYDBPos = cYOffset; } else { nXDBPos = cXOffset; nYTCPos = cYOffset; } } private void insertLabel(int i, int _iAlign) { try { if (bControlsareCreated) { LabelControlList[i].setPosition(new Point(nXTCPos, nYTCPos)); if (icurArrangement != FormWizard.SOCOLUMNARLEFT) { nTCWidth = LabelControlList[i].getPreferredWidth(FieldColumns[i].getFieldTitle()); LabelControlList[i].setSize(new Size(nTCWidth, nTCHeight)); } else { nTCWidth = LabelControlList[i].getSize().Width; } } else { Point aPoint = new Point(nXTCPos, nYTCPos); Size aSize = new Size(nTCWidth, nTCHeight); final String sFieldName = FieldColumns[i].getFieldName(); this.LabelControlList[i] = new Control(oFormHandler, xFormName, FormHandler.SOLABEL, sFieldName, aPoint, aSize); if (bIsVeryFirstRun) { if (icurArrangement == FormWizard.SOCOLUMNARTOP) { nYDBPos = nYTCPos + nTCHeight; } } String sTitle = FieldColumns[i].getFieldTitle(); nTCWidth = LabelControlList[i].getPreferredWidth(sTitle); } Control curLabelControl = LabelControlList[i]; if (icurArrangement == FormWizard.SOCOLUMNARLEFT) { // Note This If Sequence must be called before retrieving the outer Points if (bIsFirstRun) { nMaxTCWidth = nTCWidth; bIsFirstRun = false; } else if (nTCWidth > nMaxTCWidth) { nMaxTCWidth = nTCWidth; } } checkOuterPoints(nXTCPos, nTCWidth, nYTCPos, nTCHeight, false); if ((icurArrangement == FormWizard.SOCOLUMNARTOP) || (icurArrangement == FormWizard.SOTOPJUSTIFIED)) { nXDBPos = nXTCPos; nYDBPos = nYTCPos + nTCHeight; curLabelControl.xPropertySet.setPropertyValue("Align", new Short((short) com.sun.star.awt.TextAlign.LEFT)); } else { curLabelControl.xPropertySet.setPropertyValue("Align", new Short((short) _iAlign)); } if (!bControlsareCreated) { curLabelControl.setSize(new Size(nTCWidth, nTCHeight)); } // if (CurHelpText != ""){ // oModel.HelpText = CurHelptext; // } } catch (Exception e) { e.printStackTrace(System.out); } } private void insertDBControl(int i) { try { String sFieldName = FieldColumns[i].getFieldName(); int nFieldType = FieldColumns[i].getFieldType(); Point aPoint = new Point(nXDBPos, nYDBPos); if (bControlsareCreated) { DBControlList[i].setPosition(aPoint); } else { if (nFieldType == DataType.TIMESTAMP) { DBControlList[i] = new TimeStampControl(new Resource(xMSF, "FormWizard", "dbw"), oFormHandler, xFormName, sFieldName, aPoint); } else { DBControlList[i] = new DatabaseControl(oFormHandler, xFormName, sFieldName, nFieldType, aPoint); if (DBControlList[i].getControlType() == FormHandler.SOCHECKBOX) { // Checkboxes have no Label near by DBControlList[i].setPropertyValue("Label", ""); } } } DatabaseControl aDBControl = DBControlList[i]; nDBHeight = aDBControl.getControlHeight(); nDBWidth = aDBControl.getControlWidth(); if (nFieldType != DataType.TIMESTAMP) { aDBControl.setSize(new Size(nDBWidth, nDBHeight)); } if (aDBControl.getControlType() == FormHandler.SOCHECKBOX) { nYDBPos = nYDBPos + /*(int)*/ ((oFormHandler.getControlReferenceHeight() - nDBHeight) / 2); aPoint = new Point(nXDBPos, nYDBPos); aDBControl.setPosition(aPoint); } if (nFieldType == DataType.LONGVARCHAR) /* memo */ { Helper.setUnoPropertyValue(LabelControlList[i], "MultiLine", Boolean.TRUE); } checkOuterPoints(nXDBPos, nDBWidth, nYDBPos, nDBHeight, true); aDBControl.setPropertyValue("Border", NBorderType); } catch (Exception e) { e.printStackTrace(System.out); } } private int assignFieldLength(int _fieldlength) { if (_fieldlength >= 65535) { return -1; } else { return _fieldlength; } } public int getFormHeight() { return nMaxDBYPos - this.cYOffset; } public int getEntryPointY() { if (this.icurArrangement == FormWizard.SOCOLUMNARTOP) { Control curLabelControl2 = LabelControlList[0]; return curLabelControl2.getPosition().Y; } else { DatabaseControl curDBControl2 = DBControlList[0]; return curDBControl2.getPosition().Y; } } public void setStartPoint(Point _aPoint) { this.cXOffset = _aPoint.X; this.cYOffset = _aPoint.Y; } public void adjustYPositions(int _diffY) { for (int i = 0; i < DBControlList.length; i++) { Point aPoint = DBControlList[i].getPosition(); DBControlList[i].setPosition(new Point(aPoint.X, aPoint.Y - _diffY)); aPoint = this.LabelControlList[i].getPosition(); LabelControlList[i].setPosition(new Point(aPoint.X, aPoint.Y - _diffY)); } nMaxDBYPos = -_diffY; cYOffset = -_diffY; } public void setFormSize(Size _FormSize) { nFormHeight = _FormSize.Height; nFormWidth = _FormSize.Width; } }