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_COMMENT
= 1;
98 static private final int INT_COLUMN_NEEDEDDAYS
= 2;
99 static private final int INT_COLUMN_STARTDATE
= 3;
100 static private final int INT_COLUMN_START_DAY_OF_WEEK
= 4;
101 static private final int INT_COLUMN_ENDDATE
= 5;
102 static private final int INT_COLUMN_END_DAY_OF_WEEK
= 6;
103 static private final int INT_COLUMN_DUEDATE
= 7;
104 static private final int INT_COLUMN_STATUS
= 8;
106 static private final int INT_ROW_FROM
= 14; // 8
108 static private final int INT_ROW_HOLIDAYS_START
= 4;
109 static private final int INT_COLUMN_HOLIDAYS_START
= 7; // 10
111 static private final String STRING_SEPARATOR
= "/";
114 /** The constructor of the inner class has a XComponenContext parameter.
115 * @param xCompContext the initial component context
117 public ToDoImpl(XComponentContext xCompContext
) {
119 m_cmpCtx
= xCompContext
;
120 m_xMCF
= m_cmpCtx
.getServiceManager();
122 catch( Exception e
) {
123 e
.printStackTrace(System
.err
);
127 /** This method returns an array of all supported service names.
128 * @return Array of supported service names.
130 public String
[] getSupportedServiceNames() {
131 return getServiceNames();
134 public static String
[] getServiceNames() {
135 String
[] sSupportedServiceNames
= { __serviceName
};
136 return sSupportedServiceNames
;
139 /** This method returns true, if the given service will be
140 * supported by the component.
141 * @param sService Service name.
142 * @return True, if the given service name will be supported.
144 public boolean supportsService(String sServiceName
) {
145 return sServiceName
.equals( __serviceName
);
148 /** Return the class name of the component.
149 * @return Class name of the component.
151 public String
getImplementationName() {
152 return ToDoImpl
.class.getName();
155 /** For every bug/feature listed in a spreadsheet document this method
156 * calculates the start date, day of week of the start date, the end date
157 * and the day of week of the end date. All calculations are dependent
158 * on the values of "Needed Days", "Due Date" and "Status". The columns
159 * "Needed Days" and "Status" are mandatory. The first feature/bug should
160 * be placed in row nine. The date to start the calculation should be
161 * placed in cell C6. The private holidays should be placed in cell K4/K5
162 * and below. All rows will be calculated up to the first empty cell in
163 * the first column. If a cell in the column "Due Date" will be colored
164 * red, you should take a look at your entries.
165 * @param aInstance Spreadsheet document.
166 * @throws com.sun.star.uno.RuntimeException This exception could occur
167 * at every interface method.
169 public void recalc( java
.lang
.Object aInstance
)
170 throws com
.sun
.star
.uno
.RuntimeException
{
172 // Querying for the interface XSpreadsheetDocument
173 XSpreadsheetDocument xspreadsheetdocument
=
174 UnoRuntime
.queryInterface(
175 XSpreadsheetDocument
.class, aInstance
);
177 // Querying for the interface XIndexAccess
178 XIndexAccess xindexaccess
= UnoRuntime
.queryInterface( XIndexAccess
.class,
179 xspreadsheetdocument
.getSheets() );
181 // Getting the first XSpreadsheet
182 XSpreadsheet xspreadsheet
= UnoRuntime
.queryInterface(
183 XSpreadsheet
.class, xindexaccess
.getByIndex( 0 ));
185 // Querying for the interface XCellRange on the XSpeadsheet
186 XCellRange xcellrange
= UnoRuntime
.queryInterface( XCellRange
.class, xspreadsheet
);
188 /* Getting the gregorian calendar with the date on which to start
190 GregorianCalendar gregCalAbsoluteStartDate
=
191 this.getGregorianCalendarFromString(this.getStringFromCell(
192 xcellrange
, 5, 2 ) );
193 gregCalAbsoluteStartDate
.add( Calendar
.DATE
, -1 );
195 // Set the start date with the absolute start date
196 GregorianCalendar gregCalStartDate
=
197 (GregorianCalendar
) gregCalAbsoluteStartDate
.clone();
199 /* Creating the service FunctionAccess, which allows generic
200 access to all spreadsheet functions */
201 Object objectFunctionAccess
=
202 m_xMCF
.createInstanceWithContext(
203 "com.sun.star.sheet.FunctionAccess", m_cmpCtx
);
205 // Querying for the interface XFunctionAccess on service
207 XFunctionAccess xfunctionaccess
= UnoRuntime
.queryInterface(XFunctionAccess
.class,
208 objectFunctionAccess
);
210 // Creating vector for holidays
211 ArrayList
<Object
> vectorHolidays
= new ArrayList
<Object
>();
213 // Get the Official Holidays
214 this.getOfficialHolidays( vectorHolidays
, xcellrange
,
216 gregCalStartDate
.get(
219 // Get the private holidays
220 this.getPrivateHolidays(vectorHolidays
, xcellrange
,
223 // Getting the object array of holidays
224 Object
[] objectSortedHolidays
= vectorHolidays
.toArray();
226 // Sorting the holidays
227 Arrays
.sort( objectSortedHolidays
);
229 // Collect the Official Holidays and the private holidays
230 Object
[][]objectHolidays
=
231 new Object
[][] { objectSortedHolidays
};
234 int intRowTo
= ToDoImpl
.INT_ROW_FROM
- 1;
236 // Getting the feature of the first cell
237 String sFeature
= this.getStringFromCell(xcellrange
,
239 ToDoImpl
.INT_COLUMN_FEATURE
);
241 // Determine the last row with an entry in the first column
242 while ( ( sFeature
!= null ) &&
243 ( !sFeature
.equals( "" ) ) ) {
245 sFeature
= this.getStringFromCell( xcellrange
,
246 intRowTo
+ 1, ToDoImpl
.INT_COLUMN_FEATURE
);
249 // Setting the last row to be calculated
250 final int INT_ROW_TO
= intRowTo
+ 1;
252 // Deleting cells which will be recalculated
253 for ( int intRow
= ToDoImpl
.INT_ROW_FROM
; intRow
< INT_ROW_TO
+ 5;
255 for ( int intColumn
= ToDoImpl
.INT_COLUMN_STARTDATE
;
256 intColumn
<= ToDoImpl
.INT_COLUMN_END_DAY_OF_WEEK
;
258 this.setStringToCell(xcellrange
, intRow
, intColumn
, "");
262 /* Clearing the background color of the due date cells and setting
263 the hyperlink to the bugtracker */
264 for (int intRow
= ToDoImpl
.INT_ROW_FROM
; intRow
< INT_ROW_TO
; intRow
++)
266 // Querying for the interface XPropertySet for the cell
267 // providing the due date
268 XPropertySet xpropertyset
= UnoRuntime
.queryInterface(XPropertySet
.class,
269 xcellrange
.getCellByPosition(
270 ToDoImpl
.INT_COLUMN_DUEDATE
,
273 // Changing the background color of the cell to white
274 xpropertyset
.setPropertyValue( "CellBackColor",
275 new Integer( 16777215 ) );
277 // Getting the cell of the bug id
278 XCell xcell
= xcellrange
.getCellByPosition(
279 ToDoImpl
.INT_COLUMN_FEATURE
, intRow
);
281 // Querying for the interface XSimpleText
282 XSimpleText xsimpletext
= UnoRuntime
.queryInterface( XSimpleText
.class, xcell
);
284 // Getting the text cursor
285 XTextCursor xtextcursor
= xsimpletext
.createTextCursor();
287 // Querying for the interface XTextRange
288 XTextRange xtextrange
= UnoRuntime
.queryInterface( XTextRange
.class, xtextcursor
);
290 // Getting the bug ID from the cell
291 String sBugID
= xtextrange
.getString();
292 if ( !sBugID
.startsWith(
293 "http://www.openoffice.org/issues/show_bug.cgi?id=") ) {
295 "http://www.openoffice.org/issues/show_bug.cgi?id=" + sBugID
;
297 // Querying for the interface XMultiServiceFactory
298 XMultiServiceFactory xMSFTextField
=
299 UnoRuntime
.queryInterface(
300 XMultiServiceFactory
.class, aInstance
);
302 // Creating an instance of the text field URL
303 Object objectTextField
=
304 xMSFTextField
.createInstance(
305 "com.sun.star.text.TextField.URL" );
307 // Querying for the interface XTextField
308 XTextField xtextfield
= UnoRuntime
.queryInterface( XTextField
.class,
311 // Querying for the interface XPropertySet
312 XPropertySet xpropertysetTextField
= UnoRuntime
.queryInterface( XPropertySet
.class,
316 xpropertysetTextField
.setPropertyValue( "URL",
319 // Setting the representation of the URL
320 xpropertysetTextField
.setPropertyValue( "Representation",
323 // Querying for the interface XText
324 XText xtext
= UnoRuntime
.queryInterface(
325 XText
.class, xcell
);
327 // Delete cell content
328 xtextrange
.setString( "" );
330 // Inserting the text field URL to the cell
331 xtext
.insertTextContent( xtextrange
, xtextfield
, false );
335 // Processing all features/bugs in the table
336 for (int intRow
= ToDoImpl
.INT_ROW_FROM
; intRow
< INT_ROW_TO
; intRow
++)
338 // Getting the cell of the column "Needed Days" in the
340 XCell xcell
= xcellrange
.getCellByPosition(
341 INT_COLUMN_NEEDEDDAYS
, intRow
);
343 // Getting the number of needed days to perform the feature
344 int intNeededDays
= (int) Math
.round( xcell
.getValue() );
346 // Getting the content of a specified cell
347 String sStatus
= this.getStringFromCell( xcellrange
,
348 intRow
, ToDoImpl
.INT_COLUMN_STATUS
);
350 /* Testing if the number of needed days is greater than
352 the status is not "done" */
353 if ( ( intNeededDays
> 0 )
354 && !( sStatus
.toLowerCase().trim().equals("done")) ) {
355 // Getting the start date after a specified number of
357 gregCalStartDate
= this.getWorkday(
358 gregCalStartDate
, 1, objectHolidays
,
361 // Getting a string with the date format jjjj-mm-dd from
362 // the gregorian calendar
363 String sDate
= this.getStringFromGregorianCalendar(
366 // Set the start date in the specified cell of the table
367 this.setStringToCell(xcellrange
, intRow
,
368 ToDoImpl
.INT_COLUMN_STARTDATE
, sDate
);
370 // For the start day set the day of week in the specified
372 this.setDayOfWeek( gregCalStartDate
,
374 ToDoImpl
.INT_COLUMN_START_DAY_OF_WEEK
);
376 // Getting the end date after a specified number of workdays
377 GregorianCalendar gregCalEndDate
=
378 this.getWorkday( gregCalStartDate
,
380 objectHolidays
, xfunctionaccess
);
382 // Creating a string with the date format jjjj-mm-dd
383 sDate
= this.getStringFromGregorianCalendar(
386 // Set the end date in the specified cell of the table
387 this.setStringToCell( xcellrange
, intRow
,
388 ToDoImpl
.INT_COLUMN_ENDDATE
, sDate
);
390 // For the end day set the day of week in the specified
392 this.setDayOfWeek(gregCalEndDate
, xcellrange
,
393 intRow
, ToDoImpl
.INT_COLUMN_END_DAY_OF_WEEK
);
395 // Set the initial date for the next loop
396 gregCalStartDate
= ( GregorianCalendar
)
397 gregCalEndDate
.clone();
399 // Get the due date from the table
400 String sDueDate
= this.getStringFromCell(
401 xcellrange
, intRow
, ToDoImpl
.INT_COLUMN_DUEDATE
);
403 // Testing if the due date is not empty
404 if ( !sDueDate
.equals( "" ) ) {
405 GregorianCalendar gregCalDueDate
=
406 this.getGregorianCalendarFromString(sDueDate
);
408 // Testing if the due date is before the calculated
410 if ( gregCalDueDate
.before(
412 /* Getting the date when the processing of the
414 be started at the latest */
415 GregorianCalendar gregCalLatestDateToStart
=
416 this.getWorkday(gregCalDueDate
,
417 -( intNeededDays
- 1 ),
421 // Begin with the current row
422 int intRowToInsert
= intRow
;
424 // Get the start date for the feature/bug in the
426 GregorianCalendar gregCalPreviousStartDate
=
427 this.getGregorianCalendarFromString(
428 this.getStringFromCell(
429 xcellrange
, intRowToInsert
,
430 ToDoImpl
.INT_COLUMN_STARTDATE
) );
432 // Testing if we have to search for an earlier date
434 while ((gregCalLatestDateToStart
.before(
435 gregCalPreviousStartDate
)) &&
436 (INT_ROW_FROM
!= intRowToInsert
)) {
440 // Get the start date for the feature/bug in
442 String sStartDate
= this.getStringFromCell(
443 xcellrange
, intRowToInsert
,
444 ToDoImpl
.INT_COLUMN_STARTDATE
);
446 // Search until a valid start date is found
447 while ( sStartDate
.equals( "" ) ) {
451 // Get the start date for the feature/bug
452 // in the current row
453 sStartDate
= this.getStringFromCell(
454 xcellrange
, intRowToInsert
,
455 ToDoImpl
.INT_COLUMN_STARTDATE
);
458 // Get the GregorianCalender format for the
460 gregCalPreviousStartDate
=
461 this.getGregorianCalendarFromString(
465 // Getting the cell of the column "Needed Days"
466 // in the row where to insert
467 XCell xcellNeededDaysWhereToInsert
=
468 xcellrange
.getCellByPosition(
469 INT_COLUMN_NEEDEDDAYS
, intRowToInsert
);
470 // Getting the number of needed days to perform
472 int intNeededDaysWhereToInsert
= (int)
474 xcellNeededDaysWhereToInsert
.getValue());
476 GregorianCalendar gregCalPreviousNewEndDate
=
477 this.getWorkday(gregCalPreviousStartDate
,
479 intNeededDaysWhereToInsert
,
482 String sPreviousDueDate
= this.getStringFromCell(
483 xcellrange
, intRowToInsert
,
484 ToDoImpl
.INT_COLUMN_DUEDATE
);
486 GregorianCalendar gregCalPreviousDueDate
= null;
488 if ( !sPreviousDueDate
.equals( "" ) ) {
489 gregCalPreviousDueDate
=
490 this.getGregorianCalendarFromString(
494 if ( ( intRowToInsert
== intRow
) ||
495 ( gregCalPreviousNewEndDate
.after(
496 gregCalPreviousDueDate
) ) ) {
497 // Querying for the interface XPropertySet for
498 // the cell providing the due date
499 XPropertySet xpropertyset
= UnoRuntime
.queryInterface(
501 xcellrange
.getCellByPosition(
502 ToDoImpl
.INT_COLUMN_DUEDATE
,
505 // Changing the background color of the cell
507 xpropertyset
.setPropertyValue(
508 "CellBackColor", new Integer( 16711680 ) );
510 // Querying for the interface XColumnRowRange
512 XColumnRowRange xcolumnrowrange
=
513 UnoRuntime
.queryInterface(
514 XColumnRowRange
.class, xcellrange
);
515 // Inserting one row to the table
516 XTableRows xTableRows
=
517 xcolumnrowrange
.getRows();
518 xTableRows
.insertByIndex( intRowToInsert
, 1 );
520 // Querying for the interface
521 // XCellRangeMovement on XCellRange
522 XCellRangeMovement xcellrangemovement
=
523 UnoRuntime
.queryInterface(
524 XCellRangeMovement
.class, xcellrange
);
526 // Creating the cell address of the destination
527 CellAddress celladdress
= new CellAddress();
528 celladdress
.Sheet
= 0;
529 celladdress
.Column
= 0;
530 celladdress
.Row
= intRowToInsert
;
532 // Creating the cell range of the source
533 CellRangeAddress cellrangeaddress
=
534 new CellRangeAddress();
535 cellrangeaddress
.Sheet
= 0;
536 cellrangeaddress
.StartColumn
= 0;
537 cellrangeaddress
.StartRow
= intRow
+ 1;
538 cellrangeaddress
.EndColumn
= 8;
539 cellrangeaddress
.EndRow
= intRow
+ 1;
541 // Moves the cell range to another position in
543 xcellrangemovement
.moveRange(celladdress
,
546 // Removing the row not needed anymore
547 xcolumnrowrange
.getRows().removeByIndex(intRow
550 // Set the current row, because we want to
551 // recalculate all rows below
552 intRow
= intRowToInsert
- 1;
554 // Tests at which line we want to insert
555 if ( intRow
>= ToDoImpl
.INT_ROW_FROM
) {
556 // Get the start date
558 this.getGregorianCalendarFromString(
559 this.getStringFromCell( xcellrange
,
560 intRow
,ToDoImpl
.INT_COLUMN_ENDDATE
));
563 // Set the start date with the absolute s
565 gregCalStartDate
= (GregorianCalendar
)
566 gregCalAbsoluteStartDate
.clone();
574 catch( Exception exception
) {
575 showExceptionMessage( exception
);
579 /** Getting a string from a gregorian calendar.
580 * @param gregCal Date to be converted.
581 * @return string (converted gregorian calendar).
583 public String
getStringFromGregorianCalendar( GregorianCalendar gregCal
) {
584 String sDate
= ( gregCal
.get( Calendar
.MONTH
) + 1 )
585 + STRING_SEPARATOR
+ gregCal
.get( Calendar
.DATE
)
586 // + STRING_SEPARATOR + ( gregCal.get( Calendar.MONTH ) + 1 )
587 + STRING_SEPARATOR
+ gregCal
.get( Calendar
.YEAR
);
592 /** Getting a GregorianCalendar from a string.
593 * @param sDate String to be converted.
594 * @return The result of the converting of the string.
596 public GregorianCalendar
getGregorianCalendarFromString( String sDate
) {
597 int []intDateValue
= this.getDateValuesFromString( sDate
);
599 return( new GregorianCalendar( intDateValue
[ 2 ], intDateValue
[ 0 ],
600 intDateValue
[ 1 ] ) );
603 /** Getting the day, month and year from a string.
604 * @param sDate String to be parsed.
605 * @return Returns an array of integer variables.
607 public int[] getDateValuesFromString( String sDate
) {
608 int[] intDateValues
= new int[ 3 ];
610 int intPositionFirstTag
= sDate
.indexOf( STRING_SEPARATOR
);
611 int intPositionSecondTag
= sDate
.indexOf(STRING_SEPARATOR
,
612 intPositionFirstTag
+ 1);
614 // Getting the value of the month
615 intDateValues
[ 0 ] = Integer
.parseInt(
616 sDate
.substring(0, intPositionFirstTag
)) - 1;
617 // Getting the value of the day
618 intDateValues
[ 1 ] = Integer
.parseInt(
619 sDate
.substring(intPositionFirstTag
+ 1, intPositionSecondTag
));
620 // Getting the value of the year
621 intDateValues
[ 2 ] = Integer
.parseInt(
622 sDate
.substring(intPositionSecondTag
+ 1, sDate
.length()));
624 return intDateValues
;
627 /** Getting a content from a specified cell.
628 * @param xcellrange Providing access to cells.
629 * @param intRow Number of row.
630 * @param intColumn Number of column.
631 * @return String from the specified cell.
633 public String
getStringFromCell( XCellRange xcellrange
, int intRow
,
635 XTextRange xtextrangeStartDate
= null;
638 // Getting the cell holding the information about the start date
639 XCell xcellStartDate
= xcellrange
.getCellByPosition(intColumn
,
641 // Querying for the interface XTextRange on the XCell
642 xtextrangeStartDate
= UnoRuntime
.queryInterface(XTextRange
.class, xcellStartDate
);
644 catch( Exception exception
) {
645 this.showExceptionMessage( exception
);
648 // Getting the start date
649 return xtextrangeStartDate
.getString().trim();
652 /** Writing a specified string to a specified cell.
653 * @param xcellrange Providing access to the cells.
654 * @param intRow Number of row.
655 * @param intColumn Number of column.
656 * @param sDate Date to write to the cell.
658 public void setStringToCell( XCellRange xcellrange
, int intRow
,
659 int intColumn
, String sDate
) {
661 // Getting the cell holding the information on the day to start
662 XCell xcellStartDate
= xcellrange
.getCellByPosition(intColumn
,
664 // Querying for the interface XTextRange on the XCell
665 XTextRange xtextrange
= UnoRuntime
.queryInterface(XTextRange
.class, xcellStartDate
);
666 // Setting the new start date
667 xtextrange
.setString( sDate
);
669 catch( Exception exception
) {
670 this.showExceptionMessage( exception
);
674 /** Calculates the week of day and calls the method "setStringToCell".
675 * @param gregCal Day to be written to the cell.
676 * @param xcellrange Providing access to the cells.
677 * @param intRow Number of row.
678 * @param intColumn Number of column.
680 public void setDayOfWeek( GregorianCalendar gregCal
,
681 XCellRange xcellrange
, int intRow
,
683 int intDayOfWeek
= gregCal
.get( Calendar
.DAY_OF_WEEK
);
684 String sDayOfWeek
= "";
685 if ( intDayOfWeek
== Calendar
.MONDAY
) {
687 } else if ( intDayOfWeek
== Calendar
.TUESDAY
) {
689 } else if ( intDayOfWeek
== Calendar
.WEDNESDAY
) {
691 } else if ( intDayOfWeek
== Calendar
.THURSDAY
) {
693 } else if ( intDayOfWeek
== Calendar
.FRIDAY
) {
697 this.setStringToCell( xcellrange
, intRow
, intColumn
,
701 /** Calculates the dates of the official holidays with help of Calc
703 * @param vectorHolidays Holding all holidays.
704 * @param xcellrange Providing the cells.
705 * @param xfunctionaccess Provides access to functions of the Calc.
706 * @param intYear Year to calculate the official holidays.
708 public void getOfficialHolidays(
709 ArrayList
<Object
> vectorHolidays
,
710 XCellRange xcellrange
,
711 XFunctionAccess xfunctionaccess
,
714 // Official Holidays for how many years?
715 final int intHowManyYears
= 2;
717 // Get the Official Holiday for two years
718 for ( int intNumberOfYear
= 0;
719 intNumberOfYear
<= ( intHowManyYears
- 1 );
720 intNumberOfYear
++ ) {
721 intYear
+= intNumberOfYear
;
723 // Getting the Easter sunday
724 Double dEasterSunday
= ( Double
)
725 xfunctionaccess
.callFunction(
726 "EASTERSUNDAY", new Object
[] { new Integer(intYear
) });
728 int intEasterSunday
= (int)Math
.round(
729 dEasterSunday
.doubleValue());
732 vectorHolidays
.add( xfunctionaccess
.callFunction(
735 new Integer( intYear
),
737 new Integer( 1 ) } ));
741 new Double( intEasterSunday
- 2 ) );
745 new Double( intEasterSunday
+ 1 ) );
748 vectorHolidays
.add( xfunctionaccess
.callFunction(
751 new Integer( intYear
),
753 new Integer( 1 ) } ));
756 vectorHolidays
.add(new Double(intEasterSunday
+ 39 ));
759 vectorHolidays
.add(new Double(intEasterSunday
+ 50 ));
761 // German Unification
762 vectorHolidays
.add( xfunctionaccess
.callFunction(
765 new Integer( intYear
),
767 new Integer( 3 ) } ));
769 // Christmas Day First
770 vectorHolidays
.add( xfunctionaccess
.callFunction(
773 new Integer( intYear
),
775 new Integer( 25 ) } ));
777 // Christmas Day Second
778 vectorHolidays
.add( xfunctionaccess
.callFunction(
781 new Integer( intYear
),
783 new Integer( 26 ) } ));
786 catch( Exception exception
) {
787 this.showExceptionMessage( exception
);
791 /** Returns the serial number of the date before or after a specified
792 * number of workdays.
793 * @param gregCalStartDate Date to start with the calculation.
794 * @param intDays Number of workdays (e.g. 5 or -3).
795 * @param objectHolidays Private and public holidays to take into account.
796 * @param xfunctionaccess Allows to call functions from the Calc.
797 * @return The gregorian date before or after a specified number of
800 public GregorianCalendar
getWorkday(
801 GregorianCalendar gregCalStartDate
,
802 int intDays
, Object
[][] objectHolidays
,
803 XFunctionAccess xfunctionaccess
) {
804 GregorianCalendar gregCalWorkday
= null;
807 // Getting the value of the start date
808 Double dDate
= ( Double
) xfunctionaccess
.callFunction(
811 new Integer( gregCalStartDate
.get( Calendar
.YEAR
) ),
812 new Integer( gregCalStartDate
.get( Calendar
.MONTH
) + 1 ),
813 new Integer( gregCalStartDate
.get( Calendar
.DATE
) )
816 Double dWorkday
= ( Double
) xfunctionaccess
.callFunction(
817 "com.sun.star.sheet.addin.Analysis.getWorkday",
818 new Object
[] { dDate
, new Integer( intDays
), objectHolidays
} );
820 Double dYear
= ( Double
) xfunctionaccess
.callFunction(
821 "YEAR", new Object
[] { dWorkday
} );
822 Double dMonth
= ( Double
) xfunctionaccess
.callFunction(
823 "MONTH", new Object
[] { dWorkday
} );
824 Double dDay
= ( Double
) xfunctionaccess
.callFunction(
825 "DAY", new Object
[] { dWorkday
} );
827 gregCalWorkday
= new GregorianCalendar(
829 dMonth
.intValue() - 1,
832 catch( Exception exception
) {
833 this.showExceptionMessage( exception
);
836 return gregCalWorkday
;
839 /** Getting the holidays from the spreadsheet.
840 * @param vectorHolidays Holding all holidays.
841 * @param xcellrange Providing the cells.
842 * @param xfunctionaccess Provides the access to functions of the Calc.
844 public void getPrivateHolidays( ArrayList
<Object
> vectorHolidays
,
845 XCellRange xcellrange
,
846 XFunctionAccess xfunctionaccess
) {
848 int intRow
= ToDoImpl
.INT_ROW_HOLIDAYS_START
;
849 int intColumn
= ToDoImpl
.INT_COLUMN_HOLIDAYS_START
;
851 double dHolidayStart
= xcellrange
.getCellByPosition(
852 intColumn
, intRow
).getValue();
854 double dHolidayEnd
= xcellrange
.getCellByPosition(
855 intColumn
+ 1, intRow
).getValue();
857 while ( dHolidayStart
!= 0 ) {
858 if ( dHolidayEnd
== 0 ) {
860 new Integer( (int) Math
.round(
864 for ( int intHoliday
= (int) Math
.round(
866 intHoliday
<= (int) Math
.round( dHolidayEnd
);
868 vectorHolidays
.add( new Double( intHoliday
) );
873 dHolidayStart
= xcellrange
.getCellByPosition(
874 intColumn
, intRow
).getValue();
875 dHolidayEnd
= xcellrange
.getCellByPosition(
876 intColumn
+ 1, intRow
).getValue();
879 catch( Exception exception
) {
880 this.showExceptionMessage( exception
);
884 /** Showing the stack trace in a JOptionPane.
885 * @param sMessage The message to show.
887 public void showMessage( String sMessage
) {
888 javax
.swing
.JFrame jframe
= new javax
.swing
.JFrame();
889 jframe
.setLocation(100, 100);
890 jframe
.setSize(300, 200);
891 jframe
.setVisible(true);
892 javax
.swing
.JOptionPane
.showMessageDialog(
893 jframe
, sMessage
, "Debugging information",
894 javax
.swing
.JOptionPane
.INFORMATION_MESSAGE
);
898 /** Writing the stack trace from an exception to a string and calling
899 * the method showMessage() with this string.
900 * @param exception The occurred exception.
903 public void showExceptionMessage( Exception exception
) {
904 java
.io
.StringWriter swriter
= new java
.io
.StringWriter();
905 java
.io
.PrintWriter printwriter
=
906 new java
.io
.PrintWriter( swriter
);
907 exception
.printStackTrace( printwriter
);
908 System
.err
.println( exception
);
909 this.showMessage( swriter
.getBuffer().substring(0) );
914 * Gives a factory for creating the service.
915 * This method is called by the <code>JavaLoader</code>
917 * @return returns a <code>XSingleComponentFactory</code> for creating
919 * @param sImplName the name of the implementation for which a
921 * @see com.sun.star.comp.loader.JavaLoader
923 public static XSingleComponentFactory
__getComponentFactory(String sImplName
) {
924 XSingleComponentFactory xFactory
= null;
926 if ( sImplName
.equals( ToDoImpl
.class.getName() ) )
927 xFactory
= Factory
.createComponentFactory(ToDoImpl
.class,
928 ToDoImpl
.getServiceNames());
934 * Writes the service information into the given registry key.
935 * This method is called by the <code>JavaLoader</code>
937 * @return returns true if the operation succeeded
938 * @param regKey the registryKey
939 * @see com.sun.star.comp.loader.JavaLoader
941 // This method not longer necessary since OOo 3.4 where the component registration
942 // was changed to passive component registration. For more details see
943 // http://wiki.services.openoffice.org/wiki/Passive_Component_Registration
945 // public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
946 // return Factory.writeRegistryServiceInfo(ToDoImpl.class.getName(),
947 // ToDoImpl.getServiceNames(), regKey);