1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <table/defaultinputhandler.hxx>
22 #include <table/tablecontrolinterface.hxx>
23 
24 #include "mousefunction.hxx"
25 
26 #include <vcl/event.hxx>
27 #include <osl/diagnose.h>
28 
29 
30 namespace svt { namespace table
31 {
32 
33 
34     typedef ::rtl::Reference< MouseFunction >  PMouseFunction;
35     typedef ::std::vector< PMouseFunction >     MouseFunctions;
36     struct DefaultInputHandler_Impl
37     {
38         PMouseFunction  pActiveFunction;
39         MouseFunctions  aMouseFunctions;
40     };
41 
42 
43     //= DefaultInputHandler
44 
45 
DefaultInputHandler()46     DefaultInputHandler::DefaultInputHandler()
47         :m_pImpl( new DefaultInputHandler_Impl )
48     {
49         m_pImpl->aMouseFunctions.push_back( new ColumnResize );
50         m_pImpl->aMouseFunctions.push_back( new RowSelection );
51         m_pImpl->aMouseFunctions.push_back( new ColumnSortHandler );
52     }
53 
54 
~DefaultInputHandler()55     DefaultInputHandler::~DefaultInputHandler()
56     {
57     }
58 
59 
60     namespace
61     {
lcl_delegateMouseEvent(DefaultInputHandler_Impl & i_impl,ITableControl & i_control,const MouseEvent & i_event,FunctionResult (MouseFunction::* i_handlerMethod)(ITableControl &,const MouseEvent &))62         bool lcl_delegateMouseEvent( DefaultInputHandler_Impl& i_impl, ITableControl& i_control, const MouseEvent& i_event,
63             FunctionResult ( MouseFunction::*i_handlerMethod )( ITableControl&, const MouseEvent& ) )
64         {
65             if ( i_impl.pActiveFunction.is() )
66             {
67                 bool furtherHandler = false;
68                 switch ( (i_impl.pActiveFunction.get()->*i_handlerMethod)( i_control, i_event ) )
69                 {
70                 case ActivateFunction:
71                     OSL_ENSURE( false, "lcl_delegateMouseEvent: unexpected - function already *is* active!" );
72                     break;
73                 case ContinueFunction:
74                     break;
75                 case DeactivateFunction:
76                     i_impl.pActiveFunction.clear();
77                     break;
78                 case SkipFunction:
79                     furtherHandler = true;
80                     break;
81                 }
82                 if ( !furtherHandler )
83                     // handled the event
84                     return true;
85             }
86 
87             // ask all other handlers
88             bool handled = false;
89             for (auto const& mouseFunction : i_impl.aMouseFunctions)
90             {
91                 if (handled)
92                     break;
93                 if (mouseFunction == i_impl.pActiveFunction)
94                     // we already invoked this function
95                     continue;
96 
97                 switch ( (mouseFunction.get()->*i_handlerMethod)( i_control, i_event ) )
98                 {
99                 case ActivateFunction:
100                     i_impl.pActiveFunction = mouseFunction;
101                     handled = true;
102                     break;
103                 case ContinueFunction:
104                 case DeactivateFunction:
105                     OSL_ENSURE( false, "lcl_delegateMouseEvent: unexpected: inactive handler cannot be continued or deactivated!" );
106                     break;
107                 case SkipFunction:
108                     handled = false;
109                     break;
110                 }
111             }
112             return handled;
113         }
114     }
115 
116 
MouseMove(ITableControl & i_tableControl,const MouseEvent & i_event)117     bool DefaultInputHandler::MouseMove( ITableControl& i_tableControl, const MouseEvent& i_event )
118     {
119         return lcl_delegateMouseEvent( *m_pImpl, i_tableControl, i_event, &MouseFunction::handleMouseMove );
120     }
121 
122 
MouseButtonDown(ITableControl & i_tableControl,const MouseEvent & i_event)123     bool DefaultInputHandler::MouseButtonDown( ITableControl& i_tableControl, const MouseEvent& i_event )
124     {
125         return lcl_delegateMouseEvent( *m_pImpl, i_tableControl, i_event, &MouseFunction::handleMouseDown );
126     }
127 
128 
MouseButtonUp(ITableControl & i_tableControl,const MouseEvent & i_event)129     bool DefaultInputHandler::MouseButtonUp( ITableControl& i_tableControl, const MouseEvent& i_event )
130     {
131         return lcl_delegateMouseEvent( *m_pImpl, i_tableControl, i_event, &MouseFunction::handleMouseUp );
132     }
133 
134 
KeyInput(ITableControl & _rControl,const KeyEvent & rKEvt)135     bool DefaultInputHandler::KeyInput( ITableControl& _rControl, const KeyEvent& rKEvt )
136     {
137         bool bHandled = false;
138 
139         const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
140         sal_uInt16 nKeyCode = rKeyCode.GetCode();
141 
142         struct ActionMapEntry
143         {
144             sal_uInt16 const              nKeyCode;
145             sal_uInt16 const              nKeyModifier;
146             TableControlAction const  eAction;
147         }
148         static const aKnownActions[] = {
149             { KEY_DOWN,     0,          cursorDown },
150             { KEY_UP,       0,          cursorUp },
151             { KEY_LEFT,     0,          cursorLeft },
152             { KEY_RIGHT,    0,          cursorRight },
153             { KEY_HOME,     0,          cursorToLineStart },
154             { KEY_END,      0,          cursorToLineEnd },
155             { KEY_PAGEUP,   0,          cursorPageUp },
156             { KEY_PAGEDOWN, 0,          cursorPageDown },
157             { KEY_PAGEUP,   KEY_MOD1,   cursorToFirstLine },
158             { KEY_PAGEDOWN, KEY_MOD1,   cursorToLastLine },
159             { KEY_HOME,     KEY_MOD1,   cursorTopLeft },
160             { KEY_END,      KEY_MOD1,   cursorBottomRight },
161             { KEY_SPACE,    KEY_MOD1,   cursorSelectRow },
162             { KEY_UP,       KEY_SHIFT,  cursorSelectRowUp },
163             { KEY_DOWN,     KEY_SHIFT,  cursorSelectRowDown },
164             { KEY_END,      KEY_SHIFT,  cursorSelectRowAreaBottom },
165             { KEY_HOME,     KEY_SHIFT,  cursorSelectRowAreaTop },
166 
167             { 0, 0, invalidTableControlAction }
168         };
169 
170         const ActionMapEntry* pActions = aKnownActions;
171         for ( ; pActions->eAction != invalidTableControlAction; ++pActions )
172         {
173             if ( ( pActions->nKeyCode == nKeyCode ) && ( pActions->nKeyModifier == rKeyCode.GetModifier() ) )
174             {
175                 bHandled = _rControl.dispatchAction( pActions->eAction );
176                 break;
177             }
178         }
179 
180         return bHandled;
181     }
182 
183 
GetFocus(ITableControl & _rControl)184     bool DefaultInputHandler::GetFocus( ITableControl& _rControl )
185     {
186         _rControl.showCursor();
187         return false;   // continue processing
188     }
189 
190 
LoseFocus(ITableControl & _rControl)191     bool DefaultInputHandler::LoseFocus( ITableControl& _rControl )
192     {
193         _rControl.hideCursor();
194         return false;   // continue processing
195     }
196 
197 
198 } } // namespace svt::table
199 
200 
201 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
202