summaryrefslogtreecommitdiff
path: root/odk/examples/DevelopersGuide/Forms/SalesFilter.java
diff options
context:
space:
mode:
Diffstat (limited to 'odk/examples/DevelopersGuide/Forms/SalesFilter.java')
-rw-r--r--odk/examples/DevelopersGuide/Forms/SalesFilter.java518
1 files changed, 518 insertions, 0 deletions
diff --git a/odk/examples/DevelopersGuide/Forms/SalesFilter.java b/odk/examples/DevelopersGuide/Forms/SalesFilter.java
new file mode 100644
index 000000000000..a61d152d2ff9
--- /dev/null
+++ b/odk/examples/DevelopersGuide/Forms/SalesFilter.java
@@ -0,0 +1,518 @@
+/*************************************************************************
+ *
+ * $RCSfile: SalesFilter.java,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * last change: $Author: rt $ $Date: 2005-01-31 16:32:07 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * the BSD license.
+ *
+ * Copyright (c) 2003 by Sun Microsystems, Inc.
+ * 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.
+ *
+ *************************************************************************/
+
+import com.sun.star.uno.*;
+import com.sun.star.beans.*;
+import com.sun.star.form.*;
+import com.sun.star.lang.*;
+import com.sun.star.sdb.*;
+import com.sun.star.sdbc.*;
+import com.sun.star.sdbcx.*;
+import com.sun.star.container.*;
+import com.sun.star.awt.*;
+
+import java.util.Vector;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/**************************************************************************/
+/** helper class for filtering the sales form
+*/
+class SalesFilter implements XActionListener, XPropertyChangeListener, XResetListener
+{
+ private DocumentHelper m_aDocument;
+ private XPropertySet m_xSalesForm;
+
+ private XPropertySet m_xFilterList;
+ private XPropertySet m_xManualFilter;
+ private XPropertySet m_xApplyFilter;
+
+ private boolean m_bSettingsDirty;
+ private boolean m_bSettingDate;
+ private boolean m_bAdjustingFilterList;
+ private short m_nPreviousFilterIndex;
+ private java.util.Vector m_aFilterDates;
+
+ /* ------------------------------------------------------------------ */
+ public SalesFilter( DocumentHelper aDocument, XPropertySet xSalesForm,
+ XPropertySet xFilterListBox, XPropertySet xManualFilterEdit, XPropertySet xStartFilterButton )
+ {
+ m_aFilterDates = new java.util.Vector();
+ m_bSettingsDirty = false;
+ m_bSettingDate = false;
+ m_bAdjustingFilterList = false;
+ m_nPreviousFilterIndex = -1;
+ initFilterDates();
+
+ // -------------------------------------------------------------
+ // remember the components
+ m_aDocument = aDocument;
+ m_xSalesForm = xSalesForm;
+
+ m_xFilterList = xFilterListBox;
+ m_xManualFilter = xManualFilterEdit;
+ m_xApplyFilter = xStartFilterButton;
+
+ try
+ {
+ // ----------------------------------------------------------
+ // init control models
+ m_xFilterList.setPropertyValue( "Dropdown", new Boolean( true ) );
+ m_xFilterList.setPropertyValue( "LineCount", new Short( (short)11 ) );
+ m_xFilterList.setPropertyValue( "StringItemList", new String[] { "ever (means no filter)", "this morning", "1 week ago", "1 month ago", "1 year ago", "<other>" } );
+ m_xFilterList.setPropertyValue( "DefaultSelection", new Short[] { new Short( (short)0 ) } );
+
+ m_xApplyFilter.setPropertyValue( "Label", "Apply Filter" );
+
+ updateFilterControl();
+ updateApplyButton();
+
+ // ----------------------------------------------------------
+ // add as listener to the events which require action
+
+ // want to know about changed selection
+ m_xFilterList.addPropertyChangeListener( "SelectedItems", this );
+ m_xManualFilter.addPropertyChangeListener( "Date", this );
+
+ // want to know about the date field beeing reset
+ XReset xReset = UNO.queryReset( m_xManualFilter );
+ xReset.addResetListener( this );
+
+ // for the button, we can add to the control only, not to the model
+ // - clicking a button is something which happens on the _control_.
+ DocumentViewHelper aView = m_aDocument.getCurrentView();
+ XButton xButton = (XButton)aView.getFormControl( m_xApplyFilter, XButton.class );
+ xButton.addActionListener( this );
+ }
+ catch ( com.sun.star.uno.Exception e )
+ {
+ System.out.println(e);
+ e.printStackTrace();
+ }
+ }
+
+ /* ==================================================================
+ = helper
+ ================================================================== */
+ /* ------------------------------------------------------------------ */
+ protected void initFilterDates()
+ {
+ m_aFilterDates.clear();
+ java.util.Date aNowAndHere = new java.util.Date();
+ aNowAndHere.setHours( 0 );
+ aNowAndHere.setMinutes( 0 );
+ aNowAndHere.setSeconds( 0 );
+
+ // for every list entry, we add a java.util.Date to m_aFilterDates indicating
+ // since when the sales should be listed
+
+ // ever
+ m_aFilterDates.add( null );
+
+ // this morning
+ m_aFilterDates.add( aNowAndHere );
+
+ // one week ago
+ GregorianCalendar aCalendar = new GregorianCalendar( );
+ aCalendar.setTime( aNowAndHere );
+ aCalendar.add( Calendar.DATE, -7 );
+ m_aFilterDates.add( aCalendar.getTime() );
+
+ // one month ago
+ aCalendar.setTime( aNowAndHere );
+ aCalendar.add( Calendar.MONTH, -1 );
+ m_aFilterDates.add( aCalendar.getTime() );
+
+ // one year ago
+ aCalendar.setTime( aNowAndHere );
+ aCalendar.add( Calendar.YEAR, -1 );
+ m_aFilterDates.add( aCalendar.getTime() );
+
+ // the custom date
+ m_aFilterDates.add( null );
+ }
+
+ /* ------------------------------------------------------------------ */
+ /** translates a date from the AWT Toolkit format to a java.util.date, or
+ vice versa.
+ */
+ protected Object translateDate( Object aDate ) throws java.lang.Exception
+ {
+ Object aReturn = null;
+
+ GregorianCalendar aCalDate = new GregorianCalendar();
+ if ( aDate.getClass().equals( Class.forName( "java.util.Date" ) ) )
+ {
+ aCalDate.setTime( (java.util.Date)aDate );
+
+ int nDate = aCalDate.get( Calendar.YEAR );
+ nDate = nDate * 100 + aCalDate.get( Calendar.MONTH ) + 1;
+ nDate = nDate * 100 + aCalDate.get( Calendar.DAY_OF_MONTH );
+
+ aReturn = new Integer( nDate );
+ }
+ else if ( aDate.getClass().equals( Class.forName( "java.lang.Integer" ) ) )
+ {
+ int nToolkitDate = ((Integer)aDate).intValue();
+ aCalDate.set( Calendar.DAY_OF_MONTH, ( nToolkitDate % 100 ) );
+ nToolkitDate /= 100;
+ aCalDate.set( Calendar.MONTH, ( nToolkitDate % 100 ) - 1 );
+ nToolkitDate /= 100;
+ aCalDate.set( Calendar.YEAR, ( nToolkitDate % 10000 ) );
+
+ // default the time
+ aCalDate.set( Calendar.HOUR_OF_DAY, 0 );
+ aCalDate.set( Calendar.MINUTE, 0 );
+ aCalDate.set( Calendar.SECOND, 0 );
+
+ aReturn = aCalDate.getTime();
+ }
+
+ return aReturn;
+ }
+
+ /* ------------------------------------------------------------------ */
+ /** translates the given date into the ODBC date notation, which then can be used
+ for setting a filter at a row set
+ */
+ protected String getOdbcDate( Object aDate ) throws java.lang.Exception
+ {
+ String sOdbcDate = "";
+ if ( null != aDate )
+ {
+ if ( !aDate.getClass().equals( Class.forName( "java.util.Date" ) ) )
+ aDate = translateDate( aDate );
+
+ if ( aDate.getClass().equals( Class.forName( "java.util.Date" ) ) )
+ {
+ GregorianCalendar aCal = new GregorianCalendar();
+ aCal.setTime( (java.util.Date)aDate );
+
+ sOdbcDate += new String( "{D '" );
+ sOdbcDate += (new Integer( aCal.get( Calendar.YEAR ) ) ).toString();
+ sOdbcDate += "-";
+
+ int nMonth = aCal.get( Calendar.MONTH ) + 1;
+ if ( nMonth < 10 )
+ sOdbcDate += "0";
+ sOdbcDate += (new Integer( nMonth ) ).toString();
+ sOdbcDate += "-";
+
+ int nDay = aCal.get( Calendar.DAY_OF_MONTH );
+ if ( nDay < 10 )
+ sOdbcDate += "0";
+ sOdbcDate += (new Integer( nDay ) ).toString();
+ sOdbcDate += "'}";
+ }
+ }
+ return sOdbcDate;
+ }
+
+ /* ------------------------------------------------------------------ */
+ protected void updateApplyButton()
+ {
+ try
+ {
+ m_xApplyFilter.setPropertyValue( "Enabled", new Boolean( m_bSettingsDirty ) );
+ }
+ catch ( com.sun.star.uno.Exception e )
+ {
+ System.out.println(e);
+ e.printStackTrace();
+ }
+ }
+
+ /* ------------------------------------------------------------------ */
+ /** creates a normalized calendar object from the given java.util.Date
+ */
+ protected GregorianCalendar getCalendarObject( java.util.Date aDate )
+ {
+ // the date part
+ GregorianCalendar aReturn = null;
+ if ( null != aDate )
+ {
+ aReturn = new GregorianCalendar( );
+ aReturn.setTime( aDate );
+
+ // normalize the time part
+ aReturn.set( Calendar.HOUR_OF_DAY, 0 );
+ aReturn.set( Calendar.MINUTE, 0 );
+ aReturn.set( Calendar.SECOND, 0 );
+ }
+
+ return aReturn;
+ }
+
+ /* ------------------------------------------------------------------ */
+ final protected short getCurrentSelectedFilter( ) throws com.sun.star.uno.Exception
+ {
+ short[] aSelected = (short[])m_xFilterList.getPropertyValue( "SelectedItems" );
+ if ( 0 < aSelected.length )
+ return aSelected[0];
+ return -1;
+ }
+
+ /* ------------------------------------------------------------------ */
+ /** checks if the given filter index referes to the "<other>" entry which
+ allows the user to manually enter a date
+ */
+ final protected boolean isManualFilter( short nFilterIndex )
+ {
+ return ( 5 == nFilterIndex );
+ }
+
+ /* ------------------------------------------------------------------ */
+ protected void updateFilterControl()
+ {
+ try
+ {
+ if ( isManualFilter( m_nPreviousFilterIndex ) )
+ { // previously, the "custom" filter date was selected
+ // -> remember the date entered
+ Object aDate = translateDate( m_xManualFilter.getPropertyValue( "Date" ) );
+ m_aFilterDates.set( m_nPreviousFilterIndex, aDate );
+ }
+
+ // check the current selection
+ if ( !m_bAdjustingFilterList )
+ {
+ m_nPreviousFilterIndex = getCurrentSelectedFilter( );
+
+ // custom filter?
+ boolean bCustomFilter = isManualFilter( m_nPreviousFilterIndex );
+ m_xManualFilter.setPropertyValue( "Enabled", new Boolean( bCustomFilter ) );
+ if ( bCustomFilter )
+ m_aDocument.getCurrentView().grabControlFocus( m_xManualFilter );
+
+ m_bSettingDate = true;
+ Object aSelectedDateLimit = m_aFilterDates.elementAt( m_nPreviousFilterIndex );
+ if ( null != aSelectedDateLimit )
+ {
+ // translate this date into one the AWT Toolkit understands
+ Integer aTKDate = (Integer)translateDate( aSelectedDateLimit );
+ m_xManualFilter.setPropertyValue( "Date", aTKDate );
+ }
+ else
+ m_xManualFilter.setPropertyValue( "Date", new Any( new Type(), null ) );
+ m_bSettingDate = false;
+ }
+ }
+ catch ( java.lang.Exception e )
+ {
+ System.out.println(e);
+ e.printStackTrace();
+ }
+ }
+
+ /* ------------------------------------------------------------------ */
+ /** compares the date part of two calendars
+ <p>For some strange reason I do not understand, GregorianCalendar.equals( GregorianCalendar )
+ seems to always return false, as well as . Thus here is a method which compare two calendars,
+ restricted to their date part</p>
+ */
+ protected boolean equalDate( Calendar aLHS, Calendar aRHS )
+ {
+ if ( ( null == aLHS ) != ( null == aRHS ) )
+ // only one of them is null
+ return false;
+
+ if ( null == aLHS )
+ // both are null
+ return true;
+
+ return ( aLHS.get( Calendar.YEAR ) == aRHS.get( Calendar.YEAR ) )
+ && ( aLHS.get( Calendar.MONTH ) == aRHS.get( Calendar.MONTH ) )
+ && ( aLHS.get( Calendar.DAY_OF_MONTH ) == aRHS.get( Calendar.DAY_OF_MONTH ) );
+ }
+
+ /* ------------------------------------------------------------------ */
+ /** adds the current user filter to the list of date filters
+ @return
+ the index of the newly added date filter in the filter list
+ */
+ protected short addCurrentFilter( ) throws java.lang.Exception
+ {
+ // the current string items
+ String[] aOldFilterItems = (String[])m_xFilterList.getPropertyValue( "StringItemList" );
+
+ // translate this into a vector - much more comfort to work with a vector than with an array ....
+ java.util.Vector aFilterItems = new java.util.Vector();
+ for ( int i=0; i<aOldFilterItems.length; ++i )
+ aFilterItems.add( aOldFilterItems[i] );
+
+ // the currently entered user defined filter date
+ Object aDate = translateDate( m_xManualFilter.getPropertyValue( "Date" ) );
+ GregorianCalendar aDateCal = getCalendarObject( (java.util.Date)aDate );
+ // check if this date is already present in the list of user defined dates
+ for ( int i=0; i<m_aFilterDates.size(); ++i )
+ {
+ if ( !isManualFilter( (short)i ) ) // do not compare with the manual filter
+ {
+ GregorianCalendar aCheckCal = getCalendarObject( (java.util.Date)m_aFilterDates.elementAt( i ) );
+ if ( equalDate( aDateCal, aCheckCal ) )
+ return (short)i;
+ }
+ }
+ System.out.println( );
+
+ if ( aFilterItems.size() > 10 ) // (6 standard items + 5 user defined items)
+ {
+ // the first (and thus oldes) user defined item
+ aFilterItems.removeElementAt( 6 );
+ // keep our date vector synchron
+ m_aFilterDates.removeElementAt( 6 );
+ }
+
+ // add the current user defined filter
+ aFilterItems.add( aDate.toString() );
+ m_aFilterDates.add( aDate );
+
+ // write back the string item list
+ m_bAdjustingFilterList = true;
+ String[] aNewFilterItems = new String[ aFilterItems.size() ];
+ for ( int i=0; i<aFilterItems.size(); ++i )
+ aNewFilterItems[i] = (String)aFilterItems.elementAt( i );
+ m_xFilterList.setPropertyValue( "StringItemList", aNewFilterItems );
+ m_bAdjustingFilterList = false;
+
+ return (short)(aNewFilterItems.length - 1 );
+ }
+
+ /* ------------------------------------------------------------------ */
+ protected void executeCurrentFilter()
+ {
+ try
+ {
+ // we keep the date field consistent with whatever the user chooses in the
+ // list box, so just ask the field
+ Object aDate = translateDate( m_xManualFilter.getPropertyValue( "Date" ) );
+ String sOdbcDate = getOdbcDate( aDate );
+
+ // if this filter was a manually entered filter, we add it to the filter list
+ // box to allow quick-select it later on.
+ if ( isManualFilter( getCurrentSelectedFilter() ) )
+ {
+ short nNewUserDefinedFilterPos = addCurrentFilter();
+ m_xFilterList.setPropertyValue( "SelectedItems", new short[] { nNewUserDefinedFilterPos } );
+ }
+
+ // set this as filter on the form
+ String sCompleteFilter = "";
+ if ( ( null != sOdbcDate ) && ( 0 != sOdbcDate.length() ) )
+ {
+ sCompleteFilter = "SALEDATE >= ";
+ sCompleteFilter += sOdbcDate;
+ }
+ m_xSalesForm.setPropertyValue( "Filter", sCompleteFilter );
+ m_xSalesForm.setPropertyValue( "ApplyFilter", new Boolean( true ) );
+
+ // and reload the form
+ XLoadable xLoad = (XLoadable)UnoRuntime.queryInterface(
+ XLoadable.class, m_xSalesForm );
+ xLoad.reload();
+
+ m_aDocument.getCurrentView().grabControlFocus( m_xFilterList );
+ }
+ catch ( java.lang.Exception e )
+ {
+ System.out.println(e);
+ e.printStackTrace();
+ }
+ }
+
+ /* ==================================================================
+ = UNO callbacks
+ ================================================================== */
+ /* ------------------------------------------------------------------ */
+ // XActionListener overridables
+ /* ------------------------------------------------------------------ */
+ public boolean approveReset( EventObject aEvent ) throws com.sun.star.uno.RuntimeException
+ {
+ return false;
+ // do not allow the date field to be reset - it would set it's content
+ // to the current date
+ // Note that another possible solution would be to wait for the resetted
+ // event and correct the value there
+ }
+
+ /* ------------------------------------------------------------------ */
+ public void resetted( EventObject aEvent ) throws com.sun.star.uno.RuntimeException
+ {
+ }
+
+ /* ------------------------------------------------------------------ */
+ // XActionListener overridables
+ /* ------------------------------------------------------------------ */
+ public void actionPerformed( ActionEvent aEvent ) throws com.sun.star.uno.RuntimeException
+ {
+ executeCurrentFilter();
+
+ m_bSettingsDirty = false;
+ updateApplyButton();
+ }
+
+ /* ------------------------------------------------------------------ */
+ // XItemListener overridables
+ /* ------------------------------------------------------------------ */
+ public void propertyChange( PropertyChangeEvent aEvent ) throws com.sun.star.uno.RuntimeException
+ {
+ if ( aEvent.PropertyName.equals( "SelectedItems" ) )
+ {
+ updateFilterControl();
+
+ m_bSettingsDirty = true;
+ updateApplyButton();
+ }
+ else if ( aEvent.PropertyName.equals( "Date" ) && !m_bSettingDate )
+ {
+ m_bSettingsDirty = true;
+ updateApplyButton();
+ }
+ }
+
+ /* ------------------------------------------------------------------ */
+ // XEventListener overridables
+ /* ------------------------------------------------------------------ */
+ public void disposing( EventObject aEvent )
+ {
+ // not interested in
+ }
+
+};