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 : * This file incorporates work covered by the following license notice:
28 : *
29 : * Licensed to the Apache Software Foundation (ASF) under one or more
30 : * contributor license agreements. See the NOTICE file distributed
31 : * with this work for additional information regarding copyright
32 : * ownership. The ASF licenses this file to you under the Apache
33 : * License, Version 2.0 (the "License"); you may not use this file
34 : * except in compliance with the License. You may obtain a copy of
35 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
36 : ************************************************************************/
37 :
38 : #include "fieldwnd.hxx"
39 :
40 : #include <comphelper/string.hxx>
41 : #include <vcl/decoview.hxx>
42 : #include <vcl/help.hxx>
43 : #include <vcl/svapp.hxx>
44 : #include <vcl/virdev.hxx>
45 : #include <vcl/mnemonic.hxx>
46 :
47 : #include "pvlaydlg.hxx"
48 : #include "dpuiglobal.hxx"
49 : #include "AccessibleDataPilotControl.hxx"
50 : #include "scresid.hxx"
51 : #include "pivot.hrc"
52 :
53 : using namespace com::sun::star;
54 : using ::rtl::OUString;
55 : using ::std::vector;
56 : using ::com::sun::star::uno::Reference;
57 : using ::com::sun::star::uno::WeakReference;
58 : using ::com::sun::star::accessibility::XAccessible;
59 :
60 : const size_t PIVOTFIELD_INVALID = static_cast< size_t >(-1);
61 : const size_t INVALID_INDEX = static_cast<size_t>(-1);
62 :
63 0 : ScDPFieldControlBase::FieldName::FieldName(const rtl::OUString& rText, bool bFits, sal_uInt8 nDupCount) :
64 0 : maText(rText), mbFits(bFits), mnDupCount(nDupCount) {}
65 :
66 0 : ScDPFieldControlBase::FieldName::FieldName(const FieldName& r) :
67 0 : maText(r.maText), mbFits(r.mbFits), mnDupCount(r.mnDupCount) {}
68 :
69 0 : rtl::OUString ScDPFieldControlBase::FieldName::getDisplayedText() const
70 : {
71 0 : rtl::OUStringBuffer aBuf(maText);
72 0 : if (mnDupCount > 0)
73 0 : aBuf.append(static_cast<sal_Int32>(mnDupCount+1));
74 0 : return aBuf.makeStringAndClear();
75 : }
76 :
77 0 : ScDPFieldControlBase::ScrollBar::ScrollBar(Window* pParent, WinBits nStyle) :
78 : ::ScrollBar(pParent, nStyle),
79 0 : mpParent(pParent)
80 : {
81 0 : }
82 :
83 0 : void ScDPFieldControlBase::ScrollBar::Command( const CommandEvent& rCEvt )
84 : {
85 0 : mpParent->Command(rCEvt);
86 0 : }
87 :
88 0 : ScDPFieldControlBase::AccessRef::AccessRef( const com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > & rAccessible ) : mxRef( rAccessible ) {}
89 :
90 : // easy, safe access to the backing accessible for the lifetime of AccessRef
91 0 : ScAccessibleDataPilotControl *ScDPFieldControlBase::AccessRef::operator -> () const
92 : {
93 0 : if (!mxRef.is())
94 0 : return NULL;
95 0 : return static_cast< ScAccessibleDataPilotControl * >( mxRef.get() );
96 : }
97 :
98 0 : ScDPFieldControlBase::ScDPFieldControlBase(
99 : ScPivotLayoutDlg* pParent, const ResId& rResId, FixedText* pCaption, const char* pcHelpId) :
100 : Control(pParent, rResId),
101 : mpDlg(pParent),
102 : mpCaption(pCaption),
103 0 : mnFieldSelected(0)
104 : {
105 0 : SetHelpId( pcHelpId );
106 :
107 0 : if (pCaption)
108 0 : maName = MnemonicGenerator::EraseAllMnemonicChars( pCaption->GetText() );
109 0 : }
110 :
111 0 : ScDPFieldControlBase::~ScDPFieldControlBase()
112 : {
113 0 : AccessRef aRef( mxAccessible );
114 0 : if( aRef.is() )
115 0 : aRef->dispose();
116 0 : }
117 :
118 0 : OUString ScDPFieldControlBase::GetName() const
119 : {
120 0 : return maName;
121 : }
122 :
123 0 : void ScDPFieldControlBase::SetName(const OUString& rName)
124 : {
125 0 : maName = rName;
126 0 : }
127 :
128 0 : bool ScDPFieldControlBase::IsExistingIndex( size_t nIndex ) const
129 : {
130 0 : return nIndex < maFieldNames.size();
131 : }
132 :
133 0 : void ScDPFieldControlBase::AddField( const rtl::OUString& rText, size_t nNewIndex )
134 : {
135 : OSL_ENSURE( nNewIndex == maFieldNames.size(), "ScDPFieldWindow::AddField - invalid index" );
136 0 : if( IsValidIndex( nNewIndex ) )
137 : {
138 0 : sal_uInt8 nDupCount = GetNextDupCount(rText);
139 0 : maFieldNames.push_back(FieldName(rText, true, nDupCount));
140 0 : AccessRef xRef(mxAccessible);
141 0 : if ( xRef.is() )
142 0 : xRef->AddField(nNewIndex);
143 : }
144 0 : }
145 :
146 0 : bool ScDPFieldControlBase::AddField(
147 : const rtl::OUString& rText, const Point& rPos, size_t& rnIndex, sal_uInt8& rnDupCount)
148 : {
149 0 : size_t nNewIndex = GetFieldIndex(rPos);
150 0 : if (nNewIndex != PIVOTFIELD_INVALID)
151 : {
152 0 : if( nNewIndex > maFieldNames.size() )
153 0 : nNewIndex = maFieldNames.size();
154 :
155 0 : sal_uInt8 nDupCount = GetNextDupCount(rText);
156 0 : maFieldNames.insert(maFieldNames.begin() + nNewIndex, FieldName(rText, true, nDupCount));
157 0 : mnFieldSelected = nNewIndex;
158 0 : ResetScrollBar();
159 0 : Invalidate();
160 0 : rnIndex = nNewIndex;
161 0 : rnDupCount = nDupCount;
162 :
163 0 : AccessRef xRef( mxAccessible );
164 0 : if ( xRef.is() )
165 0 : xRef->AddField(nNewIndex);
166 :
167 0 : return true;
168 : }
169 :
170 0 : return false;
171 : }
172 :
173 0 : bool ScDPFieldControlBase::MoveField(size_t nCurPos, const Point& rPos, size_t& rnIndex)
174 : {
175 0 : if (nCurPos >= maFieldNames.size())
176 : // out-of-bound
177 0 : return false;
178 :
179 0 : size_t nNewIndex = GetFieldIndex(rPos);
180 0 : if (nNewIndex == PIVOTFIELD_INVALID)
181 0 : return false;
182 :
183 0 : if (nNewIndex == nCurPos)
184 : // Nothing to do.
185 0 : return true;
186 :
187 0 : FieldName aName = maFieldNames[nCurPos];
188 0 : if (nNewIndex >= maFieldNames.size())
189 : {
190 : // Move to the back.
191 0 : maFieldNames.erase(maFieldNames.begin()+nCurPos);
192 0 : maFieldNames.push_back(aName);
193 0 : rnIndex = maFieldNames.size()-1;
194 : }
195 : else
196 : {
197 0 : maFieldNames.erase(maFieldNames.begin()+nCurPos);
198 0 : size_t nTmp = nNewIndex; // we need to keep the original index for accessible.
199 0 : if (nNewIndex > nCurPos)
200 0 : --nTmp;
201 :
202 0 : maFieldNames.insert(maFieldNames.begin()+nTmp, aName);
203 0 : rnIndex = nTmp;
204 : }
205 :
206 0 : ResetScrollBar();
207 0 : Invalidate();
208 :
209 0 : AccessRef xRef( mxAccessible );
210 0 : if ( xRef.is() )
211 0 : xRef->MoveField(nCurPos, nNewIndex);
212 :
213 0 : return true;
214 : }
215 :
216 0 : bool ScDPFieldControlBase::AppendField(const rtl::OUString& rText, size_t& rnIndex)
217 : {
218 0 : if (!IsValidIndex(maFieldNames.size()))
219 0 : return false;
220 :
221 0 : sal_uInt8 nDupCount = GetNextDupCount(rText);
222 0 : maFieldNames.push_back(FieldName(rText, true, nDupCount));
223 0 : mnFieldSelected = maFieldNames.size() - 1;
224 0 : ResetScrollBar();
225 0 : Invalidate();
226 :
227 0 : rnIndex = mnFieldSelected;
228 0 : return true;
229 : }
230 :
231 0 : void ScDPFieldControlBase::DelField( size_t nDelIndex )
232 : {
233 0 : if ( IsExistingIndex(nDelIndex) )
234 : {
235 : {
236 0 : AccessRef xRef( mxAccessible );
237 0 : if ( xRef.is() )
238 0 : xRef->RemoveField(nDelIndex);
239 : }
240 :
241 0 : maFieldNames.erase( maFieldNames.begin() + nDelIndex );
242 0 : if (mnFieldSelected >= maFieldNames.size())
243 0 : mnFieldSelected = maFieldNames.size() - 1;
244 :
245 0 : ResetScrollBar();
246 0 : Invalidate();
247 : }
248 0 : }
249 :
250 0 : size_t ScDPFieldControlBase::GetFieldCount() const
251 : {
252 0 : return maFieldNames.size();
253 : }
254 :
255 0 : bool ScDPFieldControlBase::IsEmpty() const
256 : {
257 0 : return maFieldNames.empty();
258 : }
259 :
260 0 : void ScDPFieldControlBase::ClearFields()
261 : {
262 0 : AccessRef xRef( mxAccessible );
263 0 : if ( xRef.is() )
264 0 : for( size_t nIdx = maFieldNames.size(); nIdx > 0; --nIdx )
265 0 : xRef->RemoveField( nIdx - 1 );
266 :
267 0 : maFieldNames.clear();
268 0 : }
269 :
270 0 : void ScDPFieldControlBase::SetFieldText(const rtl::OUString& rText, size_t nIndex, sal_uInt8 nDupCount)
271 : {
272 0 : if( IsExistingIndex( nIndex ) )
273 : {
274 0 : maFieldNames[nIndex] = FieldName(rText, true, nDupCount);
275 0 : Invalidate();
276 :
277 0 : AccessRef xRef( mxAccessible );
278 0 : if ( xRef.is() )
279 0 : xRef->FieldNameChange(nIndex);
280 : }
281 0 : }
282 :
283 0 : rtl::OUString ScDPFieldControlBase::GetFieldText( size_t nIndex ) const
284 : {
285 0 : if( IsExistingIndex( nIndex ) )
286 0 : return maFieldNames[nIndex].maText;
287 0 : return rtl::OUString();
288 : }
289 :
290 0 : void ScDPFieldControlBase::GetExistingIndex( const Point& rPos, size_t& rnIndex )
291 : {
292 0 : if (maFieldNames.empty() || GetFieldType() == PIVOTFIELDTYPE_SELECT)
293 : {
294 0 : rnIndex = 0;
295 0 : return;
296 : }
297 :
298 0 : rnIndex = GetFieldIndex(rPos);
299 0 : if (rnIndex == PIVOTFIELD_INVALID)
300 0 : rnIndex = 0;
301 : }
302 :
303 0 : size_t ScDPFieldControlBase::GetSelectedField() const
304 : {
305 0 : return mnFieldSelected;
306 : }
307 :
308 0 : vector<ScDPFieldControlBase::FieldName>& ScDPFieldControlBase::GetFieldNames()
309 : {
310 0 : return maFieldNames;
311 : }
312 :
313 0 : const vector<ScDPFieldControlBase::FieldName>& ScDPFieldControlBase::GetFieldNames() const
314 : {
315 0 : return maFieldNames;
316 : }
317 :
318 0 : void ScDPFieldControlBase::Paint( const Rectangle& /* rRect */ )
319 : {
320 : // hiding the caption is now done from StateChanged
321 0 : Redraw();
322 0 : }
323 :
324 0 : void ScDPFieldControlBase::StateChanged( StateChangedType nStateChange )
325 : {
326 0 : Control::StateChanged( nStateChange );
327 :
328 0 : if( nStateChange == STATE_CHANGE_INITSHOW )
329 : {
330 : /* After the fixed text associated to this control has received its
331 : unique mnemonic from VCL dialog initialization code, put this text
332 : into the field windows.
333 : #124828# Hiding the FixedTexts and clearing the tab stop style bits
334 : has to be done after assigning the mnemonics, but Paint() is too
335 : late, because the test tool may send key events to the dialog when
336 : it isn't visible. Mnemonics are assigned in Dialog::StateChanged()
337 : for STATE_CHANGE_INITSHOW, so this can be done immediately
338 : afterwards. */
339 :
340 0 : if ( mpCaption )
341 : {
342 0 : SetText( mpCaption->GetText() );
343 0 : mpCaption->Hide();
344 : }
345 : }
346 0 : }
347 :
348 0 : void ScDPFieldControlBase::DataChanged( const DataChangedEvent& rDCEvt )
349 : {
350 0 : Control::DataChanged( rDCEvt );
351 0 : if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
352 0 : Invalidate();
353 0 : }
354 :
355 0 : void ScDPFieldControlBase::Command( const CommandEvent& rCEvt )
356 : {
357 0 : if (rCEvt.GetCommand() == COMMAND_WHEEL)
358 : {
359 0 : const CommandWheelData* pData = rCEvt.GetWheelData();
360 0 : if (pData->GetMode() == COMMAND_WHEEL_SCROLL && !pData->IsHorz())
361 : {
362 : // Handle vertical mouse wheel scrolls.
363 0 : long nNotch = pData->GetNotchDelta(); // positive => up; negative => down
364 0 : HandleWheelScroll(nNotch);
365 : }
366 : }
367 0 : }
368 :
369 0 : void ScDPFieldControlBase::MouseButtonDown( const MouseEvent& rMEvt )
370 : {
371 0 : if( rMEvt.IsLeft() )
372 : {
373 0 : size_t nNewSelectIndex = GetFieldIndex( rMEvt.GetPosPixel() );
374 0 : if (nNewSelectIndex != PIVOTFIELD_INVALID && IsExistingIndex(nNewSelectIndex))
375 : {
376 : // grabbing after GetFieldIndex() will prevent to focus empty window
377 0 : GrabFocusAndSelect( nNewSelectIndex );
378 :
379 0 : if( rMEvt.GetClicks() == 1 )
380 : {
381 0 : PointerStyle ePtr = mpDlg->NotifyMouseButtonDown( GetFieldType(), nNewSelectIndex );
382 0 : CaptureMouse();
383 0 : SetPointer( Pointer( ePtr ) );
384 : }
385 : else
386 0 : mpDlg->NotifyDoubleClick( GetFieldType(), nNewSelectIndex );
387 : }
388 : }
389 0 : }
390 :
391 0 : void ScDPFieldControlBase::MouseButtonUp( const MouseEvent& rMEvt )
392 : {
393 0 : if( rMEvt.IsLeft() )
394 : {
395 0 : if( rMEvt.GetClicks() == 1 )
396 : {
397 0 : Point aScrPos = OutputToScreenPixel(rMEvt.GetPosPixel());
398 0 : ScPivotFieldType eToType = mpDlg->GetFieldTypeAtPoint(aScrPos);
399 :
400 0 : mpDlg->DropFieldItem(aScrPos, eToType);
401 0 : SetPointer( Pointer( POINTER_ARROW ) );
402 : }
403 :
404 0 : if( IsMouseCaptured() )
405 0 : ReleaseMouse();
406 : }
407 0 : }
408 :
409 0 : void ScDPFieldControlBase::MouseMove( const MouseEvent& rMEvt )
410 : {
411 0 : if( IsMouseCaptured() )
412 : {
413 0 : Point aScrPos = OutputToScreenPixel(rMEvt.GetPosPixel());
414 0 : ScPivotFieldType eFieldType = mpDlg->GetFieldTypeAtPoint(aScrPos);
415 0 : PointerStyle ePtr = mpDlg->GetPointerStyleAtPoint(aScrPos, eFieldType);
416 0 : SetPointer( Pointer( ePtr ) );
417 : }
418 0 : const FieldNames& rFields = GetFieldNames();
419 0 : size_t nIndex = GetFieldIndex(rMEvt.GetPosPixel());
420 : // does the string not fit on the screen ? show a helpful helptext instead
421 0 : if (nIndex != PIVOTFIELD_INVALID && (nIndex < rFields.size()) && !rFields[nIndex].mbFits)
422 : {
423 0 : Point aPos = OutputToScreenPixel( rMEvt.GetPosPixel() );
424 0 : Rectangle aRect( aPos, GetSizePixel() );
425 0 : String aHelpText = GetFieldText(nIndex);
426 0 : Help::ShowQuickHelp( this, aRect, aHelpText );
427 : }
428 0 : }
429 :
430 0 : void ScDPFieldControlBase::KeyInput( const KeyEvent& rKEvt )
431 : {
432 0 : const KeyCode& rKeyCode = rKEvt.GetKeyCode();
433 0 : sal_uInt16 nCode = rKeyCode.GetCode();
434 :
435 :
436 0 : const FieldNames& rFields = GetFieldNames();
437 0 : bool bFieldMove = ( rKeyCode.IsMod1() && (GetFieldType() != PIVOTFIELDTYPE_SELECT) );
438 0 : bool bKeyEvaluated = true;
439 : void (ScDPFieldControlBase::*pMoveXY) (SCsCOL nDX, SCsROW nDY);
440 0 : if (bFieldMove)
441 0 : pMoveXY = &ScDPFieldControlBase::MoveFieldRel;
442 : else
443 0 : pMoveXY = &ScDPFieldControlBase::MoveSelection;
444 0 : switch( nCode )
445 : {
446 0 : case KEY_UP: (this->*pMoveXY)( 0, -1 ); break;
447 0 : case KEY_DOWN: (this->*pMoveXY)( 0, 1 ); break;
448 0 : case KEY_LEFT: (this->*pMoveXY)( -1, 0 ); break;
449 0 : case KEY_RIGHT: (this->*pMoveXY)( 1, 0 ); break;
450 : case KEY_HOME:
451 0 : if (bFieldMove)
452 0 : MoveField( 0 );
453 : else
454 : {
455 0 : if( !rFields.empty() )
456 0 : MoveSelection( 0 );
457 : }
458 0 : break;
459 : case KEY_END:
460 0 : if (bFieldMove)
461 0 : MoveField( rFields.size() - 1 );
462 : else
463 : {
464 0 : if( !rFields.empty() )
465 0 : MoveSelection( rFields.size() - 1 );
466 : }
467 0 : break;
468 : default:
469 0 : if ( !bFieldMove && nCode == KEY_DELETE )
470 0 : mpDlg->NotifyRemoveField( GetFieldType(), mnFieldSelected );
471 : else
472 0 : bKeyEvaluated = false;
473 0 : break;
474 : }
475 :
476 0 : if (bKeyEvaluated)
477 : {
478 0 : ScrollToShowSelection();
479 0 : Invalidate();
480 : }
481 : else
482 0 : Control::KeyInput( rKEvt );
483 0 : }
484 :
485 0 : void ScDPFieldControlBase::GetFocus()
486 : {
487 0 : Control::GetFocus();
488 0 : Invalidate();
489 0 : if( GetGetFocusFlags() & GETFOCUS_MNEMONIC )
490 : {
491 0 : size_t nOldCount = GetFieldCount();
492 0 : mpDlg->NotifyMoveFieldToEnd( GetFieldType() );
493 0 : if (GetFieldCount() > nOldCount)
494 : // Scroll to the end only when a new field is inserted.
495 0 : ScrollToEnd();
496 : }
497 : else // notify change focus
498 0 : mpDlg->NotifyFieldFocus( GetFieldType(), true );
499 :
500 0 : AccessRef xRef( mxAccessible );
501 0 : if( xRef.is() )
502 0 : xRef->GotFocus();
503 0 : }
504 :
505 0 : void ScDPFieldControlBase::LoseFocus()
506 : {
507 0 : Control::LoseFocus();
508 0 : Invalidate();
509 0 : mpDlg->NotifyFieldFocus( GetFieldType(), false );
510 :
511 0 : AccessRef xRef( mxAccessible );
512 0 : if( xRef.is() )
513 0 : xRef->LostFocus();
514 0 : }
515 :
516 0 : Reference<XAccessible> ScDPFieldControlBase::CreateAccessible()
517 : {
518 0 : com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xReturn(new ScAccessibleDataPilotControl(GetAccessibleParentWindow()->GetAccessible(), this));
519 :
520 0 : mxAccessible = xReturn;
521 0 : AccessRef xRef( mxAccessible );
522 0 : xRef->Init();
523 :
524 0 : return xReturn;
525 : }
526 :
527 0 : void ScDPFieldControlBase::FieldFocusChanged(size_t nOldSelected, size_t nFieldSelected)
528 : {
529 0 : AccessRef xRef( mxAccessible );
530 0 : if ( xRef.is() )
531 0 : xRef->FieldFocusChange(nOldSelected, nFieldSelected);
532 0 : }
533 :
534 0 : void ScDPFieldControlBase::UpdateStyle()
535 : {
536 0 : WinBits nMask = ~(WB_TABSTOP | WB_NOTABSTOP);
537 0 : SetStyle( (GetStyle() & nMask) | (IsEmpty() ? WB_NOTABSTOP : WB_TABSTOP) );
538 0 : }
539 :
540 0 : void ScDPFieldControlBase::DrawBackground( OutputDevice& rDev )
541 : {
542 0 : const StyleSettings& rStyleSet = GetSettings().GetStyleSettings();
543 0 : Color aFaceColor = rStyleSet.GetFaceColor();
544 0 : Color aWinColor = rStyleSet.GetWindowColor();
545 0 : Color aWinTextColor = rStyleSet.GetWindowTextColor();
546 :
547 0 : Point aPos0;
548 0 : Size aSize( GetSizePixel() );
549 :
550 0 : if (mpCaption)
551 : {
552 0 : rDev.SetLineColor( aWinTextColor );
553 0 : rDev.SetFillColor( aWinColor );
554 : }
555 : else
556 : {
557 0 : rDev.SetLineColor( aFaceColor );
558 0 : rDev.SetFillColor( aFaceColor );
559 : }
560 0 : rDev.DrawRect( Rectangle( aPos0, aSize ) );
561 :
562 0 : rDev.SetTextColor( aWinTextColor );
563 :
564 : /* Draw the caption text. This needs some special handling, because we
565 : support hard line breaks here. This part will draw each line of the
566 : text for itself. */
567 :
568 0 : xub_StrLen nTokenCnt = comphelper::string::getTokenCount(GetText(), '\n');
569 0 : long nY = (aSize.Height() - nTokenCnt * rDev.GetTextHeight()) / 2;
570 0 : for( xub_StrLen nToken = 0, nStringIx = 0; nToken < nTokenCnt; ++nToken )
571 : {
572 0 : String aLine( GetText().GetToken( 0, '\n', nStringIx ) );
573 0 : Point aLinePos( (aSize.Width() - rDev.GetCtrlTextWidth( aLine )) / 2, nY );
574 0 : rDev.DrawCtrlText( aLinePos, aLine );
575 0 : nY += rDev.GetTextHeight();
576 0 : }
577 0 : }
578 :
579 0 : void ScDPFieldControlBase::DrawField(
580 : OutputDevice& rDev, const Rectangle& rRect, FieldName& rText, bool bFocus )
581 : {
582 0 : const StyleSettings& rStyleSet = GetSettings().GetStyleSettings();
583 0 : Color aTextColor = rStyleSet.GetButtonTextColor();
584 :
585 0 : VirtualDevice aVirDev( rDev );
586 : // #i97623# VirtualDevice is always LTR while other windows derive direction from parent
587 0 : aVirDev.EnableRTL( IsRTLEnabled() );
588 :
589 0 : rtl::OUString aText = rText.getDisplayedText();
590 :
591 0 : Size aDevSize( rRect.GetSize() );
592 0 : long nWidth = aDevSize.Width();
593 0 : long nHeight = aDevSize.Height();
594 0 : long nLabelWidth = rDev.GetTextWidth( aText );
595 0 : long nLabelHeight = rDev.GetTextHeight();
596 :
597 : // #i31600# if text is too long, cut and add ellipsis
598 0 : rText.mbFits = nLabelWidth + 6 <= nWidth;
599 0 : if (!rText.mbFits)
600 : {
601 0 : sal_Int32 nMinLen = 0;
602 0 : sal_Int32 nMaxLen = aText.getLength();
603 0 : bool bFits = false;
604 0 : do
605 : {
606 0 : sal_Int32 nCurrLen = (nMinLen + nMaxLen) / 2;
607 0 : rtl::OUStringBuffer aBuf(rText.maText.copy(0, nCurrLen));
608 0 : aBuf.appendAscii("...");
609 0 : aText = aBuf.makeStringAndClear();
610 0 : nLabelWidth = rDev.GetTextWidth( aText );
611 0 : bFits = nLabelWidth + 6 <= nWidth;
612 0 : (bFits ? nMinLen : nMaxLen) = nCurrLen;
613 : }
614 0 : while( !bFits || (nMinLen + 1 < nMaxLen) );
615 : }
616 0 : Point aLabelPos( (nWidth - nLabelWidth) / 2, ::std::max< long >( (nHeight - nLabelHeight) / 2, 3 ) );
617 :
618 0 : aVirDev.SetOutputSizePixel( aDevSize );
619 0 : aVirDev.SetFont( rDev.GetFont() );
620 0 : DecorationView aDecoView( &aVirDev );
621 0 : aDecoView.DrawButton( Rectangle( Point( 0, 0 ), aDevSize ), bFocus ? BUTTON_DRAW_DEFAULT : 0 );
622 0 : aVirDev.SetTextColor( aTextColor );
623 0 : aVirDev.DrawText( aLabelPos, aText );
624 0 : rDev.DrawBitmap( rRect.TopLeft(), aVirDev.GetBitmap( Point( 0, 0 ), aDevSize ) );
625 0 : }
626 :
627 0 : void ScDPFieldControlBase::AppendPaintable(Window* p)
628 : {
629 0 : maPaintables.push_back(p);
630 0 : }
631 :
632 0 : void ScDPFieldControlBase::DrawPaintables()
633 : {
634 0 : Rectangle aRect(GetPosPixel(), GetSizePixel());
635 0 : Paintables::iterator itr = maPaintables.begin(), itrEnd = maPaintables.end();
636 0 : for (; itr != itrEnd; ++itr)
637 : {
638 0 : Window* p = *itr;
639 0 : if (!p->IsVisible())
640 0 : continue;
641 :
642 0 : p->Paint(aRect);
643 : }
644 0 : }
645 :
646 0 : void ScDPFieldControlBase::DrawInvertSelection()
647 : {
648 0 : if (!HasFocus())
649 : return;
650 :
651 0 : if (mnFieldSelected >= maFieldNames.size())
652 : return;
653 :
654 0 : size_t nPos = GetDisplayPosition(mnFieldSelected);
655 0 : if (nPos == INVALID_INDEX)
656 : return;
657 :
658 0 : Size aFldSize = GetFieldSize();
659 0 : long nFldWidth = aFldSize.Width();
660 : long nSelWidth = std::min<long>(
661 0 : GetTextWidth(maFieldNames[mnFieldSelected].getDisplayedText()) + 4, nFldWidth - 6);
662 :
663 0 : Point aPos = GetFieldPosition(nPos);
664 0 : aPos += Point((nFldWidth - nSelWidth) / 2, 3);
665 0 : Size aSize(nSelWidth, aFldSize.Height() - 6);
666 :
667 0 : Rectangle aSel(aPos, aSize);
668 0 : InvertTracking(aSel, SHOWTRACK_SMALL | SHOWTRACK_WINDOW);
669 : }
670 :
671 0 : Size ScDPFieldControlBase::GetStdFieldBtnSize() const
672 : {
673 0 : return mpDlg->GetStdFieldBtnSize();
674 : }
675 :
676 0 : void ScDPFieldControlBase::MoveField( size_t nDestIndex )
677 : {
678 0 : if (nDestIndex != mnFieldSelected)
679 : {
680 0 : std::swap(maFieldNames[nDestIndex], maFieldNames[mnFieldSelected]);
681 0 : mnFieldSelected = nDestIndex;
682 : }
683 0 : }
684 :
685 0 : void ScDPFieldControlBase::MoveFieldRel( SCsCOL nDX, SCsROW nDY )
686 : {
687 0 : MoveField( CalcNewFieldIndex( nDX, nDY ) );
688 0 : }
689 :
690 0 : void ScDPFieldControlBase::MoveSelection(size_t nIndex)
691 : {
692 0 : FieldNames& rFields = GetFieldNames();
693 0 : if (rFields.empty())
694 0 : return;
695 :
696 0 : if (nIndex >= rFields.size())
697 : // Prevent it from going out-of-bound.
698 0 : nIndex = rFields.size() - 1;
699 :
700 0 : if( mnFieldSelected != nIndex )
701 : {
702 0 : size_t nOldSelected = mnFieldSelected;
703 0 : mnFieldSelected = nIndex;
704 0 : Invalidate();
705 :
706 0 : if (HasFocus())
707 0 : FieldFocusChanged(nOldSelected, mnFieldSelected);
708 : }
709 :
710 0 : ScrollToShowSelection();
711 : }
712 :
713 0 : void ScDPFieldControlBase::MoveSelection(SCsCOL nDX, SCsROW nDY)
714 : {
715 0 : size_t nNewIndex = CalcNewFieldIndex( nDX, nDY );
716 0 : MoveSelection( nNewIndex );
717 0 : }
718 :
719 0 : sal_uInt8 ScDPFieldControlBase::GetNextDupCount(const rtl::OUString& rFieldText) const
720 : {
721 0 : sal_uInt8 nMax = 0;
722 0 : FieldNames::const_iterator it = maFieldNames.begin(), itEnd = maFieldNames.end();
723 0 : for (; it != itEnd; ++it)
724 : {
725 0 : if (it->maText != rFieldText)
726 0 : continue;
727 :
728 0 : sal_uInt8 nNextUp = it->mnDupCount + 1;
729 0 : if (nMax < nNextUp)
730 0 : nMax = nNextUp;
731 : }
732 0 : return nMax;
733 : }
734 :
735 0 : void ScDPFieldControlBase::SelectNext()
736 : {
737 0 : MoveSelection(mnFieldSelected + 1);
738 0 : }
739 :
740 0 : void ScDPFieldControlBase::GrabFocusAndSelect( size_t nIndex )
741 : {
742 0 : MoveSelection( nIndex );
743 0 : if( !HasFocus() )
744 0 : GrabFocus();
745 0 : }
746 :
747 : //=============================================================================
748 :
749 0 : ScDPHorFieldControl::ScDPHorFieldControl(
750 : ScPivotLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption, const char* pcHelpId) :
751 : ScDPFieldControlBase(pDialog, rResId, pCaption, pcHelpId),
752 : maScroll(this, WB_HORZ | WB_DRAG),
753 : mnFieldBtnRowCount(0),
754 0 : mnFieldBtnColCount(0)
755 : {
756 0 : maScroll.SetScrollHdl( LINK(this, ScDPHorFieldControl, ScrollHdl) );
757 0 : maScroll.SetEndScrollHdl( LINK(this, ScDPHorFieldControl, EndScrollHdl) );
758 0 : maScroll.Hide();
759 :
760 0 : AppendPaintable(&maScroll);
761 0 : }
762 :
763 0 : ScDPHorFieldControl::~ScDPHorFieldControl()
764 : {
765 0 : }
766 :
767 0 : Point ScDPHorFieldControl::GetFieldPosition( size_t nIndex )
768 : {
769 0 : Point aPos;
770 0 : Size aSize;
771 0 : GetFieldBtnPosSize(nIndex, aPos, aSize);
772 0 : return aPos;
773 : }
774 :
775 0 : Size ScDPHorFieldControl::GetFieldSize() const
776 : {
777 0 : return GetStdFieldBtnSize();
778 : }
779 :
780 0 : size_t ScDPHorFieldControl::GetFieldIndex( const Point& rPos )
781 : {
782 0 : if (rPos.X() < 0 || rPos.Y() < 0)
783 0 : return PIVOTFIELD_INVALID;
784 :
785 0 : Size aWndSize = GetSizePixel();
786 0 : if (rPos.X() > aWndSize.Width() || rPos.Y() > aWndSize.Height())
787 0 : return PIVOTFIELD_INVALID;
788 :
789 0 : size_t nX = rPos.X();
790 0 : size_t nY = rPos.Y();
791 0 : size_t nW = aWndSize.Width();
792 0 : size_t nH = aWndSize.Height();
793 :
794 0 : Size aFldSize = GetFieldSize();
795 0 : size_t nCurX = OUTER_MARGIN_HOR + aFldSize.Width() + ROW_FIELD_BTN_GAP/2;
796 0 : size_t nCurY = OUTER_MARGIN_VER + aFldSize.Height() + ROW_FIELD_BTN_GAP/2;
797 0 : size_t nCol = 0;
798 0 : size_t nRow = 0;
799 0 : while (nX > nCurX && nCurX <= nW)
800 : {
801 0 : nCurX += aFldSize.Width() + ROW_FIELD_BTN_GAP;
802 0 : ++nCol;
803 : }
804 0 : while (nY > nCurY && nCurY <= nH)
805 : {
806 0 : nCurY += aFldSize.Height() + ROW_FIELD_BTN_GAP;
807 0 : ++nRow;
808 : }
809 :
810 0 : size_t nOffset = maScroll.GetThumbPos();
811 0 : nCol += nOffset; // convert to logical column ID.
812 0 : size_t nIndex = nCol * mnFieldBtnRowCount + nRow;
813 0 : size_t nFldCount = GetFieldCount();
814 0 : if (nIndex > nFldCount)
815 0 : nIndex = nFldCount;
816 0 : return IsValidIndex(nIndex) ? nIndex : PIVOTFIELD_INVALID;
817 : }
818 :
819 0 : void ScDPHorFieldControl::Redraw()
820 : {
821 0 : VirtualDevice aVirDev;
822 : // #i97623# VirtualDevice is always LTR while other windows derive direction from parent
823 0 : aVirDev.EnableRTL( IsRTLEnabled() );
824 0 : aVirDev.SetMapMode( MAP_PIXEL );
825 :
826 0 : Point aPos0;
827 0 : Size aSize( GetSizePixel() );
828 0 : Font aFont( GetFont() ); // Font vom Window
829 0 : aFont.SetTransparent( true );
830 0 : aVirDev.SetFont( aFont );
831 0 : aVirDev.SetOutputSizePixel( aSize );
832 :
833 0 : DrawBackground( aVirDev );
834 :
835 0 : FieldNames& rFields = GetFieldNames();
836 : {
837 0 : long nScrollOffset = maScroll.GetThumbPos();
838 0 : FieldNames::iterator itr = rFields.begin(), itrEnd = rFields.end();
839 0 : if (nScrollOffset)
840 0 : ::std::advance(itr, nScrollOffset*mnFieldBtnRowCount);
841 :
842 0 : for (size_t i = 0; itr != itrEnd; ++itr, ++i)
843 : {
844 0 : Point aFldPt;
845 0 : Size aFldSize;
846 0 : if (!GetFieldBtnPosSize(i, aFldPt, aFldSize))
847 : break;
848 :
849 0 : size_t nField = i + nScrollOffset*mnFieldBtnRowCount;
850 0 : bool bFocus = HasFocus() && (nField == GetSelectedField());
851 0 : DrawField(aVirDev, Rectangle(aFldPt, aFldSize), *itr, bFocus);
852 : }
853 : }
854 :
855 0 : DrawBitmap( aPos0, aVirDev.GetBitmap( aPos0, aSize ) );
856 0 : DrawPaintables();
857 0 : DrawInvertSelection();
858 0 : UpdateStyle();
859 0 : }
860 :
861 0 : void ScDPHorFieldControl::CalcSize()
862 : {
863 0 : Size aWndSize = GetSizePixel();
864 :
865 0 : long nScrollSize = GetSettings().GetStyleSettings().GetScrollBarSize();
866 0 : maScroll.SetSizePixel(Size(aWndSize.Width() - OUTER_MARGIN_HOR*2, nScrollSize));
867 0 : maScroll.SetPosPixel(Point(OUTER_MARGIN_HOR, aWndSize.Height() - OUTER_MARGIN_VER - nScrollSize));
868 :
869 0 : long nTotalH = aWndSize.Height() - nScrollSize - OUTER_MARGIN_VER*2;
870 0 : long nTotalW = aWndSize.Width() - OUTER_MARGIN_HOR*2;
871 0 : mnFieldBtnRowCount = nTotalH / (GetFieldSize().Height() + ROW_FIELD_BTN_GAP);
872 0 : mnFieldBtnColCount = (nTotalW + ROW_FIELD_BTN_GAP) / (GetFieldSize().Width() + ROW_FIELD_BTN_GAP);
873 :
874 0 : maScroll.SetLineSize(1);
875 0 : maScroll.SetVisibleSize(mnFieldBtnColCount);
876 0 : maScroll.SetPageSize(mnFieldBtnColCount);
877 0 : maScroll.SetRange(Range(0, mnFieldBtnColCount));
878 0 : }
879 :
880 0 : bool ScDPHorFieldControl::IsValidIndex(size_t /*nIndex*/) const
881 : {
882 0 : return true;
883 : }
884 :
885 0 : size_t ScDPHorFieldControl::CalcNewFieldIndex(SCsCOL nDX, SCsROW nDY) const
886 : {
887 0 : size_t nSel = GetSelectedField();
888 0 : size_t nFldCount = GetFieldCount();
889 0 : SCsROW nRow = nSel % mnFieldBtnRowCount;
890 0 : SCsCOL nCol = nSel / mnFieldBtnRowCount;
891 : SCsCOL nColUpper = static_cast<SCsCOL>(ceil(
892 0 : static_cast<double>(nFldCount) / static_cast<double>(mnFieldBtnRowCount)) - 1);
893 0 : SCsROW nRowUpper = mnFieldBtnRowCount - 1;
894 :
895 0 : nCol += nDX;
896 0 : if (nCol < 0)
897 0 : nCol = 0;
898 0 : else if (nColUpper < nCol)
899 0 : nCol = nColUpper;
900 0 : nRow += nDY;
901 0 : if (nRow < 0)
902 0 : nRow = 0;
903 0 : else if (nRowUpper < nRow)
904 0 : nRow = nRowUpper;
905 :
906 0 : nSel = nCol*mnFieldBtnRowCount + nRow;
907 0 : if (nSel >= nFldCount)
908 0 : nSel = nFldCount - 1;
909 :
910 0 : return nSel;
911 : }
912 :
913 0 : size_t ScDPHorFieldControl::GetDisplayPosition(size_t nIndex) const
914 : {
915 0 : size_t nColFirst = maScroll.GetThumbPos();
916 0 : size_t nColLast = nColFirst + mnFieldBtnColCount - 1;
917 0 : size_t nCol = nIndex / mnFieldBtnRowCount;
918 0 : size_t nRow = nIndex % mnFieldBtnRowCount;
919 0 : if (nCol < nColFirst || nColLast < nCol)
920 : // index is outside the visible area.
921 0 : return INVALID_INDEX;
922 :
923 0 : size_t nPos = (nCol - nColFirst)*mnFieldBtnRowCount + nRow;
924 0 : return nPos;
925 : }
926 :
927 0 : String ScDPHorFieldControl::GetDescription() const
928 : {
929 0 : return ScResId(STR_ACC_DATAPILOT_COL_DESCR);
930 : }
931 :
932 0 : void ScDPHorFieldControl::ScrollToEnd()
933 : {
934 0 : maScroll.DoScroll(maScroll.GetRangeMax());
935 0 : }
936 :
937 0 : void ScDPHorFieldControl::ScrollToShowSelection()
938 : {
939 0 : size_t nLower = maScroll.GetThumbPos();
940 0 : size_t nUpper = nLower + mnFieldBtnColCount - 1;
941 0 : size_t nCol = GetSelectedField() / mnFieldBtnRowCount;
942 0 : if (nCol < nLower)
943 : {
944 : // scroll to left.
945 0 : maScroll.DoScroll(nCol);
946 : }
947 0 : else if (nUpper < nCol)
948 : {
949 : // scroll to right.
950 0 : maScroll.DoScroll(nCol - mnFieldBtnColCount + 1);
951 : }
952 0 : }
953 :
954 0 : void ScDPHorFieldControl::ResetScrollBar()
955 : {
956 0 : long nOldMax = maScroll.GetRangeMax();
957 : long nNewMax = static_cast<long>(ceil(
958 0 : static_cast<double>(GetFieldCount()) / static_cast<double>(mnFieldBtnRowCount)));
959 :
960 0 : if (nOldMax != nNewMax)
961 : {
962 0 : maScroll.SetRangeMax(nNewMax);
963 0 : bool bShow = mnFieldBtnColCount*mnFieldBtnRowCount < GetFieldCount();
964 0 : maScroll.Show(bShow);
965 : }
966 0 : }
967 :
968 0 : void ScDPHorFieldControl::HandleWheelScroll(long /*nNotch*/)
969 : {
970 : // not handled for horizontal field controls.
971 0 : }
972 :
973 0 : bool ScDPHorFieldControl::GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize)
974 : {
975 0 : if (nPos >= mnFieldBtnColCount*mnFieldBtnRowCount)
976 0 : return false;
977 :
978 0 : Point aPos = Point(OUTER_MARGIN_HOR, OUTER_MARGIN_VER);
979 0 : size_t nRow = nPos % mnFieldBtnRowCount;
980 0 : size_t nCol = nPos / mnFieldBtnRowCount;
981 :
982 0 : aPos.X() += nCol*(GetFieldSize().Width() + ROW_FIELD_BTN_GAP);
983 0 : aPos.Y() += nRow*(GetFieldSize().Height() + ROW_FIELD_BTN_GAP);
984 :
985 0 : rPos = aPos;
986 0 : rSize = GetFieldSize();
987 0 : return true;
988 : }
989 :
990 0 : void ScDPHorFieldControl::HandleScroll()
991 : {
992 0 : Redraw();
993 0 : }
994 :
995 0 : IMPL_LINK_NOARG(ScDPHorFieldControl, ScrollHdl)
996 : {
997 0 : HandleScroll();
998 0 : return 0;
999 : }
1000 :
1001 0 : IMPL_LINK_NOARG(ScDPHorFieldControl, EndScrollHdl)
1002 : {
1003 0 : HandleScroll();
1004 0 : return 0;
1005 : }
1006 :
1007 : //=============================================================================
1008 :
1009 0 : ScDPPageFieldControl::ScDPPageFieldControl(
1010 : ScPivotLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption, const char* pcHelpId) :
1011 0 : ScDPHorFieldControl(pDialog, rResId, pCaption, pcHelpId)
1012 : {
1013 0 : }
1014 :
1015 0 : ScDPPageFieldControl::~ScDPPageFieldControl()
1016 : {
1017 0 : }
1018 :
1019 0 : ScPivotFieldType ScDPPageFieldControl::GetFieldType() const
1020 : {
1021 0 : return PIVOTFIELDTYPE_PAGE;
1022 : }
1023 :
1024 0 : String ScDPPageFieldControl::GetDescription() const
1025 : {
1026 0 : return ScResId(STR_ACC_DATAPILOT_PAGE_DESCR);
1027 : }
1028 :
1029 : //=============================================================================
1030 :
1031 0 : ScDPColFieldControl::ScDPColFieldControl(
1032 : ScPivotLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption, const char* pcHelpId) :
1033 0 : ScDPHorFieldControl(pDialog, rResId, pCaption, pcHelpId)
1034 : {
1035 0 : }
1036 :
1037 0 : ScDPColFieldControl::~ScDPColFieldControl()
1038 : {
1039 0 : }
1040 :
1041 0 : ScPivotFieldType ScDPColFieldControl::GetFieldType() const
1042 : {
1043 0 : return PIVOTFIELDTYPE_COL;
1044 : }
1045 :
1046 0 : String ScDPColFieldControl::GetDescription() const
1047 : {
1048 0 : return ScResId(STR_ACC_DATAPILOT_COL_DESCR);
1049 : }
1050 :
1051 : //=============================================================================
1052 :
1053 0 : ScDPRowFieldControl::ScDPRowFieldControl(
1054 : ScPivotLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption, const char* pcHelpId) :
1055 : ScDPFieldControlBase(pDialog, rResId, pCaption, pcHelpId),
1056 : maScroll(this, WB_VERT | WB_DRAG),
1057 0 : mnColumnBtnCount(0)
1058 : {
1059 0 : maScroll.SetScrollHdl( LINK(this, ScDPRowFieldControl, ScrollHdl) );
1060 0 : maScroll.SetEndScrollHdl( LINK(this, ScDPRowFieldControl, EndScrollHdl) );
1061 0 : maScroll.Show(false);
1062 :
1063 0 : AppendPaintable(&maScroll);
1064 0 : }
1065 :
1066 0 : ScDPRowFieldControl::~ScDPRowFieldControl()
1067 : {
1068 0 : }
1069 :
1070 : //-------------------------------------------------------------------
1071 :
1072 0 : Point ScDPRowFieldControl::GetFieldPosition(size_t nIndex)
1073 : {
1074 0 : Point aPos;
1075 0 : Size aSize;
1076 0 : GetFieldBtnPosSize(nIndex, aPos, aSize);
1077 0 : return aPos;
1078 : }
1079 :
1080 0 : Size ScDPRowFieldControl::GetFieldSize() const
1081 : {
1082 0 : return GetStdFieldBtnSize();
1083 : }
1084 :
1085 0 : size_t ScDPRowFieldControl::GetFieldIndex( const Point& rPos )
1086 : {
1087 0 : if (rPos.X() < 0 || rPos.Y() < 0)
1088 0 : return PIVOTFIELD_INVALID;
1089 :
1090 0 : long nFldH = GetFieldSize().Height();
1091 0 : long nThreshold = OUTER_MARGIN_VER + nFldH + ROW_FIELD_BTN_GAP / 2;
1092 :
1093 0 : size_t nIndex = 0;
1094 0 : for (; nIndex < mnColumnBtnCount; ++nIndex)
1095 : {
1096 0 : if (rPos.Y() < nThreshold)
1097 0 : break;
1098 :
1099 0 : nThreshold += nFldH + ROW_FIELD_BTN_GAP;
1100 : }
1101 :
1102 0 : if (nIndex >= mnColumnBtnCount)
1103 0 : nIndex = mnColumnBtnCount - 1;
1104 :
1105 0 : nIndex += maScroll.GetThumbPos();
1106 0 : return IsValidIndex(nIndex) ? nIndex : PIVOTFIELD_INVALID;
1107 : }
1108 :
1109 0 : void ScDPRowFieldControl::Redraw()
1110 : {
1111 0 : VirtualDevice aVirDev;
1112 : // #i97623# VirtualDevice is always LTR while other windows derive direction from parent
1113 0 : aVirDev.EnableRTL( IsRTLEnabled() );
1114 0 : aVirDev.SetMapMode( MAP_PIXEL );
1115 :
1116 0 : Point aPos0;
1117 0 : Size aWndSize = GetSizePixel();
1118 0 : Font aFont = GetFont();
1119 0 : aFont.SetTransparent(true);
1120 0 : aVirDev.SetFont(aFont);
1121 0 : aVirDev.SetOutputSizePixel(aWndSize);
1122 :
1123 0 : DrawBackground(aVirDev);
1124 :
1125 0 : FieldNames& rFields = GetFieldNames();
1126 : {
1127 0 : long nScrollOffset = maScroll.GetThumbPos();
1128 0 : FieldNames::iterator itr = rFields.begin(), itrEnd = rFields.end();
1129 0 : if (nScrollOffset)
1130 0 : ::std::advance(itr, nScrollOffset);
1131 :
1132 0 : for (size_t i = 0; itr != itrEnd; ++itr, ++i)
1133 : {
1134 0 : Point aFldPt;
1135 0 : Size aFldSize;
1136 0 : if (!GetFieldBtnPosSize(i, aFldPt, aFldSize))
1137 : break;
1138 :
1139 0 : size_t nField = i + nScrollOffset;
1140 0 : bool bFocus = HasFocus() && (nField == GetSelectedField());
1141 0 : DrawField(aVirDev, Rectangle(aFldPt, aFldSize), *itr, bFocus);
1142 : }
1143 : }
1144 :
1145 : // Create a bitmap from the virtual device, and place that bitmap onto
1146 : // this control.
1147 0 : DrawBitmap(aPos0, aVirDev.GetBitmap(aPos0, aWndSize));
1148 :
1149 0 : DrawPaintables();
1150 0 : DrawInvertSelection();
1151 0 : UpdateStyle();
1152 0 : }
1153 :
1154 0 : void ScDPRowFieldControl::CalcSize()
1155 : {
1156 0 : Size aWndSize = GetSizePixel();
1157 :
1158 0 : long nTotal = aWndSize.Height() - OUTER_MARGIN_VER;
1159 0 : mnColumnBtnCount = nTotal / (GetFieldSize().Height() + ROW_FIELD_BTN_GAP);
1160 :
1161 0 : long nScrollSize = GetSettings().GetStyleSettings().GetScrollBarSize();
1162 :
1163 0 : maScroll.SetSizePixel(Size(nScrollSize, aWndSize.Height() - OUTER_MARGIN_VER*2));
1164 0 : maScroll.SetPosPixel(Point(aWndSize.Width() - nScrollSize - OUTER_MARGIN_HOR, OUTER_MARGIN_VER));
1165 0 : maScroll.SetLineSize(1);
1166 0 : maScroll.SetVisibleSize(mnColumnBtnCount);
1167 0 : maScroll.SetPageSize(mnColumnBtnCount);
1168 0 : maScroll.SetRange(Range(0, mnColumnBtnCount));
1169 0 : maScroll.DoScroll(0);
1170 :
1171 0 : }
1172 :
1173 0 : bool ScDPRowFieldControl::IsValidIndex(size_t /*nIndex*/) const
1174 : {
1175 : // This method is here in case we decide to impose an arbitrary upper
1176 : // boundary on the number of fields.
1177 0 : return true;
1178 : }
1179 :
1180 0 : size_t ScDPRowFieldControl::CalcNewFieldIndex(SCsCOL /*nDX*/, SCsROW nDY) const
1181 : {
1182 0 : size_t nNewField = GetSelectedField();
1183 0 : nNewField += nDY;
1184 0 : return IsExistingIndex(nNewField) ? nNewField : GetSelectedField();
1185 : }
1186 :
1187 0 : size_t ScDPRowFieldControl::GetDisplayPosition(size_t nIndex) const
1188 : {
1189 0 : size_t nLower = maScroll.GetThumbPos();
1190 0 : size_t nUpper = nLower + mnColumnBtnCount;
1191 0 : if (nLower <= nIndex && nIndex <= nUpper)
1192 0 : return nIndex - nLower;
1193 :
1194 0 : return INVALID_INDEX;
1195 : }
1196 :
1197 : //-------------------------------------------------------------------
1198 :
1199 0 : String ScDPRowFieldControl::GetDescription() const
1200 : {
1201 0 : return ScResId(STR_ACC_DATAPILOT_ROW_DESCR);
1202 : }
1203 :
1204 0 : ScPivotFieldType ScDPRowFieldControl::GetFieldType() const
1205 : {
1206 0 : return PIVOTFIELDTYPE_ROW;
1207 : }
1208 :
1209 0 : void ScDPRowFieldControl::ScrollToEnd()
1210 : {
1211 0 : maScroll.DoScroll(maScroll.GetRangeMax());
1212 0 : }
1213 :
1214 0 : void ScDPRowFieldControl::ScrollToShowSelection()
1215 : {
1216 0 : size_t nLower = maScroll.GetThumbPos();
1217 0 : size_t nUpper = nLower + mnColumnBtnCount - 1;
1218 0 : size_t nSel = GetSelectedField();
1219 0 : if (nSel < nLower)
1220 : {
1221 : // scroll up
1222 0 : maScroll.DoScroll(nSel);
1223 : }
1224 0 : else if (nUpper < nSel)
1225 : {
1226 : // scroll down
1227 0 : size_t nD = nSel - nUpper;
1228 0 : maScroll.DoScroll(nLower + nD);
1229 : }
1230 0 : }
1231 :
1232 0 : void ScDPRowFieldControl::ResetScrollBar()
1233 : {
1234 0 : long nOldMax = maScroll.GetRangeMax();
1235 0 : long nNewMax = std::max<long>(mnColumnBtnCount, GetFieldCount());
1236 :
1237 0 : if (nOldMax != nNewMax)
1238 : {
1239 0 : maScroll.SetRangeMax(nNewMax);
1240 0 : maScroll.Show(GetFieldCount() > mnColumnBtnCount);
1241 : }
1242 0 : }
1243 :
1244 0 : void ScDPRowFieldControl::HandleWheelScroll(long nNotch)
1245 : {
1246 0 : maScroll.DoScroll(maScroll.GetThumbPos() - nNotch);
1247 0 : }
1248 :
1249 0 : bool ScDPRowFieldControl::GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize)
1250 : {
1251 0 : if (nPos >= mnColumnBtnCount)
1252 0 : return false;
1253 :
1254 0 : size_t nOffset = maScroll.GetThumbPos();
1255 0 : if (nPos + nOffset >= GetFieldCount())
1256 0 : return false;
1257 :
1258 0 : rSize = GetFieldSize();
1259 0 : rPos = Point(OUTER_MARGIN_HOR, OUTER_MARGIN_VER);
1260 0 : rPos.Y() += nPos * (rSize.Height() + ROW_FIELD_BTN_GAP);
1261 0 : return true;
1262 : }
1263 :
1264 0 : void ScDPRowFieldControl::HandleScroll()
1265 : {
1266 0 : Redraw();
1267 0 : }
1268 :
1269 0 : IMPL_LINK_NOARG(ScDPRowFieldControl, ScrollHdl)
1270 : {
1271 0 : HandleScroll();
1272 0 : return 0;
1273 : }
1274 :
1275 0 : IMPL_LINK_NOARG(ScDPRowFieldControl, EndScrollHdl)
1276 : {
1277 0 : HandleScroll();
1278 0 : return 0;
1279 : }
1280 :
1281 : //=============================================================================
1282 :
1283 0 : ScDPSelectFieldControl::ScDPSelectFieldControl(
1284 : ScPivotLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption, const char* pcHelpId) :
1285 0 : ScDPHorFieldControl(pDialog, rResId, pCaption, pcHelpId)
1286 : {
1287 0 : SetName(String(ScResId(STR_SELECT)));
1288 0 : }
1289 :
1290 0 : ScDPSelectFieldControl::~ScDPSelectFieldControl()
1291 : {
1292 0 : }
1293 :
1294 0 : ScPivotFieldType ScDPSelectFieldControl::GetFieldType() const
1295 : {
1296 0 : return PIVOTFIELDTYPE_SELECT;
1297 : }
1298 :
1299 0 : String ScDPSelectFieldControl::GetDescription() const
1300 : {
1301 0 : return ScResId(STR_ACC_DATAPILOT_SEL_DESCR);
1302 : }
1303 :
1304 : //=============================================================================
1305 :
1306 0 : ScDPDataFieldControl::ScDPDataFieldControl(
1307 : ScPivotLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption, const char* pcHelpId) :
1308 0 : ScDPHorFieldControl(pDialog, rResId, pCaption, pcHelpId)
1309 : {
1310 0 : }
1311 :
1312 0 : ScDPDataFieldControl::~ScDPDataFieldControl()
1313 : {
1314 0 : }
1315 :
1316 0 : ScPivotFieldType ScDPDataFieldControl::GetFieldType() const
1317 : {
1318 0 : return PIVOTFIELDTYPE_DATA;
1319 : }
1320 :
1321 0 : Size ScDPDataFieldControl::GetFieldSize() const
1322 : {
1323 0 : Size aWndSize = GetSizePixel();
1324 0 : long nFieldObjWidth = static_cast<long>(aWndSize.Width() / 2.0 - OUTER_MARGIN_HOR - DATA_FIELD_BTN_GAP/2);
1325 0 : Size aFieldSize(nFieldObjWidth, FIELD_BTN_HEIGHT);
1326 0 : return aFieldSize;
1327 : }
1328 :
1329 0 : String ScDPDataFieldControl::GetDescription() const
1330 : {
1331 0 : return ScResId(STR_ACC_DATAPILOT_DATA_DESCR);
1332 102 : }
1333 :
1334 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|