/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * The Contents of this file are made available subject to the terms of * the BSD license. * * Copyright 2000, 2010 Oracle and/or its affiliates. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Sun Microsystems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*************************************************************************/
/** This class capsulates the class, that implements the minimal component, a * factory for creating the service (<CODE>__getServiceFactory</CODE>) and a * method, that writes the information into the given registry key * (<CODE>__writeRegistryServiceInfo</CODE>).
*/ publicclass ToDo {
/** This class implements the component. At least the interfaces * XInterface, XTypeProvider, and XWeak implemented by the helper class * WeakBase and XServiceInfo should be provided by the service.
*/ publicstaticclass ToDoImpl extends WeakBase implements XServiceInfo, XToDo {
/** The service name, that must be used to get an instance of this service.
*/ privatestaticfinal String __serviceName = "org.openoffice.ToDo";
/** The initial component contextr, that gives access to * the service manager, supported singletons, ... * It's often later used
*/ private XComponentContext m_cmpCtx;
/** The service manager, that gives access to all registered services. * It's often later used
*/ private XMultiComponentFactory m_xMCF;
/** The constructor of the inner class has a XComponenContext parameter. * @param xCompContext the initial component context
*/ public ToDoImpl(XComponentContext xCompContext) { try {
m_cmpCtx = xCompContext;
m_xMCF = m_cmpCtx.getServiceManager();
} catch( Exception e ) {
e.printStackTrace(System.err);
}
}
/** This method returns an array of all supported service names. * @return Array of supported service names.
*/ public String[] getSupportedServiceNames() { return getServiceNames();
}
/** This method returns true, if the given service will be * supported by the component. * @return True, if the given service name will be supported.
*/ publicboolean supportsService(String sServiceName) { return sServiceName.equals( __serviceName );
}
/** Return the class name of the component. * @return Class name of the component.
*/ public String getImplementationName() { return ToDoImpl.class.getName();
}
/** For every bug/feature listed in a spreadsheet document this method * calculates the start date, day of week of the start date, the end date * and the day of week of the end date. All calculations are dependent * on the values of "Needed Days", "Due Date" and "Status". The columns * "Needed Days" and "Status" are mandatory. The first feature/bug should * be placed in row nine. The date to start the calculation should be * placed in cell C6. The private holidays should be placed in cell K4/K5 * and below. All rows will be calculated up to the first empty cell in * the first column. If a cell in the column "Due Date" will be colored * red, you should take a look at your entries. * @param aInstance Spreadsheet document. * @throws com.sun.star.uno.RuntimeException This exception could occur * at every interface method.
*/ publicvoid recalc( java.lang.Object aInstance ) throws com.sun.star.uno.RuntimeException { try { // Querying for the interface XSpreadsheetDocument
XSpreadsheetDocument xspreadsheetdocument =
UnoRuntime.queryInterface(
XSpreadsheetDocument.class, aInstance );
// Querying for the interface XIndexAccess
XIndexAccess xindexaccess = UnoRuntime.queryInterface( XIndexAccess.class,
xspreadsheetdocument.getSheets() );
// Getting the first XSpreadsheet
XSpreadsheet xspreadsheet = UnoRuntime.queryInterface(
XSpreadsheet.class, xindexaccess.getByIndex( 0 ));
// Querying for the interface XCellRange on the XSpreadsheet
XCellRange xcellrange = UnoRuntime.queryInterface( XCellRange.class, xspreadsheet );
/* Getting the gregorian calendar with the date on which to start
the calculation */
GregorianCalendar gregCalAbsoluteStartDate = this.getGregorianCalendarFromString(this.getStringFromCell(
xcellrange, 5, 2 ) );
gregCalAbsoluteStartDate.add( Calendar.DATE, -1 );
// Set the start date with the absolute start date
GregorianCalendar gregCalStartDate =
(GregorianCalendar) gregCalAbsoluteStartDate.clone();
/* Creating the service FunctionAccess, which allows generic
access to all spreadsheet functions */
Object objectFunctionAccess =
m_xMCF.createInstanceWithContext( "com.sun.star.sheet.FunctionAccess", m_cmpCtx );
// Querying for the interface XFunctionAccess on service // FunctionAccess
XFunctionAccess xfunctionaccess = UnoRuntime.queryInterface(XFunctionAccess.class,
objectFunctionAccess );
// Creating vector for holidays
ArrayList<Object> vectorHolidays = new ArrayList<Object>();
// Get the Official Holidays this.getOfficialHolidays( vectorHolidays, xcellrange,
xfunctionaccess,
gregCalStartDate.get(
Calendar.YEAR ) );
// Get the private holidays this.getPrivateHolidays(vectorHolidays, xcellrange,
xfunctionaccess);
// Getting the object array of holidays
Object[] objectSortedHolidays = vectorHolidays.toArray();
// Sorting the holidays
Arrays.sort( objectSortedHolidays );
// Collect the Official Holidays and the private holidays
Object [][]objectHolidays = new Object[][] { objectSortedHolidays };
// Row index int intRowTo = ToDoImpl.INT_ROW_FROM - 1;
// Getting the feature of the first cell
String sFeature = this.getStringFromCell(xcellrange,
intRowTo + 1,
ToDoImpl.INT_COLUMN_FEATURE);
// Determine the last row with an entry in the first column while ( ( sFeature != null ) &&
( !sFeature.equals( "" ) ) ) {
intRowTo++;
sFeature = this.getStringFromCell( xcellrange,
intRowTo + 1, ToDoImpl.INT_COLUMN_FEATURE );
}
// Setting the last row to be calculated finalint INT_ROW_TO = intRowTo + 1;
// Deleting cells which will be recalculated for ( int intRow = ToDoImpl.INT_ROW_FROM; intRow < INT_ROW_TO + 5;
intRow++ ) { for ( int intColumn = ToDoImpl.INT_COLUMN_STARTDATE;
intColumn <= ToDoImpl.INT_COLUMN_END_DAY_OF_WEEK;
intColumn++ ) { this.setStringToCell(xcellrange, intRow, intColumn, "");
}
}
/* Clearing the background color of the due date cells and setting
the hyperlink to the bugtracker */ for (int intRow = ToDoImpl.INT_ROW_FROM; intRow < INT_ROW_TO; intRow++)
{ // Querying for the interface XPropertySet for the cell // providing the due date
XPropertySet xpropertyset = UnoRuntime.queryInterface(XPropertySet.class,
xcellrange.getCellByPosition(
ToDoImpl.INT_COLUMN_DUEDATE,
intRow ));
// Changing the background color of the cell to white
xpropertyset.setPropertyValue( "CellBackColor",
Integer.valueOf( 16777215 ) );
// Getting the cell of the bug id
XCell xcell = xcellrange.getCellByPosition(
ToDoImpl.INT_COLUMN_FEATURE, intRow );
// Querying for the interface XSimpleText
XSimpleText xsimpletext = UnoRuntime.queryInterface( XSimpleText.class, xcell );
// Getting the text cursor
XTextCursor xtextcursor = xsimpletext.createTextCursor();
// Querying for the interface XTextRange
XTextRange xtextrange = UnoRuntime.queryInterface( XTextRange.class, xtextcursor );
// Inserting the text field URL to the cell
xtext.insertTextContent( xtextrange, xtextfield, false );
}
}
// Processing all features/bugs in the table for (int intRow = ToDoImpl.INT_ROW_FROM; intRow < INT_ROW_TO; intRow++)
{ // Getting the cell of the column "Needed Days" in the // current row
XCell xcell = xcellrange.getCellByPosition(
INT_COLUMN_NEEDEDDAYS, intRow );
// Getting the number of needed days to perform the feature int intNeededDays = (int) Math.round( xcell.getValue() );
// Getting the content of a specified cell
String sStatus = this.getStringFromCell( xcellrange,
intRow, ToDoImpl.INT_COLUMN_STATUS );
/* Testing if the number of needed days is greater than zero and if
the status is not "done" */ if ( ( intNeededDays > 0 )
&& !( sStatus.toLowerCase().trim().equals("done")) ) { // Getting the start date after a specified number of // workdays
gregCalStartDate = this.getWorkday(
gregCalStartDate, 1, objectHolidays,
xfunctionaccess );
// Getting a string with the date format jjjj-mm-dd from // the gregorian calendar
String sDate = this.getStringFromGregorianCalendar(
gregCalStartDate );
// Set the start date in the specified cell of the table this.setStringToCell(xcellrange, intRow,
ToDoImpl.INT_COLUMN_STARTDATE, sDate);
// For the start day set the day of week in the specified // cell of the table this.setDayOfWeek( gregCalStartDate,
xcellrange, intRow,
ToDoImpl.INT_COLUMN_START_DAY_OF_WEEK );
// Getting the end date after a specified number of workdays
GregorianCalendar gregCalEndDate = this.getWorkday( gregCalStartDate,
intNeededDays - 1,
objectHolidays, xfunctionaccess );
// Creating a string with the date format jjjj-mm-dd
sDate = this.getStringFromGregorianCalendar(
gregCalEndDate );
// Set the end date in the specified cell of the table this.setStringToCell( xcellrange, intRow,
ToDoImpl.INT_COLUMN_ENDDATE, sDate );
// For the end day set the day of week in the specified // cell of the table this.setDayOfWeek(gregCalEndDate, xcellrange,
intRow, ToDoImpl.INT_COLUMN_END_DAY_OF_WEEK);
// Set the initial date for the next loop
gregCalStartDate = ( GregorianCalendar )
gregCalEndDate.clone();
// Get the due date from the table
String sDueDate = this.getStringFromCell(
xcellrange, intRow, ToDoImpl.INT_COLUMN_DUEDATE );
// Testing if the due date is not empty if ( !sDueDate.equals( "" ) ) {
GregorianCalendar gregCalDueDate = this.getGregorianCalendarFromString(sDueDate);
// Testing if the due date is before the calculated // end date if ( gregCalDueDate.before(
gregCalEndDate ) ) { /* Getting the date when the processing of the feature/bug should
be started at the latest */
GregorianCalendar gregCalLatestDateToStart = this.getWorkday(gregCalDueDate,
-( intNeededDays - 1 ),
objectHolidays,
xfunctionaccess);
// Begin with the current row int intRowToInsert = intRow;
// Get the start date for the feature/bug in the // current row
GregorianCalendar gregCalPreviousStartDate = this.getGregorianCalendarFromString( this.getStringFromCell(
xcellrange, intRowToInsert,
ToDoImpl.INT_COLUMN_STARTDATE ) );
// Testing if we have to search for an earlier date // to begin while ((gregCalLatestDateToStart.before(
gregCalPreviousStartDate)) &&
(INT_ROW_FROM != intRowToInsert)) { // Decrease the row
intRowToInsert--;
// Get the start date for the feature/bug in // the current row
String sStartDate = this.getStringFromCell(
xcellrange, intRowToInsert,
ToDoImpl.INT_COLUMN_STARTDATE );
// Search until a valid start date is found while ( sStartDate.equals( "" ) ) { // Decrease the row
intRowToInsert--;
// Get the start date for the feature/bug // in the current row
sStartDate = this.getStringFromCell(
xcellrange, intRowToInsert,
ToDoImpl.INT_COLUMN_STARTDATE );
}
// Get the GregorianCalendar format for the // start date
gregCalPreviousStartDate = this.getGregorianCalendarFromString(
sStartDate );
}
// Getting the cell of the column "Needed Days" // in the row where to insert
XCell xcellNeededDaysWhereToInsert =
xcellrange.getCellByPosition(
INT_COLUMN_NEEDEDDAYS, intRowToInsert ); // Getting the number of needed days to perform // the feature int intNeededDaysWhereToInsert = (int)
Math.round(
xcellNeededDaysWhereToInsert.getValue());
if ( ( intRowToInsert == intRow ) ||
( gregCalPreviousNewEndDate.after(
gregCalPreviousDueDate ) ) ) { // Querying for the interface XPropertySet for // the cell providing the due date
XPropertySet xpropertyset = UnoRuntime.queryInterface(
XPropertySet.class,
xcellrange.getCellByPosition(
ToDoImpl.INT_COLUMN_DUEDATE,
intRow ) );
// Changing the background color of the cell // to red
xpropertyset.setPropertyValue( "CellBackColor", Integer.valueOf( 16711680 ) );
} else { // Querying for the interface XColumnRowRange // on the XCellRange
XColumnRowRange xcolumnrowrange =
UnoRuntime.queryInterface(
XColumnRowRange.class, xcellrange ); // Inserting one row to the table
XTableRows xTableRows =
xcolumnrowrange.getRows();
xTableRows.insertByIndex( intRowToInsert, 1 );
// Querying for the interface // XCellRangeMovement on XCellRange
XCellRangeMovement xcellrangemovement =
UnoRuntime.queryInterface(
XCellRangeMovement.class, xcellrange );
// Creating the cell address of the destination
CellAddress celladdress = new CellAddress();
celladdress.Sheet = 0;
celladdress.Column = 0;
celladdress.Row = intRowToInsert;
// Creating the cell range of the source
CellRangeAddress cellrangeaddress = new CellRangeAddress();
cellrangeaddress.Sheet = 0;
cellrangeaddress.StartColumn = 0;
cellrangeaddress.StartRow = intRow + 1;
cellrangeaddress.EndColumn = 8;
cellrangeaddress.EndRow = intRow + 1;
// Moves the cell range to another position in // the document
xcellrangemovement.moveRange(celladdress,
cellrangeaddress);
// Removing the row not needed anymore
xcolumnrowrange.getRows().removeByIndex(intRow
+ 1, 1);
// Set the current row, because we want to // recalculate all rows below
intRow = intRowToInsert - 1;
// Tests at which line we want to insert if ( intRow >= ToDoImpl.INT_ROW_FROM ) { // Get the start date
gregCalStartDate = this.getGregorianCalendarFromString( this.getStringFromCell( xcellrange,
intRow,ToDoImpl.INT_COLUMN_ENDDATE));
} else { // Set the start date with the absolute s // tart date
gregCalStartDate = (GregorianCalendar)
gregCalAbsoluteStartDate.clone();
}
}
}
}
}
}
} catch( Exception exception ) {
showExceptionMessage( exception );
}
}
/** Getting a string from a gregorian calendar. * @param gregCal Date to be converted. * @return string (converted gregorian calendar).
*/ private String getStringFromGregorianCalendar( GregorianCalendar gregCal ) {
String sDate = ( gregCal.get( Calendar.MONTH ) + 1 )
+ STRING_SEPARATOR + gregCal.get( Calendar.DATE )
+ STRING_SEPARATOR + gregCal.get( Calendar.YEAR );
return sDate;
}
/** Getting a GregorianCalendar from a string. * @param sDate String to be converted. * @return The result of the converting of the string.
*/ private GregorianCalendar getGregorianCalendarFromString( String sDate ) { int []intDateValue = this.getDateValuesFromString( sDate );
/** Getting the day, month and year from a string. * @param sDate String to be parsed. * @return Returns an array of integer variables.
*/ privateint[] getDateValuesFromString( String sDate) { int[] intDateValues = newint[ 3 ];
int intPositionFirstTag = sDate.indexOf( STRING_SEPARATOR ); int intPositionSecondTag = sDate.indexOf(STRING_SEPARATOR,
intPositionFirstTag + 1);
// Getting the value of the month
intDateValues[ 0 ] = Integer.parseInt(
sDate.substring(0, intPositionFirstTag)) - 1; // Getting the value of the day
intDateValues[ 1 ] = Integer.parseInt(
sDate.substring(intPositionFirstTag + 1, intPositionSecondTag)); // Getting the value of the year
intDateValues[ 2 ] = Integer.parseInt(
sDate.substring(intPositionSecondTag + 1, sDate.length()));
return intDateValues;
}
/** Getting a content from a specified cell. * @param xcellrange Providing access to cells. * @param intRow Number of row. * @param intColumn Number of column. * @return String from the specified cell.
*/ private String getStringFromCell( XCellRange xcellrange, int intRow, int intColumn ) {
XTextRange xtextrangeStartDate = null;
try { // Getting the cell holding the information about the start date
XCell xcellStartDate = xcellrange.getCellByPosition(intColumn,
intRow); // Querying for the interface XTextRange on the XCell
xtextrangeStartDate = UnoRuntime.queryInterface(XTextRange.class, xcellStartDate);
} catch( Exception exception ) { this.showExceptionMessage( exception );
}
// Getting the start date return xtextrangeStartDate.getString().trim();
}
/** Writing a specified string to a specified cell. * @param xcellrange Providing access to the cells. * @param intRow Number of row. * @param intColumn Number of column. * @param sDate Date to write to the cell.
*/ privatevoid setStringToCell( XCellRange xcellrange, int intRow, int intColumn, String sDate ) { try { // Getting the cell holding the information on the day to start
XCell xcellStartDate = xcellrange.getCellByPosition(intColumn,
intRow); // Querying for the interface XTextRange on the XCell
XTextRange xtextrange = UnoRuntime.queryInterface(XTextRange.class, xcellStartDate); // Setting the new start date
xtextrange.setString( sDate );
} catch( Exception exception ) { this.showExceptionMessage( exception );
}
}
/** Calculates the week of day and calls the method "setStringToCell". * @param gregCal Day to be written to the cell. * @param xcellrange Providing access to the cells. * @param intRow Number of row. * @param intColumn Number of column.
*/ privatevoid setDayOfWeek( GregorianCalendar gregCal,
XCellRange xcellrange, int intRow, int intColumn) { int intDayOfWeek = gregCal.get( Calendar.DAY_OF_WEEK );
String sDayOfWeek = ""; if ( intDayOfWeek == Calendar.MONDAY ) {
sDayOfWeek = "MON";
} elseif ( intDayOfWeek == Calendar.TUESDAY ) {
sDayOfWeek = "TUE";
} elseif ( intDayOfWeek == Calendar.WEDNESDAY ) {
sDayOfWeek = "WED";
} elseif ( intDayOfWeek == Calendar.THURSDAY ) {
sDayOfWeek = "THU";
} elseif ( intDayOfWeek == Calendar.FRIDAY ) {
sDayOfWeek = "FRI";
}
/** Calculates the dates of the official holidays with help of Calc * functions. * @param vectorHolidays Holding all holidays. * @param xcellrange Providing the cells. * @param xfunctionaccess Provides access to functions of the Calc. * @param intYear Year to calculate the official holidays.
*/ privatevoid getOfficialHolidays(
ArrayList<Object> vectorHolidays,
XCellRange xcellrange,
XFunctionAccess xfunctionaccess, int intYear ) { try { // Official Holidays for how many years? finalint intHowManyYears = 2;
// Get the Official Holiday for two years for ( int intNumberOfYear = 0;
intNumberOfYear <= ( intHowManyYears - 1 );
intNumberOfYear++ ) {
intYear += intNumberOfYear;
// Getting the Easter sunday Double dEasterSunday = ( Double )
xfunctionaccess.callFunction( "EASTERSUNDAY", new Object[] { Integer.valueOf(intYear) });
int intEasterSunday = (int)Math.round(
dEasterSunday.doubleValue());
/** Returns the serial number of the date before or after a specified * number of workdays. * @param gregCalStartDate Date to start with the calculation. * @param intDays Number of workdays (e.g. 5 or -3). * @param objectHolidays Private and public holidays to take into account. * @param xfunctionaccess Allows to call functions from the Calc. * @return The gregorian date before or after a specified number of * workdays.
*/ private GregorianCalendar getWorkday(
GregorianCalendar gregCalStartDate, int intDays, Object[][] objectHolidays,
XFunctionAccess xfunctionaccess ) {
GregorianCalendar gregCalWorkday = null;
try { // Getting the value of the start date Double dDate = ( Double ) xfunctionaccess.callFunction( "DATE", new Object[] {
Integer.valueOf( gregCalStartDate.get( Calendar.YEAR ) ),
Integer.valueOf( gregCalStartDate.get( Calendar.MONTH ) + 1 ),
Integer.valueOf( gregCalStartDate.get( Calendar.DATE ) )
} );
/** Getting the holidays from the spreadsheet. * @param vectorHolidays Holding all holidays. * @param xcellrange Providing the cells. * @param xfunctionaccess Provides the access to functions of the Calc.
*/ privatevoid getPrivateHolidays( ArrayList<Object> vectorHolidays,
XCellRange xcellrange,
XFunctionAccess xfunctionaccess ) { try { int intRow = ToDoImpl.INT_ROW_HOLIDAYS_START; int intColumn = ToDoImpl.INT_COLUMN_HOLIDAYS_START;
/** Showing the stack trace in a JOptionPane. * @param sMessage The message to show.
*/ privatevoid showMessage( String sMessage ) {
javax.swing.JFrame jframe = new javax.swing.JFrame();
jframe.setLocation(100, 100);
jframe.setSize(300, 200);
jframe.setVisible(true);
javax.swing.JOptionPane.showMessageDialog(
jframe, sMessage, "Debugging information",
javax.swing.JOptionPane.INFORMATION_MESSAGE);
jframe.dispose();
}
/** Writing the stack trace from an exception to a string and calling * the method showMessage() with this string. * @param exception The occurred exception. * @see #showMessage(String)
*/ privatevoid showExceptionMessage( Exception exception ) {
java.io.StringWriter swriter = new java.io.StringWriter();
java.io.PrintWriter printwriter = new java.io.PrintWriter( swriter );
exception.printStackTrace( printwriter);
System.err.println( exception ); this.showMessage( swriter.getBuffer().substring(0) );
}
}
/** * Gives a factory for creating the service. * This method is called by the <code>JavaLoader</code> * <p> * @return returns a <code>XSingleComponentFactory</code> for creating * the component * @param sImplName the name of the implementation for which a * service is desired * @see com.sun.star.comp.loader.JavaLoader
*/ publicstatic XSingleComponentFactory __getComponentFactory(String sImplName) {
XSingleComponentFactory xFactory = null;
if ( sImplName.equals( ToDoImpl.class.getName() ) )
xFactory = Factory.createComponentFactory(ToDoImpl.class,
ToDoImpl.getServiceNames());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.