1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #include <svtools/editbrowsebox.hxx>
31 #include <com/sun/star/accessibility/XAccessible.hpp>
32 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33 #include "editbrowseboximpl.hxx"
34 #include <comphelper/types.hxx>
35 #include <toolkit/helper/vclunohelper.hxx>
36 #include "svtaccessiblefactory.hxx"
37 
38 namespace svt
39 {
40 	using namespace com::sun::star::accessibility;
41 	using namespace com::sun::star::uno;
42 	using namespace ::com::sun::star::accessibility::AccessibleEventId;
43 
44 // -----------------------------------------------------------------------------
45 Reference< XAccessible > EditBrowseBox::CreateAccessibleCheckBoxCell(long _nRow, sal_uInt16 _nColumnPos,const TriState& eState,sal_Bool _bEnabled)
46 {
47     Reference< XAccessible > xAccessible( GetAccessible() );
48 	Reference< XAccessibleContext > xAccContext;
49     if ( xAccessible.is() )
50         xAccContext = xAccessible->getAccessibleContext();
51 
52     Reference< XAccessible > xReturn;
53     if ( xAccContext.is() )
54     {
55         xReturn = getAccessibleFactory().createAccessibleCheckBoxCell(
56             xAccContext->getAccessibleChild( ::svt::BBINDEX_TABLE ),
57             *this,
58             NULL,
59             _nRow,
60             _nColumnPos,
61 		    eState,
62 		    _bEnabled,
63             sal_True
64         );
65     }
66     return xReturn;
67 }
68 // -----------------------------------------------------------------------------
69 Reference< XAccessible > EditBrowseBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
70 {
71     return BrowseBox::CreateAccessibleCell( _nRow, _nColumnPos );
72 }
73 // -----------------------------------------------------------------------------
74 sal_Int32 EditBrowseBox::GetAccessibleControlCount() const
75 {
76     return IsEditing() ? 1 : 0;
77 }
78 // -----------------------------------------------------------------------------
79 void EditBrowseBox::implCreateActiveAccessible( )
80 {
81     DBG_ASSERT( IsEditing(), "EditBrowseBox::implCreateActiveAccessible: not to be called if we're not editing currently!" );
82     DBG_ASSERT( !m_aImpl->m_xActiveCell.is(), "EditBrowseBox::implCreateActiveAccessible: not to be called if the old one is still alive!" );
83 
84     if ( !m_aImpl->m_xActiveCell.is() && IsEditing() )
85     {
86  	    Reference< XAccessible > xCont = aController->GetWindow().GetAccessible();
87  	    Reference< XAccessible > xMy = GetAccessible();
88  	    if ( xMy.is() && xCont.is() )
89   	    {
90  		    m_aImpl->m_xActiveCell = getAccessibleFactory().createEditBrowseBoxTableCellAccess(
91  			    xMy,														// parent accessible
92  			    xCont,														// control accessible
93  			    VCLUnoHelper::GetInterface( &aController->GetWindow() ),	// focus window (for notifications)
94  			    *this,														// the browse box
95  			    GetCurRow(),
96  			    GetColumnPos( GetCurColumnId() )
97  		    );
98 
99  		    commitBrowseBoxEvent( CHILD, makeAny( m_aImpl->m_xActiveCell ), Any() );
100   	    }
101     }
102 }
103 
104 // -----------------------------------------------------------------------------
105 Reference< XAccessible > EditBrowseBox::CreateAccessibleControl( sal_Int32
106 #ifdef DBG_UTIL
107 _nIndex
108 #endif
109 )
110 {
111     DBG_ASSERT( 0 == _nIndex, "EditBrowseBox::CreateAccessibleControl: invalid index!" );
112 
113     if ( isAccessibleAlive() )
114     {
115     	if ( !m_aImpl->m_xActiveCell.is() )
116     		implCreateActiveAccessible();
117     }
118 
119     return m_aImpl->m_xActiveCell;
120 }
121 // -----------------------------------------------------------------------------
122 Reference<XAccessible > EditBrowseBox::CreateAccessibleRowHeader( sal_Int32 _nRow )
123 {
124     return BrowseBox::CreateAccessibleRowHeader( _nRow );
125 }
126 // -----------------------------------------------------------------------------
127 void EditBrowseBoxImpl::clearActiveCell()
128 {
129 	try
130 	{
131 		::comphelper::disposeComponent(m_xActiveCell);
132 	}
133 	catch(const Exception&)
134 	{
135 		OSL_ENSURE( sal_False, "EditBrowseBoxImpl::clearActiveCell: caught an exception while disposing the AccessibleCell!" );
136 	}
137 
138 	m_xActiveCell = NULL;
139 }
140 // -----------------------------------------------------------------------------
141 void EditBrowseBox::GrabTableFocus()
142 {
143 	if ( aController.Is() )
144 		aController->GetWindow().GrabFocus();
145 }
146 //------------------------------------------------------------------------------
147 void EditBrowseBox::DetermineFocus( const sal_uInt16 _nGetFocusFlags )
148 {
149 	sal_Bool bFocus = sal_False;
150 	for (Window* pWindow = Application::GetFocusWindow();
151 		 pWindow && !bFocus;
152 		 pWindow = pWindow->GetParent())
153 		 bFocus = pWindow == this;
154 
155 	if (bFocus != bHasFocus)
156 	{
157 		bHasFocus = bFocus;
158 
159 		if ( GetBrowserFlags( ) & EBBF_SMART_TAB_TRAVEL )
160 		{
161 			if	(	bHasFocus							// we got the focus
162 				&&	( _nGetFocusFlags & GETFOCUS_TAB )	// using the TAB key
163 				)
164 			{
165 				long nRows = GetRowCount();
166 				sal_uInt16 nCols = ColCount();
167 
168 				if ( ( nRows > 0 ) && ( nCols > 0 ) )
169 				{
170 					if ( _nGetFocusFlags & GETFOCUS_FORWARD )
171 					{
172 						if ( GetColumnId( 0 ) != 0 )
173 						{
174 							GoToRowColumnId( 0, GetColumnId( 0 ) );
175 						}
176 						else
177 						{	// the first column is the handle column -> not focussable
178 							if ( nCols > 1 )
179 								GoToRowColumnId( 0, GetColumnId( 1 ) );
180 						}
181 					}
182 					else if ( _nGetFocusFlags & GETFOCUS_BACKWARD )
183 					{
184 						GoToRowColumnId( nRows - 1, GetColumnId( nCols -1 ) );
185 					}
186 				}
187 			}
188 		}
189 	}
190 }
191 // -----------------------------------------------------------------------------
192 Rectangle EditBrowseBox::GetFieldCharacterBounds(sal_Int32 _nRow,sal_Int32 _nColumnPos,sal_Int32 _nIndex)
193 {
194 	Rectangle aRect;
195 	if ( SeekRow(_nRow) )
196 	{
197 		CellController* pController = GetController(
198             _nRow, GetColumnId( sal::static_int_cast< sal_uInt16 >(_nColumnPos) ) );
199 		if ( pController )
200 			aRect = pController->GetWindow().GetCharacterBounds(_nIndex);
201 	}
202 	return aRect;
203 }
204 // -----------------------------------------------------------------------------
205 sal_Int32 EditBrowseBox::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
206 {
207 	sal_Int32 nRet = -1;
208 	if ( SeekRow(_nRow) )
209 	{
210 		CellController* pController = GetController(
211             _nRow, GetColumnId( sal::static_int_cast< sal_uInt16 >(_nColumnPos) ) );
212 		if ( pController )
213 			nRet = pController->GetWindow().GetIndexForPoint(_rPoint);
214 	}
215 	return nRet;
216 }
217 // -----------------------------------------------------------------------------
218 // -----------------------------------------------------------------------------
219 } // namespace svt
220 // -----------------------------------------------------------------------------
221 
222 
223