1 /*************************************************************************
3 * The Contents of this file are made available subject to the terms of
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *************************************************************************/
35 import java
.util
.ArrayList
;
36 import java
.util
.Arrays
;
37 import java
.util
.Calendar
;
38 import java
.util
.GregorianCalendar
;
40 import com
.sun
.star
.beans
.XPropertySet
;
41 import com
.sun
.star
.container
.XIndexAccess
;
42 import com
.sun
.star
.lang
.XMultiComponentFactory
;
43 import com
.sun
.star
.lang
.XMultiServiceFactory
;
44 import com
.sun
.star
.lang
.XServiceInfo
;
45 import com
.sun
.star
.lang
.XSingleComponentFactory
;
46 import com
.sun
.star
.lib
.uno
.helper
.Factory
;
47 import com
.sun
.star
.lib
.uno
.helper
.WeakBase
;
48 import com
.sun
.star
.sheet
.XCellRangeMovement
;
49 import com
.sun
.star
.sheet
.XFunctionAccess
;
50 import com
.sun
.star
.sheet
.XSpreadsheet
;
51 import com
.sun
.star
.sheet
.XSpreadsheetDocument
;
52 import com
.sun
.star
.table
.CellAddress
;
53 import com
.sun
.star
.table
.CellRangeAddress
;
54 import com
.sun
.star
.table
.XCell
;
55 import com
.sun
.star
.table
.XCellRange
;
56 import com
.sun
.star
.table
.XColumnRowRange
;
57 import com
.sun
.star
.table
.XTableRows
;
58 import com
.sun
.star
.text
.XSimpleText
;
59 import com
.sun
.star
.text
.XText
;
60 import com
.sun
.star
.text
.XTextCursor
;
61 import com
.sun
.star
.text
.XTextField
;
62 import com
.sun
.star
.text
.XTextRange
;
63 import com
.sun
.star
.uno
.UnoRuntime
;
64 import com
.sun
.star
.uno
.XComponentContext
;
65 import org
.openoffice
.XToDo
;
67 /** This class capsulates the class, that implements the minimal component, a
68 * factory for creating the service (<CODE>__getServiceFactory</CODE>) and a
69 * method, that writes the information into the given registry key
70 * (<CODE>__writeRegistryServiceInfo</CODE>).
74 /** This class implements the component. At least the interfaces
75 * XInterface, XTypeProvider, and XWeak implemented by the helper class
76 * WeakBase and XServiceInfo should be provided by the service.
78 public static class ToDoImpl
extends WeakBase
implements XServiceInfo
, XToDo
{
80 /** The service name, that must be used to get an instance of this service.
82 private static final String __serviceName
= "org.openoffice.ToDo";
84 /** The initial component contextr, that gives access to
85 * the service manager, supported singletons, ...
86 * It's often later used
88 private XComponentContext m_cmpCtx
;
90 /** The service manager, that gives access to all registered services.
91 * It's often later used
93 private XMultiComponentFactory m_xMCF
;
95 // Implementation helper variables
96 static private final int INT_COLUMN_FEATURE
= 0;
97 static private final int INT_COLUMN_NEEDEDDAYS
= 2;
98 static private final int INT_COLUMN_STARTDATE
= 3;
99 static private final int INT_COLUMN_START_DAY_OF_WEEK
= 4;
100 static private final int INT_COLUMN_ENDDATE
= 5;
101 static private final int INT_COLUMN_END_DAY_OF_WEEK
= 6;
102 static private final int INT_COLUMN_DUEDATE
= 7;
103 static private final int INT_COLUMN_STATUS
= 8;
105 static private final int INT_ROW_FROM
= 14; // 8
107 static private final int INT_ROW_HOLIDAYS_START
= 4;
108 static private final int INT_COLUMN_HOLIDAYS_START
= 7; // 10
110 static private final String STRING_SEPARATOR
= "/";
113 /** The constructor of the inner class has a XComponenContext parameter.
114 * @param xCompContext the initial component context
116 public ToDoImpl(XComponentContext xCompContext
) {
118 m_cmpCtx
= xCompContext
;
119 m_xMCF
= m_cmpCtx
.getServiceManager();
121 catch( Exception e
) {
122 e
.printStackTrace(System
.err
);
126 /** This method returns an array of all supported service names.
127 * @return Array of supported service names.
129 public String
[] getSupportedServiceNames() {
130 return getServiceNames();
133 private static String
[] getServiceNames() {
134 String
[] sSupportedServiceNames
= { __serviceName
};
135 return sSupportedServiceNames
;
138 /** This method returns true, if the given service will be
139 * supported by the component.
140 * @return True, if the given service name will be supported.
142 public boolean supportsService(String sServiceName
) {
143 return sServiceName
.equals( __serviceName
);
146 /** Return the class name of the component.
147 * @return Class name of the component.
149 public String
getImplementationName() {
150 return ToDoImpl
.class.getName();
153 /** For every bug/feature listed in a spreadsheet document this method
154 * calculates the start date, day of week of the start date, the end date
155 * and the day of week of the end date. All calculations are dependent
156 * on the values of "Needed Days", "Due Date" and "Status". The columns
157 * "Needed Days" and "Status" are mandatory. The first feature/bug should
158 * be placed in row nine. The date to start the calculation should be
159 * placed in cell C6. The private holidays should be placed in cell K4/K5
160 * and below. All rows will be calculated up to the first empty cell in
161 * the first column. If a cell in the column "Due Date" will be colored
162 * red, you should take a look at your entries.
163 * @param aInstance Spreadsheet document.
164 * @throws com.sun.star.uno.RuntimeException This exception could occur
165 * at every interface method.
167 public void recalc( java
.lang
.Object aInstance
)
168 throws com
.sun
.star
.uno
.RuntimeException
{
170 // Querying for the interface XSpreadsheetDocument
171 XSpreadsheetDocument xspreadsheetdocument
=
172 UnoRuntime
.queryInterface(
173 XSpreadsheetDocument
.class, aInstance
);
175 // Querying for the interface XIndexAccess
176 XIndexAccess xindexaccess
= UnoRuntime
.queryInterface( XIndexAccess
.class,
177 xspreadsheetdocument
.getSheets() );
179 // Getting the first XSpreadsheet
180 XSpreadsheet xspreadsheet
= UnoRuntime
.queryInterface(
181 XSpreadsheet
.class, xindexaccess
.getByIndex( 0 ));
183 // Querying for the interface XCellRange on the XSpeadsheet
184 XCellRange xcellrange
= UnoRuntime
.queryInterface( XCellRange
.class, xspreadsheet
);
186 /* Getting the gregorian calendar with the date on which to start
188 GregorianCalendar gregCalAbsoluteStartDate
=
189 this.getGregorianCalendarFromString(this.getStringFromCell(
190 xcellrange
, 5, 2 ) );
191 gregCalAbsoluteStartDate
.add( Calendar
.DATE
, -1 );
193 // Set the start date with the absolute start date
194 GregorianCalendar gregCalStartDate
=
195 (GregorianCalendar
) gregCalAbsoluteStartDate
.clone();
197 /* Creating the service FunctionAccess, which allows generic
198 access to all spreadsheet functions */
199 Object objectFunctionAccess
=
200 m_xMCF
.createInstanceWithContext(
201 "com.sun.star.sheet.FunctionAccess", m_cmpCtx
);
203 // Querying for the interface XFunctionAccess on service
205 XFunctionAccess xfunctionaccess
= UnoRuntime
.queryInterface(XFunctionAccess
.class,
206 objectFunctionAccess
);
208 // Creating vector for holidays
209 ArrayList
<Object
> vectorHolidays
= new ArrayList
<Object
>();
211 // Get the Official Holidays
212 this.getOfficialHolidays( vectorHolidays
, xcellrange
,
214 gregCalStartDate
.get(
217 // Get the private holidays
218 this.getPrivateHolidays(vectorHolidays
, xcellrange
,
221 // Getting the object array of holidays
222 Object
[] objectSortedHolidays
= vectorHolidays
.toArray();
224 // Sorting the holidays
225 Arrays
.sort( objectSortedHolidays
);
227 // Collect the Official Holidays and the private holidays
228 Object
[][]objectHolidays
=
229 new Object
[][] { objectSortedHolidays
};
232 int intRowTo
= ToDoImpl
.INT_ROW_FROM
- 1;
234 // Getting the feature of the first cell
235 String sFeature
= this.getStringFromCell(xcellrange
,
237 ToDoImpl
.INT_COLUMN_FEATURE
);
239 // Determine the last row with an entry in the first column
240 while ( ( sFeature
!= null ) &&
241 ( !sFeature
.equals( "" ) ) ) {
243 sFeature
= this.getStringFromCell( xcellrange
,
244 intRowTo
+ 1, ToDoImpl
.INT_COLUMN_FEATURE
);
247 // Setting the last row to be calculated
248 final int INT_ROW_TO
= intRowTo
+ 1;
250 // Deleting cells which will be recalculated
251 for ( int intRow
= ToDoImpl
.INT_ROW_FROM
; intRow
< INT_ROW_TO
+ 5;
253 for ( int intColumn
= ToDoImpl
.INT_COLUMN_STARTDATE
;
254 intColumn
<= ToDoImpl
.INT_COLUMN_END_DAY_OF_WEEK
;
256 this.setStringToCell(xcellrange
, intRow
, intColumn
, "");
260 /* Clearing the background color of the due date cells and setting
261 the hyperlink to the bugtracker */
262 for (int intRow
= ToDoImpl
.INT_ROW_FROM
; intRow
< INT_ROW_TO
; intRow
++)
264 // Querying for the interface XPropertySet for the cell
265 // providing the due date
266 XPropertySet xpropertyset
= UnoRuntime
.queryInterface(XPropertySet
.class,
267 xcellrange
.getCellByPosition(
268 ToDoImpl
.INT_COLUMN_DUEDATE
,
271 // Changing the background color of the cell to white
272 xpropertyset
.setPropertyValue( "CellBackColor",
273 Integer
.valueOf( 16777215 ) );
275 // Getting the cell of the bug id
276 XCell xcell
= xcellrange
.getCellByPosition(
277 ToDoImpl
.INT_COLUMN_FEATURE
, intRow
);
279 // Querying for the interface XSimpleText
280 XSimpleText xsimpletext
= UnoRuntime
.queryInterface( XSimpleText
.class, xcell
);
282 // Getting the text cursor
283 XTextCursor xtextcursor
= xsimpletext
.createTextCursor();
285 // Querying for the interface XTextRange
286 XTextRange xtextrange
= UnoRuntime
.queryInterface( XTextRange
.class, xtextcursor
);
288 // Getting the bug ID from the cell
289 String sBugID
= xtextrange
.getString();
290 if ( !sBugID
.startsWith(
291 "http://www.openoffice.org/issues/show_bug.cgi?id=") ) {
293 "http://www.openoffice.org/issues/show_bug.cgi?id=" + sBugID
;
295 // Querying for the interface XMultiServiceFactory
296 XMultiServiceFactory xMSFTextField
=
297 UnoRuntime
.queryInterface(
298 XMultiServiceFactory
.class, aInstance
);
300 // Creating an instance of the text field URL
301 Object objectTextField
=
302 xMSFTextField
.createInstance(
303 "com.sun.star.text.TextField.URL" );
305 // Querying for the interface XTextField
306 XTextField xtextfield
= UnoRuntime
.queryInterface( XTextField
.class,
309 // Querying for the interface XPropertySet
310 XPropertySet xpropertysetTextField
= UnoRuntime
.queryInterface( XPropertySet
.class,
314 xpropertysetTextField
.setPropertyValue( "URL",
317 // Setting the representation of the URL
318 xpropertysetTextField
.setPropertyValue( "Representation",
321 // Querying for the interface XText
322 XText xtext
= UnoRuntime
.queryInterface(
323 XText
.class, xcell
);
325 // Delete cell content
326 xtextrange
.setString( "" );
328 // Inserting the text field URL to the cell
329 xtext
.insertTextContent( xtextrange
, xtextfield
, false );
333 // Processing all features/bugs in the table
334 for (int intRow
= ToDoImpl
.INT_ROW_FROM
; intRow
< INT_ROW_TO
; intRow
++)
336 // Getting the cell of the column "Needed Days" in the
338 XCell xcell
= xcellrange
.getCellByPosition(
339 INT_COLUMN_NEEDEDDAYS
, intRow
);
341 // Getting the number of needed days to perform the feature
342 int intNeededDays
= (int) Math
.round( xcell
.getValue() );
344 // Getting the content of a specified cell
345 String sStatus
= this.getStringFromCell( xcellrange
,
346 intRow
, ToDoImpl
.INT_COLUMN_STATUS
);
348 /* Testing if the number of needed days is greater than
350 the status is not "done" */
351 if ( ( intNeededDays
> 0 )
352 && !( sStatus
.toLowerCase().trim().equals("done")) ) {
353 // Getting the start date after a specified number of
355 gregCalStartDate
= this.getWorkday(
356 gregCalStartDate
, 1, objectHolidays
,
359 // Getting a string with the date format jjjj-mm-dd from
360 // the gregorian calendar
361 String sDate
= this.getStringFromGregorianCalendar(
364 // Set the start date in the specified cell of the table
365 this.setStringToCell(xcellrange
, intRow
,
366 ToDoImpl
.INT_COLUMN_STARTDATE
, sDate
);
368 // For the start day set the day of week in the specified
370 this.setDayOfWeek( gregCalStartDate
,
372 ToDoImpl
.INT_COLUMN_START_DAY_OF_WEEK
);
374 // Getting the end date after a specified number of workdays
375 GregorianCalendar gregCalEndDate
=
376 this.getWorkday( gregCalStartDate
,
378 objectHolidays
, xfunctionaccess
);
380 // Creating a string with the date format jjjj-mm-dd
381 sDate
= this.getStringFromGregorianCalendar(
384 // Set the end date in the specified cell of the table
385 this.setStringToCell( xcellrange
, intRow
,
386 ToDoImpl
.INT_COLUMN_ENDDATE
, sDate
);
388 // For the end day set the day of week in the specified
390 this.setDayOfWeek(gregCalEndDate
, xcellrange
,
391 intRow
, ToDoImpl
.INT_COLUMN_END_DAY_OF_WEEK
);
393 // Set the initial date for the next loop
394 gregCalStartDate
= ( GregorianCalendar
)
395 gregCalEndDate
.clone();
397 // Get the due date from the table
398 String sDueDate
= this.getStringFromCell(
399 xcellrange
, intRow
, ToDoImpl
.INT_COLUMN_DUEDATE
);
401 // Testing if the due date is not empty
402 if ( !sDueDate
.equals( "" ) ) {
403 GregorianCalendar gregCalDueDate
=
404 this.getGregorianCalendarFromString(sDueDate
);
406 // Testing if the due date is before the calculated
408 if ( gregCalDueDate
.before(
410 /* Getting the date when the processing of the
412 be started at the latest */
413 GregorianCalendar gregCalLatestDateToStart
=
414 this.getWorkday(gregCalDueDate
,
415 -( intNeededDays
- 1 ),
419 // Begin with the current row
420 int intRowToInsert
= intRow
;
422 // Get the start date for the feature/bug in the
424 GregorianCalendar gregCalPreviousStartDate
=
425 this.getGregorianCalendarFromString(
426 this.getStringFromCell(
427 xcellrange
, intRowToInsert
,
428 ToDoImpl
.INT_COLUMN_STARTDATE
) );
430 // Testing if we have to search for an earlier date
432 while ((gregCalLatestDateToStart
.before(
433 gregCalPreviousStartDate
)) &&
434 (INT_ROW_FROM
!= intRowToInsert
)) {
438 // Get the start date for the feature/bug in
440 String sStartDate
= this.getStringFromCell(
441 xcellrange
, intRowToInsert
,
442 ToDoImpl
.INT_COLUMN_STARTDATE
);
444 // Search until a valid start date is found
445 while ( sStartDate
.equals( "" ) ) {
449 // Get the start date for the feature/bug
450 // in the current row
451 sStartDate
= this.getStringFromCell(
452 xcellrange
, intRowToInsert
,
453 ToDoImpl
.INT_COLUMN_STARTDATE
);
456 // Get the GregorianCalendar format for the
458 gregCalPreviousStartDate
=
459 this.getGregorianCalendarFromString(
463 // Getting the cell of the column "Needed Days"
464 // in the row where to insert
465 XCell xcellNeededDaysWhereToInsert
=
466 xcellrange
.getCellByPosition(
467 INT_COLUMN_NEEDEDDAYS
, intRowToInsert
);
468 // Getting the number of needed days to perform
470 int intNeededDaysWhereToInsert
= (int)
472 xcellNeededDaysWhereToInsert
.getValue());
474 GregorianCalendar gregCalPreviousNewEndDate
=
475 this.getWorkday(gregCalPreviousStartDate
,
477 intNeededDaysWhereToInsert
,
480 String sPreviousDueDate
= this.getStringFromCell(
481 xcellrange
, intRowToInsert
,
482 ToDoImpl
.INT_COLUMN_DUEDATE
);
484 GregorianCalendar gregCalPreviousDueDate
= null;
486 if ( !sPreviousDueDate
.equals( "" ) ) {
487 gregCalPreviousDueDate
=
488 this.getGregorianCalendarFromString(
492 if ( ( intRowToInsert
== intRow
) ||
493 ( gregCalPreviousNewEndDate
.after(
494 gregCalPreviousDueDate
) ) ) {
495 // Querying for the interface XPropertySet for
496 // the cell providing the due date
497 XPropertySet xpropertyset
= UnoRuntime
.queryInterface(
499 xcellrange
.getCellByPosition(
500 ToDoImpl
.INT_COLUMN_DUEDATE
,
503 // Changing the background color of the cell
505 xpropertyset
.setPropertyValue(
506 "CellBackColor", Integer
.valueOf( 16711680 ) );
508 // Querying for the interface XColumnRowRange
510 XColumnRowRange xcolumnrowrange
=
511 UnoRuntime
.queryInterface(
512 XColumnRowRange
.class, xcellrange
);
513 // Inserting one row to the table
514 XTableRows xTableRows
=
515 xcolumnrowrange
.getRows();
516 xTableRows
.insertByIndex( intRowToInsert
, 1 );
518 // Querying for the interface
519 // XCellRangeMovement on XCellRange
520 XCellRangeMovement xcellrangemovement
=
521 UnoRuntime
.queryInterface(
522 XCellRangeMovement
.class, xcellrange
);
524 // Creating the cell address of the destination
525 CellAddress celladdress
= new CellAddress();
526 celladdress
.Sheet
= 0;
527 celladdress
.Column
= 0;
528 celladdress
.Row
= intRowToInsert
;
530 // Creating the cell range of the source
531 CellRangeAddress cellrangeaddress
=
532 new CellRangeAddress();
533 cellrangeaddress
.Sheet
= 0;
534 cellrangeaddress
.StartColumn
= 0;
535 cellrangeaddress
.StartRow
= intRow
+ 1;
536 cellrangeaddress
.EndColumn
= 8;
537 cellrangeaddress
.EndRow
= intRow
+ 1;
539 // Moves the cell range to another position in
541 xcellrangemovement
.moveRange(celladdress
,
544 // Removing the row not needed anymore
545 xcolumnrowrange
.getRows().removeByIndex(intRow
548 // Set the current row, because we want to
549 // recalculate all rows below
550 intRow
= intRowToInsert
- 1;
552 // Tests at which line we want to insert
553 if ( intRow
>= ToDoImpl
.INT_ROW_FROM
) {
554 // Get the start date
556 this.getGregorianCalendarFromString(
557 this.getStringFromCell( xcellrange
,
558 intRow
,ToDoImpl
.INT_COLUMN_ENDDATE
));
561 // Set the start date with the absolute s
563 gregCalStartDate
= (GregorianCalendar
)
564 gregCalAbsoluteStartDate
.clone();
572 catch( Exception exception
) {
573 showExceptionMessage( exception
);
577 /** Getting a string from a gregorian calendar.
578 * @param gregCal Date to be converted.
579 * @return string (converted gregorian calendar).
581 private String
getStringFromGregorianCalendar( GregorianCalendar gregCal
) {
582 String sDate
= ( gregCal
.get( Calendar
.MONTH
) + 1 )
583 + STRING_SEPARATOR
+ gregCal
.get( Calendar
.DATE
)
584 + STRING_SEPARATOR
+ gregCal
.get( Calendar
.YEAR
);
589 /** Getting a GregorianCalendar from a string.
590 * @param sDate String to be converted.
591 * @return The result of the converting of the string.
593 private GregorianCalendar
getGregorianCalendarFromString( String sDate
) {
594 int []intDateValue
= this.getDateValuesFromString( sDate
);
596 return( new GregorianCalendar( intDateValue
[ 2 ], intDateValue
[ 0 ],
597 intDateValue
[ 1 ] ) );
600 /** Getting the day, month and year from a string.
601 * @param sDate String to be parsed.
602 * @return Returns an array of integer variables.
604 private int[] getDateValuesFromString( String sDate
) {
605 int[] intDateValues
= new int[ 3 ];
607 int intPositionFirstTag
= sDate
.indexOf( STRING_SEPARATOR
);
608 int intPositionSecondTag
= sDate
.indexOf(STRING_SEPARATOR
,
609 intPositionFirstTag
+ 1);
611 // Getting the value of the month
612 intDateValues
[ 0 ] = Integer
.parseInt(
613 sDate
.substring(0, intPositionFirstTag
)) - 1;
614 // Getting the value of the day
615 intDateValues
[ 1 ] = Integer
.parseInt(
616 sDate
.substring(intPositionFirstTag
+ 1, intPositionSecondTag
));
617 // Getting the value of the year
618 intDateValues
[ 2 ] = Integer
.parseInt(
619 sDate
.substring(intPositionSecondTag
+ 1, sDate
.length()));
621 return intDateValues
;
624 /** Getting a content from a specified cell.
625 * @param xcellrange Providing access to cells.
626 * @param intRow Number of row.
627 * @param intColumn Number of column.
628 * @return String from the specified cell.
630 private String
getStringFromCell( XCellRange xcellrange
, int intRow
,
632 XTextRange xtextrangeStartDate
= null;
635 // Getting the cell holding the information about the start date
636 XCell xcellStartDate
= xcellrange
.getCellByPosition(intColumn
,
638 // Querying for the interface XTextRange on the XCell
639 xtextrangeStartDate
= UnoRuntime
.queryInterface(XTextRange
.class, xcellStartDate
);
641 catch( Exception exception
) {
642 this.showExceptionMessage( exception
);
645 // Getting the start date
646 return xtextrangeStartDate
.getString().trim();
649 /** Writing a specified string to a specified cell.
650 * @param xcellrange Providing access to the cells.
651 * @param intRow Number of row.
652 * @param intColumn Number of column.
653 * @param sDate Date to write to the cell.
655 private void setStringToCell( XCellRange xcellrange
, int intRow
,
656 int intColumn
, String sDate
) {
658 // Getting the cell holding the information on the day to start
659 XCell xcellStartDate
= xcellrange
.getCellByPosition(intColumn
,
661 // Querying for the interface XTextRange on the XCell
662 XTextRange xtextrange
= UnoRuntime
.queryInterface(XTextRange
.class, xcellStartDate
);
663 // Setting the new start date
664 xtextrange
.setString( sDate
);
666 catch( Exception exception
) {
667 this.showExceptionMessage( exception
);
671 /** Calculates the week of day and calls the method "setStringToCell".
672 * @param gregCal Day to be written to the cell.
673 * @param xcellrange Providing access to the cells.
674 * @param intRow Number of row.
675 * @param intColumn Number of column.
677 private void setDayOfWeek( GregorianCalendar gregCal
,
678 XCellRange xcellrange
, int intRow
,
680 int intDayOfWeek
= gregCal
.get( Calendar
.DAY_OF_WEEK
);
681 String sDayOfWeek
= "";
682 if ( intDayOfWeek
== Calendar
.MONDAY
) {
684 } else if ( intDayOfWeek
== Calendar
.TUESDAY
) {
686 } else if ( intDayOfWeek
== Calendar
.WEDNESDAY
) {
688 } else if ( intDayOfWeek
== Calendar
.THURSDAY
) {
690 } else if ( intDayOfWeek
== Calendar
.FRIDAY
) {
694 this.setStringToCell( xcellrange
, intRow
, intColumn
,
698 /** Calculates the dates of the official holidays with help of Calc
700 * @param vectorHolidays Holding all holidays.
701 * @param xcellrange Providing the cells.
702 * @param xfunctionaccess Provides access to functions of the Calc.
703 * @param intYear Year to calculate the official holidays.
705 private void getOfficialHolidays(
706 ArrayList
<Object
> vectorHolidays
,
707 XCellRange xcellrange
,
708 XFunctionAccess xfunctionaccess
,
711 // Official Holidays for how many years?
712 final int intHowManyYears
= 2;
714 // Get the Official Holiday for two years
715 for ( int intNumberOfYear
= 0;
716 intNumberOfYear
<= ( intHowManyYears
- 1 );
717 intNumberOfYear
++ ) {
718 intYear
+= intNumberOfYear
;
720 // Getting the Easter sunday
721 Double dEasterSunday
= ( Double
)
722 xfunctionaccess
.callFunction(
723 "EASTERSUNDAY", new Object
[] { Integer
.valueOf(intYear
) });
725 int intEasterSunday
= (int)Math
.round(
726 dEasterSunday
.doubleValue());
729 vectorHolidays
.add( xfunctionaccess
.callFunction(
732 Integer
.valueOf( intYear
),
733 Integer
.valueOf( 1 ),
734 Integer
.valueOf( 1 ) } ));
738 new Double( intEasterSunday
- 2 ) );
742 new Double( intEasterSunday
+ 1 ) );
745 vectorHolidays
.add( xfunctionaccess
.callFunction(
748 Integer
.valueOf( intYear
),
749 Integer
.valueOf( 5 ),
750 Integer
.valueOf( 1 ) } ));
753 vectorHolidays
.add(new Double(intEasterSunday
+ 39 ));
756 vectorHolidays
.add(new Double(intEasterSunday
+ 50 ));
758 // German Unification
759 vectorHolidays
.add( xfunctionaccess
.callFunction(
762 Integer
.valueOf( intYear
),
763 Integer
.valueOf( 10 ),
764 Integer
.valueOf( 3 ) } ));
766 // Christmas Day First
767 vectorHolidays
.add( xfunctionaccess
.callFunction(
770 Integer
.valueOf( intYear
),
771 Integer
.valueOf( 12 ),
772 Integer
.valueOf( 25 ) } ));
774 // Christmas Day Second
775 vectorHolidays
.add( xfunctionaccess
.callFunction(
778 Integer
.valueOf( intYear
),
779 Integer
.valueOf( 12 ),
780 Integer
.valueOf( 26 ) } ));
783 catch( Exception exception
) {
784 this.showExceptionMessage( exception
);
788 /** Returns the serial number of the date before or after a specified
789 * number of workdays.
790 * @param gregCalStartDate Date to start with the calculation.
791 * @param intDays Number of workdays (e.g. 5 or -3).
792 * @param objectHolidays Private and public holidays to take into account.
793 * @param xfunctionaccess Allows to call functions from the Calc.
794 * @return The gregorian date before or after a specified number of
797 private GregorianCalendar
getWorkday(
798 GregorianCalendar gregCalStartDate
,
799 int intDays
, Object
[][] objectHolidays
,
800 XFunctionAccess xfunctionaccess
) {
801 GregorianCalendar gregCalWorkday
= null;
804 // Getting the value of the start date
805 Double dDate
= ( Double
) xfunctionaccess
.callFunction(
808 Integer
.valueOf( gregCalStartDate
.get( Calendar
.YEAR
) ),
809 Integer
.valueOf( gregCalStartDate
.get( Calendar
.MONTH
) + 1 ),
810 Integer
.valueOf( gregCalStartDate
.get( Calendar
.DATE
) )
813 Double dWorkday
= ( Double
) xfunctionaccess
.callFunction(
814 "com.sun.star.sheet.addin.Analysis.getWorkday",
815 new Object
[] { dDate
, Integer
.valueOf( intDays
), objectHolidays
} );
817 Double dYear
= ( Double
) xfunctionaccess
.callFunction(
818 "YEAR", new Object
[] { dWorkday
} );
819 Double dMonth
= ( Double
) xfunctionaccess
.callFunction(
820 "MONTH", new Object
[] { dWorkday
} );
821 Double dDay
= ( Double
) xfunctionaccess
.callFunction(
822 "DAY", new Object
[] { dWorkday
} );
824 gregCalWorkday
= new GregorianCalendar(
826 dMonth
.intValue() - 1,
829 catch( Exception exception
) {
830 this.showExceptionMessage( exception
);
833 return gregCalWorkday
;
836 /** Getting the holidays from the spreadsheet.
837 * @param vectorHolidays Holding all holidays.
838 * @param xcellrange Providing the cells.
839 * @param xfunctionaccess Provides the access to functions of the Calc.
841 private void getPrivateHolidays( ArrayList
<Object
> vectorHolidays
,
842 XCellRange xcellrange
,
843 XFunctionAccess xfunctionaccess
) {
845 int intRow
= ToDoImpl
.INT_ROW_HOLIDAYS_START
;
846 int intColumn
= ToDoImpl
.INT_COLUMN_HOLIDAYS_START
;
848 double dHolidayStart
= xcellrange
.getCellByPosition(
849 intColumn
, intRow
).getValue();
851 double dHolidayEnd
= xcellrange
.getCellByPosition(
852 intColumn
+ 1, intRow
).getValue();
854 while ( dHolidayStart
!= 0 ) {
855 if ( dHolidayEnd
== 0 ) {
857 Integer
.valueOf( (int) Math
.round(
861 for ( int intHoliday
= (int) Math
.round(
863 intHoliday
<= (int) Math
.round( dHolidayEnd
);
865 vectorHolidays
.add( new Double( intHoliday
) );
870 dHolidayStart
= xcellrange
.getCellByPosition(
871 intColumn
, intRow
).getValue();
872 dHolidayEnd
= xcellrange
.getCellByPosition(
873 intColumn
+ 1, intRow
).getValue();
876 catch( Exception exception
) {
877 this.showExceptionMessage( exception
);
881 /** Showing the stack trace in a JOptionPane.
882 * @param sMessage The message to show.
884 private void showMessage( String sMessage
) {
885 javax
.swing
.JFrame jframe
= new javax
.swing
.JFrame();
886 jframe
.setLocation(100, 100);
887 jframe
.setSize(300, 200);
888 jframe
.setVisible(true);
889 javax
.swing
.JOptionPane
.showMessageDialog(
890 jframe
, sMessage
, "Debugging information",
891 javax
.swing
.JOptionPane
.INFORMATION_MESSAGE
);
895 /** Writing the stack trace from an exception to a string and calling
896 * the method showMessage() with this string.
897 * @param exception The occurred exception.
898 * @see #showMessage(String)
900 private void showExceptionMessage( Exception exception
) {
901 java
.io
.StringWriter swriter
= new java
.io
.StringWriter();
902 java
.io
.PrintWriter printwriter
=
903 new java
.io
.PrintWriter( swriter
);
904 exception
.printStackTrace( printwriter
);
905 System
.err
.println( exception
);
906 this.showMessage( swriter
.getBuffer().substring(0) );
911 * Gives a factory for creating the service.
912 * This method is called by the <code>JavaLoader</code>
914 * @return returns a <code>XSingleComponentFactory</code> for creating
916 * @param sImplName the name of the implementation for which a
918 * @see com.sun.star.comp.loader.JavaLoader
920 public static XSingleComponentFactory
__getComponentFactory(String sImplName
) {
921 XSingleComponentFactory xFactory
= null;
923 if ( sImplName
.equals( ToDoImpl
.class.getName() ) )
924 xFactory
= Factory
.createComponentFactory(ToDoImpl
.class,
925 ToDoImpl
.getServiceNames());