Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <vcl/svapp.hxx>
30 : : #include <vcl/taskpanelist.hxx>
31 : :
32 : : #include "olinewin.hxx"
33 : : #include "olinetab.hxx"
34 : : #include "document.hxx"
35 : : #include "dbfunc.hxx"
36 : : #include "sc.hrc"
37 : :
38 : : // ============================================================================
39 : :
40 : : const long SC_OL_BITMAPSIZE = 12;
41 : : const long SC_OL_POSOFFSET = 2;
42 : :
43 : : const size_t SC_OL_NOLEVEL = static_cast< size_t >( -1 );
44 : : const size_t SC_OL_HEADERENTRY = static_cast< size_t >( -1 );
45 : :
46 : : const sal_uInt16 SC_OL_IMAGE_PLUS = 9;
47 : : const sal_uInt16 SC_OL_IMAGE_MINUS = SC_OL_IMAGE_PLUS + 1;
48 : : const sal_uInt16 SC_OL_IMAGE_NOTPRESSED = SC_OL_IMAGE_MINUS + 1;
49 : : const sal_uInt16 SC_OL_IMAGE_PRESSED = SC_OL_IMAGE_NOTPRESSED + 1;
50 : :
51 : : // ============================================================================
52 : :
53 : 2 : ScOutlineWindow::ScOutlineWindow( Window* pParent, ScOutlineMode eMode, ScViewData* pViewData, ScSplitPos eWhich ) :
54 : : Window( pParent ),
55 : : mrViewData( *pViewData ),
56 : : meWhich( eWhich ),
57 : : mbHoriz( eMode == SC_OUTLINE_HOR ),
58 : : mbMirrorEntries( false ), // updated in SetHeaderSize
59 : : mbMirrorLevels( false ), // updated in SetHeaderSize
60 : : mpSymbols( NULL ),
61 : : maLineColor( COL_BLACK ),
62 : : mnHeaderSize( 0 ),
63 : : mnHeaderPos( 0 ),
64 : : mnMainFirstPos( 0 ),
65 : : mnMainLastPos( 0 ),
66 : : mbMTActive( false ),
67 : : mbMTPressed( false ),
68 : : mnFocusLevel( 0 ),
69 : : mnFocusEntry( SC_OL_HEADERENTRY ),
70 [ + - ]: 2 : mbDontDrawFocus( false )
71 : : {
72 [ + - ]: 2 : EnableRTL( false ); // mirroring is done manually
73 : :
74 [ + - ]: 2 : InitSettings();
75 : 2 : maFocusRect.SetEmpty();
76 [ + - ]: 2 : SetHeaderSize( 0 );
77 : :
78 : : // insert the window into task pane list for "F6 cycling"
79 [ + - ][ + - ]: 2 : if( SystemWindow* pSysWin = GetSystemWindow() )
80 [ + - ][ + - ]: 2 : if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
81 [ + - ]: 2 : pTaskPaneList->AddWindow( this );
82 : 2 : }
83 : :
84 : 2 : ScOutlineWindow::~ScOutlineWindow()
85 : : {
86 : : // remove the window from task pane list
87 [ + - ][ + - ]: 2 : if( SystemWindow* pSysWin = GetSystemWindow() )
88 [ + - ][ + - ]: 2 : if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
89 [ + - ]: 2 : pTaskPaneList->RemoveWindow( this );
90 [ - + ]: 4 : }
91 : :
92 : 8 : void ScOutlineWindow::SetHeaderSize( long nNewSize )
93 : : {
94 : 8 : sal_Bool bLayoutRTL = GetDoc().IsLayoutRTL( GetTab() );
95 [ # # ][ - + ]: 8 : mbMirrorEntries = bLayoutRTL && mbHoriz;
96 [ - + ][ # # ]: 8 : mbMirrorLevels = bLayoutRTL && !mbHoriz;
97 : :
98 : 8 : bool bNew = (nNewSize != mnHeaderSize);
99 : 8 : mnHeaderSize = nNewSize;
100 [ - + ]: 8 : mnHeaderPos = mbMirrorEntries ? (GetOutputSizeEntry() - mnHeaderSize) : 0;
101 [ - + ]: 8 : mnMainFirstPos = mbMirrorEntries ? 0 : mnHeaderSize;
102 [ - + ]: 8 : mnMainLastPos = GetOutputSizeEntry() - (mbMirrorEntries ? mnHeaderSize : 0) - 1;
103 [ + + ]: 8 : if ( bNew )
104 : 2 : Invalidate();
105 : 8 : }
106 : :
107 : 2 : long ScOutlineWindow::GetDepthSize() const
108 : : {
109 : 2 : long nSize = GetLevelCount() * SC_OL_BITMAPSIZE;
110 [ + - ]: 2 : if ( nSize > 0 )
111 : 2 : nSize += 2 * SC_OL_POSOFFSET + 1;
112 : 2 : return nSize;
113 : : }
114 : :
115 : 0 : void ScOutlineWindow::ScrollPixel( long nDiff )
116 : : {
117 : 0 : HideFocus();
118 : 0 : mbDontDrawFocus = true;
119 : :
120 : 0 : long nStart = mnMainFirstPos;
121 : 0 : long nEnd = mnMainLastPos;
122 : :
123 : : long nInvStart, nInvEnd;
124 [ # # ]: 0 : if (nDiff < 0)
125 : : {
126 : 0 : nStart -= nDiff;
127 : 0 : nInvStart = nEnd + nDiff;
128 : 0 : nInvEnd = nEnd;
129 : : }
130 : : else
131 : : {
132 : 0 : nEnd -= nDiff;
133 : 0 : nInvStart = nStart;
134 : 0 : nInvEnd = nStart + nDiff;
135 : : }
136 : :
137 : 0 : ScrollRel( nDiff, nStart, nEnd );
138 [ # # ]: 0 : Invalidate( GetRectangle( 0, nInvStart, GetOutputSizeLevel() - 1, nInvEnd ) );
139 : 0 : Update();
140 : :
141 : : // if focus becomes invisible, move it to next visible button
142 : 0 : ImplMoveFocusToVisible( nDiff < 0 );
143 : :
144 : 0 : mbDontDrawFocus = false;
145 : 0 : ShowFocus();
146 : 0 : }
147 : :
148 : 0 : void ScOutlineWindow::ScrollRel( long nEntryDiff, long nEntryStart, long nEntryEnd )
149 : : {
150 [ # # ]: 0 : Rectangle aRect( GetRectangle( 0, nEntryStart, GetOutputSizeLevel() - 1, nEntryEnd ) );
151 [ # # ]: 0 : if ( mbHoriz )
152 [ # # ]: 0 : Scroll( nEntryDiff, 0, aRect );
153 : : else
154 [ # # ]: 0 : Scroll( 0, nEntryDiff, aRect );
155 : 0 : }
156 : :
157 : : // internal -------------------------------------------------------------------
158 : :
159 : 2 : void ScOutlineWindow::InitSettings()
160 : : {
161 : 2 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
162 [ + - ]: 2 : SetBackground( rStyleSettings.GetFaceColor() );
163 : 2 : maLineColor = rStyleSettings.GetButtonTextColor();
164 : 2 : mpSymbols = ScGlobal::GetOutlineSymbols();
165 : 2 : Invalidate();
166 : 2 : }
167 : :
168 : 20 : const ScOutlineArray* ScOutlineWindow::GetOutlineArray() const
169 : : {
170 : 20 : const ScOutlineTable* pTable = GetDoc().GetOutlineTable( GetTab() );
171 [ - + ]: 20 : if ( !pTable ) return NULL;
172 [ - + ]: 20 : return mbHoriz ? pTable->GetColArray() : pTable->GetRowArray();
173 : : }
174 : :
175 : 12 : const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nEntry ) const
176 : : {
177 : 12 : const ScOutlineArray* pArray = GetOutlineArray();
178 [ + - ]: 12 : return pArray ? pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) ) : NULL;
179 : : }
180 : :
181 : 10 : bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const
182 : : {
183 : : return mbHoriz ?
184 : 0 : GetDoc().ColHidden(static_cast<SCCOL>(nColRowIndex), GetTab()) :
185 [ - + ]: 10 : GetDoc().RowHidden(static_cast<SCROW>(nColRowIndex), GetTab());
186 : : }
187 : :
188 : 10 : bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const
189 : : {
190 : : // columns cannot be filtered
191 [ + - ][ - + ]: 10 : return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
192 : : }
193 : :
194 : 0 : bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const
195 : : {
196 : 0 : bool bAllHidden = true;
197 [ # # ][ # # ]: 0 : for ( SCCOLROW nPos = 0; (nPos < nColRowIndex) && bAllHidden; ++nPos )
[ # # ]
198 : 0 : bAllHidden = IsHidden( nPos );
199 : 0 : return bAllHidden;
200 : : }
201 : :
202 : 2 : void ScOutlineWindow::GetVisibleRange( SCCOLROW& rnColRowStart, SCCOLROW& rnColRowEnd ) const
203 : : {
204 [ - + ]: 2 : if ( mbHoriz )
205 : : {
206 : 0 : rnColRowStart = mrViewData.GetPosX( WhichH( meWhich ) );
207 : 0 : rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsX( WhichH( meWhich ) );
208 : : }
209 : : else
210 : : {
211 : 2 : rnColRowStart = mrViewData.GetPosY( WhichV( meWhich ) );
212 : 2 : rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsY( WhichV( meWhich ) );
213 : : }
214 : :
215 : : // include collapsed columns/rows in front of visible range
216 [ - + ][ # # ]: 2 : while ( (rnColRowStart > 0) && IsHidden( rnColRowStart - 1 ) )
[ - + ]
217 : 0 : --rnColRowStart;
218 : 2 : }
219 : :
220 : 43 : Point ScOutlineWindow::GetPoint( long nLevelPos, long nEntryPos ) const
221 : : {
222 [ - + ]: 43 : return mbHoriz ? Point( nEntryPos, nLevelPos ) : Point( nLevelPos, nEntryPos );
223 : : }
224 : :
225 : 10 : Rectangle ScOutlineWindow::GetRectangle(
226 : : long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd ) const
227 : : {
228 [ + - ]: 10 : return Rectangle( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
229 : : }
230 : :
231 : 2 : long ScOutlineWindow::GetOutputSizeLevel() const
232 : : {
233 : 2 : Size aSize( GetOutputSizePixel() );
234 [ - + ]: 2 : return mbHoriz ? aSize.Height() : aSize.Width();
235 : : }
236 : :
237 : 8 : long ScOutlineWindow::GetOutputSizeEntry() const
238 : : {
239 : 8 : Size aSize( GetOutputSizePixel() );
240 [ - + ]: 8 : return mbHoriz ? aSize.Width() : aSize.Height();
241 : : }
242 : :
243 : 6 : size_t ScOutlineWindow::GetLevelCount() const
244 : : {
245 : 6 : const ScOutlineArray* pArray = GetOutlineArray();
246 [ + - ]: 6 : size_t nLevelCount = pArray ? pArray->GetDepth() : 0;
247 [ + - ]: 6 : return nLevelCount ? (nLevelCount + 1) : 0;
248 : : }
249 : :
250 : 10 : long ScOutlineWindow::GetLevelPos( size_t nLevel ) const
251 : : {
252 : : // #i51970# must always return the *left* edge of the area used by a level
253 : 10 : long nPos = static_cast< long >( SC_OL_POSOFFSET + nLevel * SC_OL_BITMAPSIZE );
254 [ - + ]: 10 : return mbMirrorLevels ? (GetOutputSizeLevel() - nPos - SC_OL_BITMAPSIZE) : nPos;
255 : : }
256 : :
257 : 0 : size_t ScOutlineWindow::GetLevelFromPos( long nLevelPos ) const
258 : : {
259 [ # # ]: 0 : if( mbMirrorLevels ) nLevelPos = GetOutputSizeLevel() - nLevelPos - 1;
260 : 0 : long nStart = SC_OL_POSOFFSET;
261 [ # # ]: 0 : if ( nLevelPos < nStart ) return SC_OL_NOLEVEL;
262 : 0 : size_t nLevel = static_cast< size_t >( (nLevelPos - nStart) / SC_OL_BITMAPSIZE );
263 [ # # ]: 0 : return (nLevel < GetLevelCount()) ? nLevel : SC_OL_NOLEVEL;
264 : : }
265 : :
266 : 20 : long ScOutlineWindow::GetColRowPos( SCCOLROW nColRowIndex ) const
267 : : {
268 : : long nDocPos = mbHoriz ?
269 [ # # ][ - + ]: 20 : mrViewData.GetScrPos( static_cast<SCCOL>(nColRowIndex), 0, meWhich, sal_True ).X() :
[ # # ]
270 [ - + ][ + - ]: 20 : mrViewData.GetScrPos( 0, static_cast<SCROW>(nColRowIndex), meWhich, sal_True ).Y();
[ + - ][ # # ]
271 : 20 : return mnMainFirstPos + nDocPos;
272 : : }
273 : :
274 : 2 : long ScOutlineWindow::GetHeaderEntryPos() const
275 : : {
276 : 2 : return mnHeaderPos + (mnHeaderSize - SC_OL_BITMAPSIZE) / 2;
277 : : }
278 : :
279 : 10 : bool ScOutlineWindow::GetEntryPos(
280 : : size_t nLevel, size_t nEntry,
281 : : long& rnStartPos, long& rnEndPos, long& rnImagePos ) const
282 : : {
283 : 10 : const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
284 [ - + ][ - + ]: 10 : if ( !pEntry || !pEntry->IsVisible() )
[ + - ]
285 : 0 : return false;
286 : :
287 : 10 : SCCOLROW nStart = pEntry->GetStart();
288 : 10 : SCCOLROW nEnd = pEntry->GetEnd();
289 : :
290 [ - + ]: 10 : long nEntriesSign = mbMirrorEntries ? -1 : 1;
291 : :
292 : : // --- common calculation ---
293 : :
294 : 10 : rnStartPos = GetColRowPos( nStart );
295 : 10 : rnEndPos = GetColRowPos( nEnd + 1 );
296 : :
297 : 10 : bool bHidden = IsHidden( nStart );
298 : : rnImagePos = bHidden ?
299 : : (rnStartPos - ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign) :
300 [ - + ]: 10 : rnStartPos + nEntriesSign;
301 : : long nCenter = (rnStartPos + rnEndPos - SC_OL_BITMAPSIZE * nEntriesSign +
302 [ - + ]: 10 : ( mbMirrorEntries ? 1 : 0 )) / 2L;
303 [ - + ]: 10 : rnImagePos = mbMirrorEntries ? Max( rnImagePos, nCenter ) : Min( rnImagePos, nCenter );
304 : :
305 : : // --- refinements ---
306 : :
307 : : // do not cut leftmost/topmost image
308 [ - + ][ # # ]: 10 : if ( bHidden && IsFirstVisible( nStart ) )
[ - + ]
309 : 0 : rnImagePos = rnStartPos;
310 : :
311 : : // do not cover previous collapsed image
312 [ + - ][ + + ]: 10 : if ( !bHidden && nEntry )
313 : : {
314 : 2 : const ScOutlineEntry* pPrevEntry = GetOutlineEntry( nLevel, nEntry - 1 );
315 : 2 : SCCOLROW nPrevEnd = pPrevEntry->GetEnd();
316 [ # # ][ - + ]: 2 : if ( (nPrevEnd + 1 == nStart) && IsHidden( nPrevEnd ) )
[ - + ]
317 : : {
318 [ # # ]: 0 : if ( IsFirstVisible( pPrevEntry->GetStart() ) )
319 : 0 : rnStartPos += SC_OL_BITMAPSIZE * nEntriesSign;
320 : : else
321 : 0 : rnStartPos += ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign;
322 : 0 : rnImagePos = rnStartPos;
323 : : }
324 : : }
325 : :
326 : : // restrict rnStartPos...rnEndPos to valid area
327 : 10 : rnStartPos = std::max( rnStartPos, mnMainFirstPos );
328 : 10 : rnEndPos = std::max( rnEndPos, mnMainFirstPos );
329 : :
330 [ - + ]: 10 : if ( mbMirrorEntries )
331 : 0 : rnImagePos -= SC_OL_BITMAPSIZE - 1; // start pos aligns with right edge of bitmap
332 : :
333 : : // --- all rows filtered? ---
334 : :
335 : 10 : bool bVisible = true;
336 [ + - ]: 10 : if ( !mbHoriz )
337 : : {
338 : 10 : bVisible = false;
339 [ + + ][ + + ]: 20 : for ( SCCOLROW nRow = nStart; (nRow <= nEnd) && !bVisible; ++nRow )
[ + + ]
340 : 10 : bVisible = !IsFiltered( nRow );
341 : : }
342 : 10 : return bVisible;
343 : : }
344 : :
345 : 0 : bool ScOutlineWindow::GetImagePos( size_t nLevel, size_t nEntry, Point& rPos ) const
346 : : {
347 : 0 : bool bRet = nLevel < GetLevelCount();
348 [ # # ]: 0 : if ( bRet )
349 : : {
350 : 0 : long nLevelPos = GetLevelPos( nLevel );
351 [ # # ]: 0 : if ( nEntry == SC_OL_HEADERENTRY )
352 : 0 : rPos = GetPoint( nLevelPos, GetHeaderEntryPos() );
353 : : else
354 : : {
355 : : long nStartPos, nEndPos, nImagePos;
356 [ # # ]: 0 : bRet = GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos );
357 : 0 : rPos = GetPoint( nLevelPos, nImagePos );
358 : : }
359 : : }
360 : 0 : return bRet;
361 : : }
362 : :
363 : 4 : bool ScOutlineWindow::IsButtonVisible( size_t nLevel, size_t nEntry ) const
364 : : {
365 : 4 : bool bRet = false;
366 [ + - ]: 4 : if ( nEntry == SC_OL_HEADERENTRY )
367 [ + + ][ + - ]: 4 : bRet = (mnHeaderSize > 0) && (nLevel < GetLevelCount());
368 : : else
369 : : {
370 : 0 : const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
371 [ # # ][ # # ]: 0 : if ( pEntry && pEntry->IsVisible() )
[ # # ]
372 : : {
373 : : SCCOLROW nStart, nEnd;
374 [ # # ]: 0 : GetVisibleRange( nStart, nEnd );
375 [ # # ][ # # ]: 0 : bRet = (nStart <= pEntry->GetStart()) && (pEntry->GetStart() <= nEnd);
[ # # ][ # # ]
376 : : }
377 : : }
378 : 4 : return bRet;
379 : : }
380 : :
381 : 0 : bool ScOutlineWindow::ItemHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry, bool& rbButton ) const
382 : : {
383 [ # # ]: 0 : const ScOutlineArray* pArray = GetOutlineArray();
384 [ # # ]: 0 : if ( !pArray ) return false;
385 : :
386 : : SCCOLROW nStartIndex, nEndIndex;
387 [ # # ]: 0 : GetVisibleRange( nStartIndex, nEndIndex );
388 : :
389 [ # # ][ # # ]: 0 : size_t nLevel = GetLevelFromPos( mbHoriz ? rPos.Y() : rPos.X() );
390 [ # # ]: 0 : if ( nLevel == SC_OL_NOLEVEL )
391 : 0 : return false;
392 : :
393 [ # # ]: 0 : long nEntryMousePos = mbHoriz ? rPos.X() : rPos.Y();
394 : :
395 : : // --- level buttons ---
396 : :
397 [ # # ]: 0 : if ( mnHeaderSize > 0 )
398 : : {
399 : 0 : long nImagePos = GetHeaderEntryPos();
400 [ # # ][ # # ]: 0 : if ( (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
401 : : {
402 : 0 : rnLevel = nLevel;
403 : 0 : rnEntry = SC_OL_HEADERENTRY;
404 : 0 : rbButton = true;
405 : 0 : return true;
406 : : }
407 : : }
408 : :
409 : : // --- expand/collapse buttons and expanded lines ---
410 : :
411 : : // search outline entries backwards
412 [ # # ]: 0 : size_t nEntry = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
413 [ # # ]: 0 : while ( nEntry )
414 : : {
415 : 0 : --nEntry;
416 : :
417 : 0 : const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
418 [ # # ]: 0 : sal::static_int_cast<sal_uInt16>(nEntry) );
419 [ # # ]: 0 : SCCOLROW nStart = pEntry->GetStart();
420 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
421 : :
422 [ # # ][ # # ]: 0 : if ( (nEnd >= nStartIndex) && (nStart <= nEndIndex) )
423 : : {
424 : : long nStartPos, nEndPos, nImagePos;
425 [ # # ][ # # ]: 0 : if ( GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos ) )
426 : : {
427 : 0 : rnLevel = nLevel;
428 : 0 : rnEntry = nEntry;
429 : :
430 : : // button?
431 [ # # ][ # # ]: 0 : if ( (nStart >= nStartIndex) && (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
[ # # ]
432 : : {
433 : 0 : rbButton = true;
434 : 0 : return true;
435 : : }
436 : :
437 : : // line?
438 [ # # ]: 0 : if ( mbMirrorEntries )
439 : 0 : ::std::swap( nStartPos, nEndPos ); // in RTL mode, nStartPos is the larger value
440 [ # # ][ # # ]: 0 : if ( (nStartPos <= nEntryMousePos) && (nEntryMousePos <= nEndPos) )
441 : : {
442 : 0 : rbButton = false;
443 : 0 : return true;
444 : : }
445 : : }
446 : : }
447 : : }
448 : :
449 : 0 : return false;
450 : : }
451 : :
452 : 0 : bool ScOutlineWindow::ButtonHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
453 : : {
454 : : bool bButton;
455 [ # # ]: 0 : bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
456 [ # # ][ # # ]: 0 : return bRet && bButton;
457 : : }
458 : :
459 : 0 : bool ScOutlineWindow::LineHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
460 : : {
461 : : bool bButton;
462 [ # # ]: 0 : bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
463 [ # # ][ # # ]: 0 : return bRet && !bButton;
464 : : }
465 : :
466 : 0 : void ScOutlineWindow::DoFunction( size_t nLevel, size_t nEntry ) const
467 : : {
468 : 0 : ScDBFunc& rFunc = *mrViewData.GetView();
469 [ # # ]: 0 : if ( nEntry == SC_OL_HEADERENTRY )
470 : 0 : rFunc.SelectLevel( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel) );
471 : : else
472 : : {
473 : 0 : const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
474 [ # # ]: 0 : if ( pEntry )
475 : : {
476 [ # # ]: 0 : if ( pEntry->IsHidden() )
477 : 0 : rFunc.ShowOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
478 : : else
479 : 0 : rFunc.HideOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
480 : : }
481 : : }
482 : 0 : }
483 : :
484 : 0 : void ScOutlineWindow::DoExpand( size_t nLevel, size_t nEntry ) const
485 : : {
486 : 0 : const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
487 [ # # ][ # # ]: 0 : if ( pEntry && pEntry->IsHidden() )
[ # # ]
488 : 0 : DoFunction( nLevel, nEntry );
489 : 0 : }
490 : :
491 : 0 : void ScOutlineWindow::DoCollapse( size_t nLevel, size_t nEntry ) const
492 : : {
493 : 0 : const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
494 [ # # ][ # # ]: 0 : if ( pEntry && !pEntry->IsHidden() )
[ # # ]
495 : 0 : DoFunction( nLevel, nEntry );
496 : 0 : }
497 : :
498 : 4 : void ScOutlineWindow::Resize()
499 : : {
500 : 4 : Window::Resize();
501 : 4 : SetHeaderSize( mnHeaderSize ); // recalculates header/group positions
502 [ + + ]: 4 : if ( !IsFocusButtonVisible() )
503 : : {
504 : 2 : HideFocus();
505 : 2 : ShowFocus(); // calculates valid position
506 : : }
507 : 4 : }
508 : :
509 : 0 : void ScOutlineWindow::DataChanged( const DataChangedEvent& rDCEvt )
510 : : {
511 [ # # # # ]: 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
[ # # ]
512 : 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
513 : : {
514 : 0 : InitSettings();
515 : 0 : Invalidate();
516 : : }
517 : 0 : Window::DataChanged( rDCEvt );
518 : 0 : }
519 : :
520 : : // drawing --------------------------------------------------------------------
521 : :
522 : 2 : void ScOutlineWindow::SetEntryAreaClipRegion()
523 : : {
524 : : SetClipRegion( Rectangle(
525 : 2 : GetPoint( 0, mnMainFirstPos ),
526 [ + - ][ + - ]: 2 : GetPoint( GetOutputSizeLevel() - 1, mnMainLastPos ) ) );
[ + - ][ + - ]
527 : 2 : }
528 : :
529 : 4 : void ScOutlineWindow::DrawLineRel(
530 : : long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
531 : : {
532 [ + - ]: 4 : DrawLine( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
533 : 4 : }
534 : :
535 : 10 : void ScOutlineWindow::DrawRectRel(
536 : : long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
537 : : {
538 [ + - ]: 10 : DrawRect( GetRectangle( nLevelStart, nEntryStart, nLevelEnd, nEntryEnd ) );
539 : 10 : }
540 : :
541 : 11 : void ScOutlineWindow::DrawImageRel( long nLevelPos, long nEntryPos, sal_uInt16 nId )
542 : : {
543 : : OSL_ENSURE( mpSymbols, "ScOutlineWindow::DrawImageRel - no images" );
544 [ + - ]: 11 : const Image& rImage = mpSymbols->GetImage( nId );
545 [ + - ]: 11 : SetLineColor();
546 [ + - ][ + - ]: 11 : SetFillColor( GetBackground().GetColor() );
547 : 11 : Point aPos( GetPoint( nLevelPos, nEntryPos ) );
548 [ + - ][ + - ]: 11 : DrawRect( Rectangle( aPos, rImage.GetSizePixel() ) );
[ + - ]
549 [ + - ][ + - ]: 11 : DrawImage( aPos, rImage );
550 : 11 : }
551 : :
552 : 0 : void ScOutlineWindow::DrawBorderRel( size_t nLevel, size_t nEntry, bool bPressed )
553 : : {
554 : 0 : Point aPos;
555 [ # # ][ # # ]: 0 : if ( GetImagePos( nLevel, nEntry, aPos ) )
556 : : {
557 : : OSL_ENSURE( mpSymbols, "ScOutlineWindow::DrawBorderRel - no images" );
558 [ # # ]: 0 : sal_uInt16 nId = bPressed ? SC_OL_IMAGE_PRESSED : SC_OL_IMAGE_NOTPRESSED;
559 : 0 : bool bClip = (nEntry != SC_OL_HEADERENTRY);
560 [ # # ]: 0 : if ( bClip )
561 [ # # ]: 0 : SetEntryAreaClipRegion();
562 [ # # ][ # # ]: 0 : DrawImage( aPos, mpSymbols->GetImage( nId ) );
[ # # ]
563 [ # # ]: 0 : if ( bClip )
564 [ # # ]: 0 : SetClipRegion();
565 : : }
566 : 0 : mbMTPressed = bPressed;
567 : 0 : }
568 : :
569 : 4 : void ScOutlineWindow::ShowFocus()
570 : : {
571 [ - + ]: 4 : if ( HasFocus() )
572 : : {
573 : : // first move to a visible position
574 : 0 : ImplMoveFocusToVisible( true );
575 : :
576 [ # # ]: 0 : if ( IsFocusButtonVisible() )
577 : : {
578 : 0 : Point aPos;
579 [ # # ][ # # ]: 0 : if ( GetImagePos( mnFocusLevel, mnFocusEntry, aPos ) )
580 : : {
581 : 0 : aPos += Point( 1, 1 );
582 [ # # ]: 0 : maFocusRect = Rectangle( aPos, Size( SC_OL_BITMAPSIZE - 2, SC_OL_BITMAPSIZE - 2 ) );
583 : 0 : bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
584 [ # # ]: 0 : if ( bClip )
585 [ # # ]: 0 : SetEntryAreaClipRegion();
586 [ # # ]: 0 : InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
587 [ # # ]: 0 : if ( bClip )
588 [ # # ]: 0 : SetClipRegion();
589 : : }
590 : : }
591 : : }
592 : 4 : }
593 : :
594 : 2 : void ScOutlineWindow::HideFocus()
595 : : {
596 [ - + ]: 2 : if ( !maFocusRect.IsEmpty() )
597 : : {
598 : 0 : bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
599 [ # # ]: 0 : if ( bClip )
600 : 0 : SetEntryAreaClipRegion();
601 : 0 : InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
602 [ # # ]: 0 : if ( bClip )
603 : 0 : SetClipRegion();
604 : 0 : maFocusRect.SetEmpty();
605 : : }
606 : 2 : }
607 : :
608 : 2 : void ScOutlineWindow::Paint( const Rectangle& /* rRect */ )
609 : : {
610 [ - + ]: 2 : long nEntriesSign = mbMirrorEntries ? -1 : 1;
611 [ - + ]: 2 : long nLevelsSign = mbMirrorLevels ? -1 : 1;
612 : :
613 : 2 : Size aSize = GetOutputSizePixel();
614 [ - + ]: 2 : long nLevelEnd = (mbHoriz ? aSize.Height() : aSize.Width()) - 1;
615 [ - + ]: 2 : long nEntryEnd = (mbHoriz ? aSize.Width() : aSize.Height()) - 1;
616 : :
617 [ + - ]: 2 : SetLineColor( maLineColor );
618 [ - + ]: 2 : long nBorderPos = mbMirrorLevels ? 0 : nLevelEnd;
619 [ + - ]: 2 : DrawLineRel( nBorderPos, 0, nBorderPos, nEntryEnd );
620 : :
621 [ + - ]: 2 : const ScOutlineArray* pArray = GetOutlineArray();
622 [ + - ]: 4 : if ( !pArray ) return;
623 : :
624 [ + - ]: 2 : size_t nLevelCount = GetLevelCount();
625 : :
626 : : // --- draw header images ---
627 : :
628 [ + - ]: 2 : if ( mnHeaderSize > 0 )
629 : : {
630 : 2 : long nEntryPos = GetHeaderEntryPos();
631 [ + + ]: 8 : for ( size_t nLevel = 0; nLevel < nLevelCount; ++nLevel )
632 [ + - ]: 6 : DrawImageRel( GetLevelPos( nLevel ), nEntryPos, static_cast< sal_uInt16 >( nLevel + 1 ) );
633 : :
634 [ + - ]: 2 : SetLineColor( maLineColor );
635 [ - + ]: 2 : long nLinePos = mnHeaderPos + (mbMirrorEntries ? 0 : (mnHeaderSize - 1));
636 [ + - ]: 2 : DrawLineRel( 0, nLinePos, nLevelEnd, nLinePos );
637 : : }
638 : :
639 : : // --- draw lines & collapse/expand images ---
640 : :
641 [ + - ]: 2 : SetEntryAreaClipRegion();
642 : :
643 : : SCCOLROW nStartIndex, nEndIndex;
644 [ + - ]: 2 : GetVisibleRange( nStartIndex, nEndIndex );
645 : :
646 [ + + ]: 6 : for ( size_t nLevel = 0; nLevel + 1 < nLevelCount; ++nLevel )
647 : : {
648 : 4 : long nLevelPos = GetLevelPos( nLevel );
649 : 4 : long nEntryPos1 = 0, nEntryPos2 = 0, nImagePos = 0;
650 : :
651 [ + - ]: 4 : size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
652 : : size_t nEntry;
653 : :
654 : : // first draw all lines in the current level
655 [ + - ]: 4 : SetLineColor();
656 [ + - ]: 4 : SetFillColor( maLineColor );
657 [ + + ]: 9 : for ( nEntry = 0; nEntry < nEntryCount; ++nEntry )
658 : : {
659 : 5 : const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
660 [ + - ]: 10 : sal::static_int_cast<sal_uInt16>(nEntry) );
661 [ + - ]: 5 : SCCOLROW nStart = pEntry->GetStart();
662 [ + - ]: 5 : SCCOLROW nEnd = pEntry->GetEnd();
663 : :
664 : : // visible range?
665 [ + - ][ + - ]: 5 : bool bDraw = (nEnd >= nStartIndex) && (nStart <= nEndIndex);
666 : : // find output coordinates
667 [ + - ]: 5 : if ( bDraw )
668 [ + - ]: 5 : bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
669 : : // draw, if not collapsed
670 [ + - ][ + - ]: 5 : if ( bDraw && !pEntry->IsHidden() )
[ + - ][ + - ]
671 : : {
672 [ + - ]: 5 : if ( nStart >= nStartIndex )
673 : 5 : nEntryPos1 += nEntriesSign;
674 : 5 : nEntryPos2 -= 2 * nEntriesSign;
675 : 5 : long nLinePos = nLevelPos;
676 [ - + ]: 5 : if ( mbMirrorLevels )
677 : 0 : nLinePos += SC_OL_BITMAPSIZE - 1; // align with right edge of bitmap
678 [ + - ]: 5 : DrawRectRel( nLinePos, nEntryPos1, nLinePos + nLevelsSign, nEntryPos2 );
679 : :
680 [ + - ]: 5 : if ( nEnd <= nEndIndex )
681 : : DrawRectRel( nLinePos, nEntryPos2 - nEntriesSign,
682 [ + - ]: 5 : nLinePos + ( SC_OL_BITMAPSIZE / 3 ) * nLevelsSign, nEntryPos2 );
683 : : }
684 : : }
685 : :
686 : : // draw all images in the level from last to first
687 : 4 : nEntry = nEntryCount;
688 [ + + ]: 9 : while ( nEntry )
689 : : {
690 : 5 : --nEntry;
691 : :
692 : 5 : const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
693 [ + - ]: 10 : sal::static_int_cast<sal_uInt16>(nEntry) );
694 [ + - ]: 5 : SCCOLROW nStart = pEntry->GetStart();
695 : :
696 : : // visible range?
697 [ + - ][ + - ]: 5 : bool bDraw = (nStartIndex <= nStart) && (nStart <= nEndIndex + 1);
698 : : // find output coordinates
699 [ + - ]: 5 : if ( bDraw )
700 [ + - ]: 5 : bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
701 : : // draw, if not hidden by higher levels
702 [ + - ]: 5 : if ( bDraw )
703 : : {
704 [ + - ][ - + ]: 5 : sal_uInt16 nImageId = pEntry->IsHidden() ? SC_OL_IMAGE_PLUS : SC_OL_IMAGE_MINUS;
705 [ + - ]: 5 : DrawImageRel( nLevelPos, nImagePos, nImageId );
706 : : }
707 : : }
708 : : }
709 : :
710 [ + - ]: 2 : SetClipRegion();
711 : :
712 [ + - ]: 2 : if ( !mbDontDrawFocus )
713 [ + - ]: 2 : ShowFocus();
714 : : }
715 : :
716 : : // focus ----------------------------------------------------------------------
717 : :
718 : : /** Increments or decrements a value and wraps at the specified limits.
719 : : @return true = value wrapped. */
720 : 0 : bool lcl_RotateValue( size_t& rnValue, size_t nMin, size_t nMax, bool bForward )
721 : : {
722 : : OSL_ENSURE( nMin <= nMax, "lcl_RotateValue - invalid range" );
723 : : OSL_ENSURE( nMax < static_cast< size_t >( -1 ), "lcl_RotateValue - range overflow" );
724 : 0 : bool bWrap = false;
725 [ # # ]: 0 : if ( bForward )
726 : : {
727 [ # # ]: 0 : if ( rnValue < nMax )
728 : 0 : ++rnValue;
729 : : else
730 : : {
731 : 0 : rnValue = nMin;
732 : 0 : bWrap = true;
733 : : }
734 : : }
735 : : else
736 : : {
737 [ # # ]: 0 : if ( rnValue > nMin )
738 : 0 : --rnValue;
739 : : else
740 : : {
741 : 0 : rnValue = nMax;
742 : 0 : bWrap = true;
743 : : }
744 : : }
745 : 0 : return bWrap;
746 : : }
747 : :
748 : 4 : bool ScOutlineWindow::IsFocusButtonVisible() const
749 : : {
750 : 4 : return IsButtonVisible( mnFocusLevel, mnFocusEntry );
751 : : }
752 : :
753 : 0 : bool ScOutlineWindow::ImplMoveFocusByEntry( bool bForward, bool bFindVisible )
754 : : {
755 : 0 : const ScOutlineArray* pArray = GetOutlineArray();
756 [ # # ]: 0 : if ( !pArray )
757 : 0 : return false;
758 : :
759 : 0 : bool bWrapped = false;
760 : 0 : size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(mnFocusLevel) );
761 : : // #i29530# entry count may be decreased after changing active sheet
762 [ # # ]: 0 : if( mnFocusEntry >= nEntryCount )
763 : 0 : mnFocusEntry = SC_OL_HEADERENTRY;
764 : 0 : size_t nOldEntry = mnFocusEntry;
765 : :
766 [ # # # # ]: 0 : do
[ # # ][ # # ]
767 : : {
768 [ # # ]: 0 : if ( mnFocusEntry == SC_OL_HEADERENTRY )
769 : : {
770 : : // move from header to first or last entry
771 [ # # ]: 0 : if ( nEntryCount > 0 )
772 [ # # ]: 0 : mnFocusEntry = bForward ? 0 : (nEntryCount - 1);
773 : : /* wrapped, if forward from right header to first entry,
774 : : or if backward from left header to last entry */
775 : : // Header and entries are now always in consistent order,
776 : : // so there's no need to check for mirroring here.
777 [ # # ][ # # ]: 0 : if ( !nEntryCount || !bForward )
778 : 0 : bWrapped = true;
779 : : }
780 [ # # ]: 0 : else if ( lcl_RotateValue( mnFocusEntry, 0, nEntryCount - 1, bForward ) )
781 : : {
782 : : // lcl_RotateValue returns true -> wrapped the entry range -> move to header
783 : 0 : mnFocusEntry = SC_OL_HEADERENTRY;
784 : : /* wrapped, if forward from last entry to left header,
785 : : or if backward from first entry to right header */
786 [ # # ]: 0 : if ( bForward )
787 : 0 : bWrapped = true;
788 : : }
789 : : }
790 : 0 : while ( bFindVisible && !IsFocusButtonVisible() && (nOldEntry != mnFocusEntry) );
791 : :
792 : 0 : return bWrapped;
793 : : }
794 : :
795 : 0 : bool ScOutlineWindow::ImplMoveFocusByLevel( bool bForward )
796 : : {
797 : 0 : const ScOutlineArray* pArray = GetOutlineArray();
798 [ # # ]: 0 : if ( !pArray )
799 : 0 : return false;
800 : :
801 : 0 : bool bWrapped = false;
802 : 0 : size_t nLevelCount = GetLevelCount();
803 : :
804 [ # # ]: 0 : if ( mnFocusEntry == SC_OL_HEADERENTRY )
805 : : {
806 [ # # ]: 0 : if ( nLevelCount > 0 )
807 : 0 : bWrapped = lcl_RotateValue( mnFocusLevel, 0, nLevelCount - 1, bForward );
808 : : }
809 : : else
810 : : {
811 : : const ScOutlineEntry* pEntry = pArray->GetEntry(
812 : 0 : mnFocusLevel, mnFocusEntry);
813 : :
814 [ # # ]: 0 : if ( pEntry )
815 : : {
816 [ # # ]: 0 : SCCOLROW nStart = pEntry->GetStart();
817 [ # # ]: 0 : SCCOLROW nEnd = pEntry->GetEnd();
818 : 0 : size_t nNewLevel = mnFocusLevel;
819 : 0 : size_t nNewEntry = 0;
820 : :
821 : 0 : bool bFound = false;
822 [ # # ][ # # ]: 0 : if ( bForward && (mnFocusLevel + 2 < nLevelCount) )
823 : : {
824 : : // next level -> find first child entry
825 : 0 : nNewLevel = mnFocusLevel + 1;
826 [ # # ]: 0 : bFound = pArray->GetEntryIndexInRange(nNewLevel, nStart, nEnd, nNewEntry);
827 : : }
828 [ # # ][ # # ]: 0 : else if ( !bForward && (mnFocusLevel > 0) )
829 : : {
830 : : // previous level -> find parent entry
831 : 0 : nNewLevel = mnFocusLevel - 1;
832 [ # # ]: 0 : bFound = pArray->GetEntryIndex(nNewLevel, nStart, nNewEntry);
833 : : }
834 : :
835 [ # # ][ # # ]: 0 : if ( bFound && IsButtonVisible( nNewLevel, nNewEntry ) )
[ # # ][ # # ]
836 : : {
837 : 0 : mnFocusLevel = nNewLevel;
838 : 0 : mnFocusEntry = nNewEntry;
839 : : }
840 : : }
841 : : }
842 : :
843 : 0 : return bWrapped;
844 : : }
845 : :
846 : 0 : bool ScOutlineWindow::ImplMoveFocusByTabOrder( bool bForward, bool bFindVisible )
847 : : {
848 : 0 : bool bRet = false;
849 : 0 : size_t nOldLevel = mnFocusLevel;
850 : 0 : size_t nOldEntry = mnFocusEntry;
851 : :
852 [ # # # # ]: 0 : do
[ # # ][ # # ]
[ # # ]
853 : : {
854 : : /* one level up, if backward from left header,
855 : : or one level down, if forward from right header */
856 [ # # ][ # # ]: 0 : if ( (!bForward) && (mnFocusEntry == SC_OL_HEADERENTRY) )
857 : 0 : bRet |= ImplMoveFocusByLevel( bForward );
858 : : // move to next/previous entry
859 : 0 : bool bWrapInLevel = ImplMoveFocusByEntry( bForward, false );
860 : 0 : bRet |= bWrapInLevel;
861 : : /* one level up, if wrapped backward to right header,
862 : : or one level down, if wrapped forward to right header */
863 [ # # ][ # # ]: 0 : if ( bForward && bWrapInLevel )
864 : 0 : bRet |= ImplMoveFocusByLevel( bForward );
865 : : }
866 : 0 : while ( bFindVisible && !IsFocusButtonVisible() && ((nOldLevel != mnFocusLevel) || (nOldEntry != mnFocusEntry)) );
867 : :
868 : 0 : return bRet;
869 : : }
870 : :
871 : 0 : void ScOutlineWindow::ImplMoveFocusToVisible( bool bForward )
872 : : {
873 : : // first try to find an entry in the same level
874 [ # # ]: 0 : if ( !IsFocusButtonVisible() )
875 : 0 : ImplMoveFocusByEntry( bForward, true );
876 : : // then try to find any other entry
877 [ # # ]: 0 : if ( !IsFocusButtonVisible() )
878 : 0 : ImplMoveFocusByTabOrder( bForward, true );
879 : 0 : }
880 : :
881 : 0 : void ScOutlineWindow::MoveFocusByEntry( bool bForward )
882 : : {
883 : 0 : HideFocus();
884 : 0 : ImplMoveFocusByEntry( bForward, true );
885 : 0 : ShowFocus();
886 : 0 : }
887 : :
888 : 0 : void ScOutlineWindow::MoveFocusByLevel( bool bForward )
889 : : {
890 : 0 : HideFocus();
891 : 0 : ImplMoveFocusByLevel( bForward );
892 : 0 : ShowFocus();
893 : 0 : }
894 : :
895 : 0 : void ScOutlineWindow::MoveFocusByTabOrder( bool bForward )
896 : : {
897 : 0 : HideFocus();
898 : 0 : ImplMoveFocusByTabOrder( bForward, true );
899 : 0 : ShowFocus();
900 : 0 : }
901 : :
902 : 0 : void ScOutlineWindow::GetFocus()
903 : : {
904 : 0 : Window::GetFocus();
905 : 0 : ShowFocus();
906 : 0 : }
907 : :
908 : 0 : void ScOutlineWindow::LoseFocus()
909 : : {
910 : 0 : HideFocus();
911 : 0 : Window::LoseFocus();
912 : 0 : }
913 : :
914 : :
915 : : // mouse ----------------------------------------------------------------------
916 : :
917 : 0 : void ScOutlineWindow::StartMouseTracking( size_t nLevel, size_t nEntry )
918 : : {
919 : 0 : mbMTActive = true;
920 : 0 : mnMTLevel = nLevel;
921 : 0 : mnMTEntry = nEntry;
922 : 0 : DrawBorderRel( nLevel, nEntry, true );
923 : 0 : }
924 : :
925 : 0 : void ScOutlineWindow::EndMouseTracking()
926 : : {
927 [ # # ]: 0 : if ( mbMTPressed )
928 : 0 : DrawBorderRel( mnMTLevel, mnMTEntry, false );
929 : 0 : mbMTActive = false;
930 : 0 : }
931 : :
932 : 0 : void ScOutlineWindow::MouseMove( const MouseEvent& rMEvt )
933 : : {
934 [ # # ]: 0 : if ( IsMouseTracking() )
935 : : {
936 : : size_t nLevel, nEntry;
937 : 0 : bool bHit = false;
938 : :
939 [ # # ][ # # ]: 0 : if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
940 [ # # ][ # # ]: 0 : bHit = (nLevel == mnMTLevel) && (nEntry == mnMTEntry);
941 : :
942 [ # # ]: 0 : if ( bHit != mbMTPressed )
943 [ # # ]: 0 : DrawBorderRel( mnMTLevel, mnMTEntry, bHit );
944 : : }
945 : 0 : }
946 : :
947 : 0 : void ScOutlineWindow::MouseButtonUp( const MouseEvent& rMEvt )
948 : : {
949 [ # # ]: 0 : if ( IsMouseTracking() )
950 : : {
951 [ # # ]: 0 : EndMouseTracking();
952 : :
953 : : size_t nLevel, nEntry;
954 [ # # ][ # # ]: 0 : if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
955 [ # # ][ # # ]: 0 : if ( (nLevel == mnMTLevel) && (nEntry == mnMTEntry) )
956 [ # # ]: 0 : DoFunction( nLevel, nEntry );
957 : : }
958 : 0 : }
959 : :
960 : 0 : void ScOutlineWindow::MouseButtonDown( const MouseEvent& rMEvt )
961 : : {
962 : : size_t nLevel, nEntry;
963 [ # # ]: 0 : bool bHit = ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry );
964 [ # # ]: 0 : if ( bHit )
965 [ # # ]: 0 : StartMouseTracking( nLevel, nEntry );
966 [ # # ]: 0 : else if ( rMEvt.GetClicks() == 2 )
967 : : {
968 [ # # ]: 0 : bHit = LineHit( rMEvt.GetPosPixel(), nLevel, nEntry );
969 [ # # ]: 0 : if ( bHit )
970 [ # # ]: 0 : DoFunction( nLevel, nEntry );
971 : : }
972 : :
973 : : // if an item has been hit and window is focused, move focus to this item
974 [ # # ][ # # ]: 0 : if ( bHit && HasFocus() )
[ # # ][ # # ]
975 : : {
976 [ # # ]: 0 : HideFocus();
977 : 0 : mnFocusLevel = nLevel;
978 : 0 : mnFocusEntry = nEntry;
979 [ # # ]: 0 : ShowFocus();
980 : : }
981 : 0 : }
982 : :
983 : :
984 : : // keyboard -------------------------------------------------------------------
985 : :
986 : 0 : void ScOutlineWindow::KeyInput( const KeyEvent& rKEvt )
987 : : {
988 : 0 : const KeyCode& rKCode = rKEvt.GetKeyCode();
989 : 0 : bool bNoMod = !rKCode.GetModifier();
990 : 0 : bool bShift = (rKCode.GetModifier() == KEY_SHIFT);
991 : 0 : bool bCtrl = (rKCode.GetModifier() == KEY_MOD1);
992 : :
993 : 0 : sal_uInt16 nCode = rKCode.GetCode();
994 [ # # ][ # # ]: 0 : bool bUpDownKey = (nCode == KEY_UP) || (nCode == KEY_DOWN);
995 [ # # ][ # # ]: 0 : bool bLeftRightKey = (nCode == KEY_LEFT) || (nCode == KEY_RIGHT);
996 : :
997 : : // TAB key
998 [ # # ][ # # ]: 0 : if ( (nCode == KEY_TAB) && (bNoMod || bShift) )
[ # # ]
999 : : // move forward without SHIFT key
1000 : 0 : MoveFocusByTabOrder( bNoMod ); // TAB uses logical order, regardless of mirroring
1001 : :
1002 : : // LEFT/RIGHT/UP/DOWN keys
1003 [ # # ][ # # ]: 0 : else if ( bNoMod && (bUpDownKey || bLeftRightKey) )
[ # # ]
1004 : : {
1005 [ # # ][ # # ]: 0 : bool bForward = (nCode == KEY_DOWN) || (nCode == KEY_RIGHT);
1006 [ # # ]: 0 : if ( mbHoriz == bLeftRightKey )
1007 : : // move inside level with LEFT/RIGHT in horizontal and with UP/DOWN in vertical
1008 : 0 : MoveFocusByEntry( bForward != mbMirrorEntries );
1009 : : else
1010 : : // move to next/prev level with LEFT/RIGHT in vertical and with UP/DOWN in horizontal
1011 : 0 : MoveFocusByLevel( bForward != mbMirrorLevels );
1012 : : }
1013 : :
1014 : : // CTRL + number
1015 [ # # ][ # # ]: 0 : else if ( bCtrl && (nCode >= KEY_1) && (nCode <= KEY_9) )
[ # # ]
1016 : : {
1017 : 0 : size_t nLevel = static_cast< size_t >( nCode - KEY_1 );
1018 [ # # ]: 0 : if ( nLevel < GetLevelCount() )
1019 : 0 : DoFunction( nLevel, SC_OL_HEADERENTRY );
1020 : : }
1021 : :
1022 : : // other key codes
1023 [ # # # # ]: 0 : else switch ( rKCode.GetFullCode() )
1024 : : {
1025 : 0 : case KEY_ADD: DoExpand( mnFocusLevel, mnFocusEntry ); break;
1026 : 0 : case KEY_SUBTRACT: DoCollapse( mnFocusLevel, mnFocusEntry ); break;
1027 : : case KEY_SPACE:
1028 : 0 : case KEY_RETURN: DoFunction( mnFocusLevel, mnFocusEntry ); break;
1029 : 0 : default: Window::KeyInput( rKEvt );
1030 : : }
1031 : 0 : }
1032 : :
1033 : :
1034 : : // ============================================================================
1035 : :
1036 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|