Line data Source code
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 <svtools/tabbar.hxx>
22 : #include <tools/time.hxx>
23 : #include <tools/debug.hxx>
24 : #include <tools/poly.hxx>
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/help.hxx>
27 : #include <vcl/decoview.hxx>
28 : #include <vcl/button.hxx>
29 : #include <vcl/edit.hxx>
30 : #include <vcl/image.hxx>
31 : #include <vcl/settings.hxx>
32 : #include "svtaccessiblefactory.hxx"
33 : #include <filectrl.hrc>
34 : #include <svtools/svtresid.hxx>
35 : #include <svtools/svtools.hrc>
36 : #include <limits>
37 :
38 :
39 : #define TABBAR_DRAG_SCROLLOFF 5
40 : #define TABBAR_MINSIZE 5
41 :
42 : const sal_uInt16 ADDNEWPAGE_AREAWIDTH = 10;
43 :
44 :
45 :
46 4816 : struct ImplTabBarItem
47 : {
48 : sal_uInt16 mnId;
49 : TabBarPageBits mnBits;
50 : OUString maText;
51 : OUString maHelpText;
52 : Rectangle maRect;
53 : long mnWidth;
54 : OString maHelpId;
55 : bool mbShort;
56 : bool mbSelect;
57 : bool mbEnable;
58 : Color maTabBgColor;
59 : Color maTabTextColor;
60 :
61 4816 : ImplTabBarItem( sal_uInt16 nItemId, const OUString& rText,
62 : TabBarPageBits nPageBits ) :
63 4816 : maText( rText )
64 : {
65 4816 : mnId = nItemId;
66 4816 : mnBits = nPageBits;
67 4816 : mnWidth = 0;
68 4816 : mbShort = false;
69 4816 : mbSelect = false;
70 4816 : mbEnable = true;
71 4816 : maTabBgColor = Color( COL_AUTO );
72 4816 : maTabTextColor = Color( COL_AUTO );
73 4816 : }
74 :
75 1119 : bool IsDefaultTabBgColor() const
76 : {
77 1119 : return maTabBgColor == Color(COL_AUTO);
78 : }
79 :
80 1119 : bool IsSelected(ImplTabBarItem* pCurItem) const
81 : {
82 1119 : return mbSelect || (pCurItem == this);
83 : }
84 : };
85 :
86 :
87 :
88 :
89 : // - ImplTabButton -
90 :
91 :
92 7344 : class ImplTabButton : public PushButton
93 : {
94 : public:
95 3672 : ImplTabButton( TabBar* pParent, WinBits nWinStyle = 0 ) :
96 3672 : PushButton( pParent, nWinStyle | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS ) {}
97 :
98 0 : TabBar* GetParent() const { return static_cast<TabBar*>(Window::GetParent()); }
99 :
100 : virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
101 :
102 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
103 :
104 : virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE;
105 : };
106 :
107 0 : void ImplTabButton::MouseButtonDown( const MouseEvent& rMEvt )
108 : {
109 0 : PushButton::MouseButtonDown(rMEvt);
110 0 : }
111 :
112 0 : void ImplTabButton::Command( const CommandEvent& rCEvt )
113 : {
114 0 : sal_uInt16 nCmd = rCEvt.GetCommand();
115 0 : if ( nCmd == COMMAND_CONTEXTMENU )
116 : {
117 0 : TabBar *pParent = GetParent();
118 0 : pParent->maScrollAreaContextHdl.Call((void*)&rCEvt);
119 : }
120 0 : PushButton::Command(rCEvt);
121 0 : }
122 :
123 :
124 :
125 0 : bool ImplTabButton::PreNotify( NotifyEvent& rNEvt )
126 : {
127 0 : if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
128 : {
129 0 : if ( GetParent()->IsInEditMode() )
130 : {
131 0 : GetParent()->EndEditMode();
132 0 : return true;
133 : }
134 : }
135 :
136 0 : return PushButton::PreNotify( rNEvt );
137 : }
138 :
139 :
140 :
141 :
142 : // - ImplTabSizer -
143 :
144 :
145 424 : class ImplTabSizer : public vcl::Window
146 : {
147 : public:
148 : ImplTabSizer( TabBar* pParent, WinBits nWinStyle = 0 );
149 :
150 0 : TabBar* GetParent() const { return static_cast<TabBar*>(Window::GetParent()); }
151 :
152 : private:
153 : void ImplTrack( const Point& rScreenPos );
154 :
155 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
156 : virtual void Tracking( const TrackingEvent& rTEvt ) SAL_OVERRIDE;
157 : virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
158 :
159 : Point maStartPos;
160 : long mnStartWidth;
161 : };
162 :
163 :
164 :
165 212 : ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle )
166 : : Window( pParent, nWinStyle & WB_3DLOOK )
167 212 : , mnStartWidth(0)
168 : {
169 212 : SetPointer( Pointer( POINTER_HSIZEBAR ) );
170 212 : SetSizePixel( Size( 7, 0 ) );
171 212 : }
172 :
173 :
174 :
175 0 : void ImplTabSizer::ImplTrack( const Point& rScreenPos )
176 : {
177 0 : TabBar* pParent = GetParent();
178 0 : long nDiff = rScreenPos.X() - maStartPos.X();
179 0 : pParent->mnSplitSize = mnStartWidth + (pParent->IsMirrored() ? -nDiff : nDiff);
180 0 : if ( pParent->mnSplitSize < TABBAR_MINSIZE )
181 0 : pParent->mnSplitSize = TABBAR_MINSIZE;
182 0 : pParent->Split();
183 0 : pParent->Update();
184 0 : }
185 :
186 :
187 :
188 0 : void ImplTabSizer::MouseButtonDown( const MouseEvent& rMEvt )
189 : {
190 0 : if ( GetParent()->IsInEditMode() )
191 : {
192 0 : GetParent()->EndEditMode();
193 0 : return;
194 : }
195 :
196 0 : if ( rMEvt.IsLeft() )
197 : {
198 0 : maStartPos = OutputToScreenPixel( rMEvt.GetPosPixel() );
199 0 : mnStartWidth = GetParent()->GetSizePixel().Width();
200 0 : StartTracking();
201 : }
202 : }
203 :
204 :
205 :
206 0 : void ImplTabSizer::Tracking( const TrackingEvent& rTEvt )
207 : {
208 0 : if ( rTEvt.IsTrackingEnded() )
209 : {
210 0 : if ( rTEvt.IsTrackingCanceled() )
211 0 : ImplTrack( maStartPos );
212 0 : GetParent()->mnSplitSize = 0;
213 : }
214 : else
215 0 : ImplTrack( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
216 0 : }
217 :
218 :
219 :
220 0 : void ImplTabSizer::Paint( const Rectangle& )
221 : {
222 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
223 0 : DecorationView aDecoView( this );
224 0 : long nOffX = 0;
225 0 : Size aOutputSize = GetOutputSizePixel();
226 :
227 0 : if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
228 : {
229 0 : SetLineColor( rStyleSettings.GetDarkShadowColor() );
230 0 : DrawLine( Point( 0, 0 ), Point( 0, aOutputSize.Height()-1 ) );
231 0 : nOffX++;
232 0 : aOutputSize.Width()--;
233 : }
234 0 : aDecoView.DrawButton( Rectangle( Point( nOffX, 0 ), aOutputSize ), BUTTON_DRAW_NOLIGHTBORDER );
235 0 : }
236 :
237 :
238 :
239 : // Is not named Impl. as it may be called or overloaded
240 :
241 :
242 : // - TabBarEdit -
243 :
244 :
245 0 : class TabBarEdit : public Edit
246 : {
247 : private:
248 : Timer maLoseFocusTimer;
249 : bool mbPostEvt;
250 :
251 : DECL_LINK( ImplEndEditHdl, void* );
252 : DECL_LINK( ImplEndTimerHdl, void* );
253 :
254 : public:
255 : TabBarEdit( TabBar* pParent, WinBits nWinStyle = 0 );
256 :
257 0 : TabBar* GetParent() const { return static_cast<TabBar*>(Window::GetParent()); }
258 :
259 0 : void SetPostEvent() { mbPostEvt = true; }
260 0 : void ResetPostEvent() { mbPostEvt = false; }
261 :
262 : virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
263 : virtual void LoseFocus() SAL_OVERRIDE;
264 : };
265 :
266 :
267 :
268 0 : TabBarEdit::TabBarEdit( TabBar* pParent, WinBits nWinStyle ) :
269 0 : Edit( pParent, nWinStyle )
270 : {
271 0 : mbPostEvt = false;
272 0 : }
273 :
274 :
275 :
276 0 : bool TabBarEdit::PreNotify( NotifyEvent& rNEvt )
277 : {
278 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
279 : {
280 0 : const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
281 0 : if ( !pKEvt->GetKeyCode().GetModifier() )
282 : {
283 0 : if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
284 : {
285 0 : if ( !mbPostEvt )
286 : {
287 0 : if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), reinterpret_cast<void*>(sal_False) ) )
288 0 : mbPostEvt = true;
289 : }
290 0 : return true;
291 : }
292 0 : else if ( pKEvt->GetKeyCode().GetCode() == KEY_ESCAPE )
293 : {
294 0 : if ( !mbPostEvt )
295 : {
296 0 : if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), reinterpret_cast<void*>(sal_True) ) )
297 0 : mbPostEvt = true;
298 : }
299 0 : return true;
300 : }
301 : }
302 : }
303 :
304 0 : return Edit::PreNotify( rNEvt );
305 : }
306 :
307 :
308 :
309 0 : void TabBarEdit::LoseFocus()
310 : {
311 0 : if ( !mbPostEvt )
312 : {
313 0 : if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), reinterpret_cast<void*>(sal_False) ) )
314 0 : mbPostEvt = true;
315 : }
316 :
317 0 : Edit::LoseFocus();
318 0 : }
319 :
320 :
321 :
322 0 : IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel )
323 : {
324 0 : ResetPostEvent();
325 0 : maLoseFocusTimer.Stop();
326 :
327 : // We need this query, because the edit get a losefous event,
328 : // when it shows the context menu or the insert symbol dialog
329 0 : if ( !HasFocus() && HasChildPathFocus( true ) )
330 : {
331 0 : maLoseFocusTimer.SetTimeout( 30 );
332 0 : maLoseFocusTimer.SetTimeoutHdl( LINK( this, TabBarEdit, ImplEndTimerHdl ) );
333 0 : maLoseFocusTimer.Start();
334 : }
335 : else
336 0 : GetParent()->EndEditMode( pCancel != 0 );
337 :
338 0 : return 0;
339 : }
340 :
341 :
342 :
343 0 : IMPL_LINK_NOARG(TabBarEdit, ImplEndTimerHdl)
344 : {
345 0 : if ( HasFocus() )
346 0 : return 0;
347 :
348 : // We need this query, because the edit get a losefous event,
349 : // when it shows the context menu or the insert symbol dialog
350 0 : if ( HasChildPathFocus( true ) )
351 0 : maLoseFocusTimer.Start();
352 : else
353 0 : GetParent()->EndEditMode( true );
354 :
355 0 : return 0;
356 : }
357 :
358 :
359 : struct TabBar_Impl
360 : {
361 : ImplTabSizer* mpSizer;
362 : ::svt::AccessibleFactoryAccess maAccessibleFactory;
363 :
364 918 : TabBar_Impl()
365 918 : :mpSizer( NULL )
366 : {
367 918 : }
368 918 : ~TabBar_Impl()
369 : {
370 918 : delete mpSizer;
371 918 : }
372 : };
373 :
374 :
375 :
376 : const sal_uInt16 TabBar::APPEND = ::std::numeric_limits<sal_uInt16>::max();
377 : const sal_uInt16 TabBar::PAGE_NOT_FOUND = ::std::numeric_limits<sal_uInt16>::max();
378 : const sal_uInt16 TabBar::INSERT_TAB_POS = ::std::numeric_limits<sal_uInt16>::max() - 1;
379 :
380 918 : void TabBar::ImplInit( WinBits nWinStyle )
381 : {
382 918 : mpItemList = new ImplTabBarList;
383 918 : mpFirstBtn = NULL;
384 918 : mpPrevBtn = NULL;
385 918 : mpNextBtn = NULL;
386 918 : mpLastBtn = NULL;
387 918 : mpImpl = new TabBar_Impl;
388 918 : mpEdit = NULL;
389 918 : mnMaxPageWidth = 0;
390 918 : mnCurMaxWidth = 0;
391 918 : mnOffX = 0;
392 918 : mnOffY = 0;
393 918 : mnLastOffX = 0;
394 918 : mnSplitSize = 0;
395 918 : mnSwitchTime = 0;
396 918 : mnWinStyle = nWinStyle;
397 918 : mnCurPageId = 0;
398 918 : mnFirstPos = 0;
399 918 : mnDropPos = 0;
400 918 : mnSwitchId = 0;
401 918 : mnEditId = 0;
402 918 : mbFormat = true;
403 918 : mbFirstFormat = true;
404 918 : mbSizeFormat = true;
405 918 : mbAutoMaxWidth = true;
406 918 : mbInSwitching = false;
407 918 : mbAutoEditMode = false;
408 918 : mbEditCanceled = false;
409 918 : mbDropPos = false;
410 918 : mbInSelect = false;
411 918 : mbSelColor = false;
412 918 : mbSelTextColor = false;
413 918 : mbMirrored = false;
414 918 : mbMirrored = false;
415 918 : mbScrollAlwaysEnabled = false;
416 :
417 918 : if ( nWinStyle & WB_3DTAB )
418 0 : mnOffY++;
419 :
420 918 : ImplInitControls();
421 :
422 918 : if(mpFirstBtn)
423 918 : mpFirstBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVET0HOME));
424 918 : if(mpPrevBtn)
425 918 : mpPrevBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVELEFT));
426 918 : if(mpNextBtn)
427 918 : mpNextBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVERIGHT));
428 918 : if(mpLastBtn)
429 918 : mpLastBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVETOEND));
430 :
431 918 : SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
432 918 : ImplInitSettings( true, true );
433 918 : }
434 :
435 :
436 :
437 918 : TabBar::TabBar( vcl::Window* pParent, WinBits nWinStyle ) :
438 918 : Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN )
439 : {
440 918 : ImplInit( nWinStyle );
441 918 : maCurrentItemList = 0;
442 918 : }
443 :
444 :
445 :
446 1836 : TabBar::~TabBar()
447 : {
448 918 : EndEditMode( true );
449 :
450 : // Controls loeschen
451 918 : if ( mpPrevBtn )
452 918 : delete mpPrevBtn;
453 918 : if ( mpNextBtn )
454 918 : delete mpNextBtn;
455 918 : if ( mpFirstBtn )
456 918 : delete mpFirstBtn;
457 918 : if ( mpLastBtn )
458 918 : delete mpLastBtn;
459 918 : delete mpImpl;
460 :
461 2488 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
462 1570 : delete (*mpItemList)[ i ];
463 : }
464 918 : delete mpItemList;
465 918 : }
466 :
467 :
468 1088 : ImplTabBarItem* TabBar::seek( size_t i )
469 : {
470 1088 : if ( i < mpItemList->size() )
471 : {
472 1088 : maCurrentItemList = i;
473 1088 : return (*mpItemList)[ maCurrentItemList ];
474 : }
475 0 : return NULL;
476 : }
477 :
478 1119 : ImplTabBarItem* TabBar::prev()
479 : {
480 1119 : if ( maCurrentItemList > 0 ) {
481 575 : return (*mpItemList)[ --maCurrentItemList ];
482 : }
483 544 : return NULL;
484 : }
485 :
486 811 : ImplTabBarItem* TabBar::next()
487 : {
488 811 : if ( maCurrentItemList+1 < mpItemList->size() ) {
489 267 : return (*mpItemList)[ ++maCurrentItemList ];
490 : }
491 544 : return NULL;
492 : }
493 :
494 :
495 :
496 3620 : void TabBar::ImplInitSettings( bool bFont, bool bBackground )
497 : {
498 3620 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
499 :
500 3620 : if ( bFont )
501 : {
502 3620 : vcl::Font aToolFont;
503 3620 : aToolFont = rStyleSettings.GetToolFont();
504 3620 : if ( IsControlFont() )
505 0 : aToolFont.Merge( GetControlFont() );
506 3620 : aToolFont.SetWeight( WEIGHT_BOLD );
507 3620 : SetZoomedPointFont( aToolFont );
508 :
509 : // Adapt font size if window too small?
510 11890 : while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) )
511 : {
512 5580 : vcl::Font aFont = GetFont();
513 5580 : if ( aFont.GetHeight() <= 6 )
514 930 : break;
515 4650 : aFont.SetHeight( aFont.GetHeight()-1 );
516 4650 : SetFont( aFont );
517 8270 : }
518 : }
519 :
520 3620 : if ( bBackground )
521 : {
522 964 : Color aColor;
523 964 : if ( IsControlBackground() )
524 0 : aColor = GetControlBackground();
525 : else
526 964 : aColor = rStyleSettings.GetFaceColor();
527 964 : SetBackground( aColor );
528 : }
529 3620 : }
530 :
531 :
532 :
533 544 : void TabBar::ImplGetColors( Color& rFaceColor, Color& rFaceTextColor,
534 : Color& rSelectColor, Color& rSelectTextColor )
535 : {
536 544 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
537 :
538 544 : if ( IsControlBackground() )
539 0 : rFaceColor = GetControlBackground();
540 : else
541 544 : rFaceColor = rStyleSettings.GetInactiveTabColor();
542 544 : if ( IsControlForeground() )
543 0 : rFaceTextColor = GetControlForeground();
544 : else
545 544 : rFaceTextColor = rStyleSettings.GetButtonTextColor();
546 544 : if ( mbSelColor )
547 0 : rSelectColor = maSelColor;
548 : else
549 544 : rSelectColor = rStyleSettings.GetActiveTabColor();
550 544 : if ( mbSelTextColor )
551 0 : rSelectTextColor = maSelTextColor;
552 : else
553 544 : rSelectTextColor = rStyleSettings.GetWindowTextColor();
554 :
555 : // For 3D-tabs the selection- and face-colours are swapped,
556 : // as the selected tabs should appear in 3D
557 544 : if ( mnWinStyle & WB_3DTAB )
558 : {
559 0 : Color aTempColor = rFaceColor;
560 0 : rFaceColor = rSelectColor;
561 0 : rSelectColor = aTempColor;
562 0 : aTempColor = rFaceTextColor;
563 0 : rFaceTextColor = rSelectTextColor;
564 0 : rSelectTextColor = rFaceTextColor;
565 : }
566 544 : }
567 :
568 :
569 :
570 4718 : bool TabBar::ImplCalcWidth()
571 : {
572 : // Sizes should only be retrieved if the text or the font was changed
573 4718 : if ( !mbSizeFormat )
574 2350 : return false;
575 :
576 : // retrieve width of tabs with bold font
577 2368 : vcl::Font aFont = GetFont();
578 2368 : if ( aFont.GetWeight() != WEIGHT_BOLD )
579 : {
580 0 : aFont.SetWeight( WEIGHT_BOLD );
581 0 : SetFont( aFont );
582 : }
583 :
584 2368 : if ( mnMaxPageWidth )
585 609 : mnCurMaxWidth = mnMaxPageWidth;
586 1759 : else if ( mbAutoMaxWidth )
587 : {
588 1759 : mnCurMaxWidth = mnLastOffX - mnOffX;
589 1759 : if ( mnCurMaxWidth < 1 )
590 0 : mnCurMaxWidth = 1;
591 : }
592 : else
593 0 : mnCurMaxWidth = 0;
594 :
595 2368 : bool bChanged = false;
596 7292 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
597 : {
598 4924 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
599 4924 : long nNewWidth = GetTextWidth( pItem->maText );
600 4924 : if ( mnCurMaxWidth && (nNewWidth > mnCurMaxWidth) )
601 : {
602 0 : pItem->mbShort = true;
603 0 : nNewWidth = mnCurMaxWidth;
604 : }
605 : else
606 : {
607 4924 : pItem->mbShort = false;
608 : }
609 :
610 : // Padding is dependent on font height - bigger font = bigger padding
611 4924 : long nFontWidth = aFont.GetHeight();
612 4924 : nNewWidth += nFontWidth * 2;
613 :
614 4924 : if ( pItem->mnWidth != nNewWidth )
615 : {
616 2527 : pItem->mnWidth = nNewWidth;
617 2527 : if ( !pItem->maRect.IsEmpty() )
618 218 : bChanged = true;
619 : }
620 : }
621 2368 : mbSizeFormat = false;
622 2368 : mbFormat = true;
623 2368 : return bChanged;
624 : }
625 :
626 :
627 :
628 3684 : void TabBar::ImplFormat()
629 : {
630 3684 : ImplCalcWidth();
631 :
632 3684 : if ( !mbFormat )
633 4930 : return;
634 :
635 2438 : sal_uInt16 n = 0;
636 2438 : long x = mnOffX;
637 7770 : for ( size_t i = 0, nL = mpItemList->size(); i < nL; ++i )
638 : {
639 5332 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
640 : // At all non-visible tabs an empty rectangle is set
641 5332 : if ( (n+1 < mnFirstPos) || (x > mnLastOffX) )
642 896 : pItem->maRect.SetEmpty();
643 : else
644 : {
645 : // Slightly before the tab before the first visible page
646 : // should also be visible
647 4436 : if ( n+1 == mnFirstPos )
648 40 : pItem->maRect.Left() = x-pItem->mnWidth;
649 : else
650 : {
651 4396 : pItem->maRect.Left() = x;
652 4396 : x += pItem->mnWidth;
653 : }
654 4436 : pItem->maRect.Right() = x;
655 4436 : pItem->maRect.Bottom() = maWinSize.Height() - 1;
656 :
657 4436 : if( mbMirrored )
658 : {
659 2 : long nTmp = mnOffX + mnLastOffX - pItem->maRect.Right();
660 2 : pItem->maRect.Right() = mnOffX + mnLastOffX - pItem->maRect.Left();
661 2 : pItem->maRect.Left() = nTmp;
662 : }
663 : }
664 :
665 5332 : n++;
666 : }
667 :
668 2438 : mbFormat = false;
669 :
670 : // enable/disable button
671 2438 : ImplEnableControls();
672 : }
673 :
674 :
675 :
676 1811 : sal_uInt16 TabBar::ImplGetLastFirstPos()
677 : {
678 1811 : sal_uInt16 nCount = (sal_uInt16)(mpItemList->size());
679 1811 : if ( !nCount || mbSizeFormat || mbFormat )
680 0 : return 0;
681 :
682 1811 : sal_uInt16 nLastFirstPos = nCount-1;
683 1811 : long nWinWidth = mnLastOffX - mnOffX - ADDNEWPAGE_AREAWIDTH;
684 1811 : long nWidth = (*mpItemList)[ nLastFirstPos ]->mnWidth;
685 6026 : while ( nLastFirstPos && (nWidth < nWinWidth) )
686 : {
687 2404 : nLastFirstPos--;
688 2404 : nWidth += (*mpItemList)[ nLastFirstPos ]->mnWidth;
689 : }
690 1811 : if ( (nLastFirstPos != (sal_uInt16)(mpItemList->size()-1)) &&
691 : (nWidth > nWinWidth) )
692 143 : nLastFirstPos++;
693 1811 : return nLastFirstPos;
694 : }
695 :
696 :
697 :
698 2782 : void TabBar::ImplInitControls()
699 : {
700 2782 : if ( mnWinStyle & WB_SIZEABLE )
701 : {
702 212 : if ( !mpImpl->mpSizer )
703 212 : mpImpl->mpSizer = new ImplTabSizer( this, mnWinStyle & (WB_DRAG | WB_3DLOOK) );
704 212 : mpImpl->mpSizer->Show();
705 : }
706 : else
707 : {
708 2570 : DELETEZ( mpImpl->mpSizer );
709 : }
710 :
711 2782 : Link aLink = LINK( this, TabBar, ImplClickHdl );
712 :
713 2782 : if ( mnWinStyle & (WB_MINSCROLL | WB_SCROLL) )
714 : {
715 2782 : if ( !mpPrevBtn )
716 : {
717 918 : mpPrevBtn = new ImplTabButton( this, WB_REPEAT );
718 918 : mpPrevBtn->SetClickHdl( aLink );
719 : }
720 2782 : mpPrevBtn->SetSymbol( mbMirrored ? SymbolType::NEXT : SymbolType::PREV );
721 2782 : mpPrevBtn->Show();
722 :
723 2782 : if ( !mpNextBtn )
724 : {
725 918 : mpNextBtn = new ImplTabButton( this, WB_REPEAT );
726 918 : mpNextBtn->SetClickHdl( aLink );
727 : }
728 2782 : mpNextBtn->SetSymbol( mbMirrored ? SymbolType::PREV : SymbolType::NEXT );
729 2782 : mpNextBtn->Show();
730 : }
731 : else
732 : {
733 0 : DELETEZ( mpPrevBtn );
734 0 : DELETEZ( mpNextBtn );
735 : }
736 :
737 2782 : if ( mnWinStyle & WB_SCROLL )
738 : {
739 2782 : if ( !mpFirstBtn )
740 : {
741 918 : mpFirstBtn = new ImplTabButton( this );
742 918 : mpFirstBtn->SetClickHdl( aLink );
743 : }
744 2782 : mpFirstBtn->SetSymbol( mbMirrored ? SymbolType::LAST : SymbolType::FIRST );
745 2782 : mpFirstBtn->Show();
746 :
747 2782 : if ( !mpLastBtn )
748 : {
749 918 : mpLastBtn = new ImplTabButton( this );
750 918 : mpLastBtn->SetClickHdl( aLink );
751 : }
752 2782 : mpLastBtn->SetSymbol( mbMirrored ? SymbolType::FIRST : SymbolType::LAST );
753 2782 : mpLastBtn->Show();
754 : }
755 : else
756 : {
757 0 : DELETEZ( mpFirstBtn );
758 0 : DELETEZ( mpLastBtn );
759 : }
760 :
761 2782 : mbHasInsertTab = (mnWinStyle & WB_INSERTTAB);
762 2782 : }
763 :
764 :
765 :
766 5640 : void TabBar::ImplEnableControls()
767 : {
768 5640 : if ( mbSizeFormat || mbFormat )
769 7808 : return;
770 :
771 : // enable/disable buttons
772 3472 : bool bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos > 0;
773 3472 : if ( mpFirstBtn )
774 3472 : mpFirstBtn->Enable( bEnableBtn );
775 3472 : if ( mpPrevBtn )
776 3472 : mpPrevBtn->Enable( bEnableBtn );
777 :
778 3472 : bEnableBtn = mbScrollAlwaysEnabled || mnFirstPos < ImplGetLastFirstPos();
779 3472 : if ( mpNextBtn )
780 3472 : mpNextBtn->Enable( bEnableBtn );
781 3472 : if ( mpLastBtn )
782 3472 : mpLastBtn->Enable( bEnableBtn );
783 : }
784 :
785 546 : void TabBar::SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled)
786 : {
787 546 : mbScrollAlwaysEnabled = bScrollAlwaysEnabled;
788 546 : ImplEnableControls();
789 546 : }
790 :
791 1034 : void TabBar::ImplShowPage( sal_uInt16 nPos )
792 : {
793 1034 : if (nPos >= mpItemList->size())
794 1034 : return;
795 :
796 : // calculate width
797 1034 : long nWidth = GetOutputSizePixel().Width();
798 :
799 1034 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
800 1034 : if ( nPos < mnFirstPos )
801 0 : SetFirstPageId( pItem->mnId );
802 1034 : else if ( pItem->maRect.Right() > nWidth )
803 : {
804 24 : while ( pItem->maRect.Right() > nWidth )
805 : {
806 12 : sal_uInt16 nNewPos = mnFirstPos+1;
807 12 : SetFirstPageId( GetPageId( nNewPos ) );
808 12 : ImplFormat();
809 12 : if ( nNewPos != mnFirstPos )
810 12 : break;
811 : }
812 : }
813 : }
814 :
815 0 : IMPL_LINK( TabBar, ImplClickHdl, ImplTabButton*, pBtn )
816 : {
817 0 : EndEditMode();
818 :
819 0 : sal_uInt16 nNewPos = mnFirstPos;
820 :
821 0 : if ( pBtn == mpFirstBtn )
822 0 : nNewPos = 0;
823 0 : else if ( pBtn == mpPrevBtn )
824 : {
825 0 : if ( mnFirstPos )
826 0 : nNewPos = mnFirstPos-1;
827 : }
828 0 : else if ( pBtn == mpNextBtn )
829 : {
830 0 : sal_uInt16 nCount = GetPageCount();
831 0 : if ( mnFirstPos < nCount )
832 0 : nNewPos = mnFirstPos+1;
833 : }
834 : else
835 : {
836 0 : sal_uInt16 nCount = GetPageCount();
837 0 : if ( nCount )
838 0 : nNewPos = nCount-1;
839 : }
840 :
841 0 : if ( nNewPos != mnFirstPos )
842 0 : SetFirstPageId( GetPageId( nNewPos ) );
843 0 : return 0;
844 : }
845 :
846 :
847 :
848 0 : void TabBar::MouseMove( const MouseEvent& rMEvt )
849 : {
850 0 : if ( rMEvt.IsLeaveWindow() )
851 0 : mbInSelect = false;
852 :
853 0 : Window::MouseMove( rMEvt );
854 0 : }
855 :
856 :
857 :
858 0 : void TabBar::MouseButtonDown( const MouseEvent& rMEvt )
859 : {
860 : // Only terminate EditModus and do not execute Klick
861 : // if clicked inside our window,
862 0 : if ( IsInEditMode() )
863 : {
864 0 : EndEditMode();
865 0 : return;
866 : }
867 :
868 : ImplTabBarItem* pItem;
869 0 : sal_uInt16 nSelId = GetPageId( rMEvt.GetPosPixel() );
870 :
871 0 : if ( !rMEvt.IsLeft() )
872 : {
873 0 : Window::MouseButtonDown( rMEvt );
874 0 : if ( (nSelId > 0) && (nSelId != mnCurPageId) )
875 : {
876 0 : sal_uInt16 nPos = GetPagePos( nSelId );
877 0 : pItem = (*mpItemList)[ nPos ];
878 :
879 0 : if ( pItem->mbEnable )
880 : {
881 0 : if ( ImplDeactivatePage() )
882 : {
883 0 : SetCurPageId( nSelId );
884 0 : Update();
885 0 : ImplActivatePage();
886 0 : ImplSelect();
887 : }
888 0 : mbInSelect = true;
889 : }
890 : }
891 0 : return;
892 : }
893 :
894 0 : if ( rMEvt.IsMod2() && mbAutoEditMode && nSelId )
895 : {
896 0 : if ( StartEditMode( nSelId ) )
897 0 : return;
898 : }
899 :
900 0 : if ( (rMEvt.GetMode() & (MOUSE_MULTISELECT | MOUSE_RANGESELECT)) && (rMEvt.GetClicks() == 1) )
901 : {
902 0 : if ( nSelId )
903 : {
904 0 : sal_uInt16 nPos = GetPagePos( nSelId );
905 0 : bool bSelectTab = false;
906 0 : pItem = (*mpItemList)[ nPos ];
907 :
908 0 : if ( pItem->mbEnable )
909 : {
910 0 : if ( (rMEvt.GetMode() & MOUSE_MULTISELECT) && (mnWinStyle & WB_MULTISELECT) )
911 : {
912 0 : if ( nSelId != mnCurPageId )
913 : {
914 0 : SelectPage( nSelId, !IsPageSelected( nSelId ) );
915 0 : bSelectTab = true;
916 : }
917 : }
918 0 : else if ( mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT) )
919 : {
920 0 : bSelectTab = true;
921 : sal_uInt16 n;
922 : bool bSelect;
923 0 : sal_uInt16 nCurPos = GetPagePos( mnCurPageId );
924 0 : if ( nPos <= nCurPos )
925 : {
926 : // Deselect all tabs till the clicked tab
927 : // and select all tabs from the clicked tab
928 : // till the the actual position
929 0 : n = 0;
930 0 : while ( n < nCurPos )
931 : {
932 0 : pItem = (*mpItemList)[ n ];
933 0 : if ( n < nPos )
934 0 : bSelect = false;
935 : else
936 0 : bSelect = true;
937 :
938 0 : if ( pItem->mbSelect != bSelect )
939 : {
940 0 : pItem->mbSelect = bSelect;
941 0 : if ( !pItem->maRect.IsEmpty() )
942 0 : Invalidate( pItem->maRect );
943 : }
944 :
945 0 : n++;
946 : }
947 : }
948 :
949 0 : if ( nPos >= nCurPos )
950 : {
951 : // Select all tabs from the actual position till the clicked tab
952 : // and deselect all tabs from the actual position
953 : // till the last tab
954 0 : sal_uInt16 nCount = (sal_uInt16)mpItemList->size();
955 0 : n = nCurPos;
956 0 : while ( n < nCount )
957 : {
958 0 : pItem = (*mpItemList)[ n ];
959 :
960 0 : if ( n <= nPos )
961 0 : bSelect = true;
962 : else
963 0 : bSelect = false;
964 :
965 0 : if ( pItem->mbSelect != bSelect )
966 : {
967 0 : pItem->mbSelect = bSelect;
968 0 : if ( !pItem->maRect.IsEmpty() )
969 0 : Invalidate( pItem->maRect );
970 : }
971 :
972 0 : n++;
973 : }
974 : }
975 : }
976 :
977 : // scroll the selected tab if required
978 0 : if ( bSelectTab )
979 : {
980 0 : ImplShowPage( nPos );
981 0 : Update();
982 0 : ImplSelect();
983 : }
984 : }
985 : else
986 0 : ImplShowPage( nPos );
987 0 : mbInSelect = true;
988 :
989 0 : return;
990 : }
991 : }
992 0 : else if ( rMEvt.GetClicks() == 2 )
993 : {
994 : // call double-click-handler if required
995 0 : if ( !rMEvt.GetModifier() && (!nSelId || (nSelId == mnCurPageId)) )
996 : {
997 0 : sal_uInt16 nOldCurId = mnCurPageId;
998 0 : mnCurPageId = nSelId;
999 0 : DoubleClick();
1000 : // check, as actual page could be switched inside
1001 : // the doubleclick-handler
1002 0 : if ( mnCurPageId == nSelId )
1003 0 : mnCurPageId = nOldCurId;
1004 : }
1005 :
1006 0 : return;
1007 : }
1008 : else
1009 : {
1010 0 : if ( nSelId )
1011 : {
1012 : // execute Select if not actual page
1013 0 : if ( nSelId != mnCurPageId )
1014 : {
1015 0 : sal_uInt16 nPos = GetPagePos( nSelId );
1016 0 : pItem = (*mpItemList)[ nPos ];
1017 :
1018 0 : if ( pItem->mbEnable )
1019 : {
1020 0 : if ( !pItem->mbSelect )
1021 : {
1022 : // make not valid
1023 0 : bool bUpdate = false;
1024 0 : if ( IsReallyVisible() && IsUpdateMode() )
1025 0 : bUpdate = true;
1026 :
1027 : // deselect all selected items
1028 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
1029 : {
1030 0 : pItem = (*mpItemList)[ i ];
1031 0 : if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
1032 : {
1033 0 : pItem->mbSelect = false;
1034 0 : if ( bUpdate )
1035 0 : Invalidate( pItem->maRect );
1036 : }
1037 : }
1038 : }
1039 :
1040 0 : if ( ImplDeactivatePage() )
1041 : {
1042 0 : SetCurPageId( nSelId );
1043 0 : Update();
1044 0 : ImplActivatePage();
1045 0 : ImplSelect();
1046 : }
1047 : }
1048 : else
1049 0 : ImplShowPage( nPos );
1050 0 : mbInSelect = true;
1051 : }
1052 :
1053 0 : return;
1054 : }
1055 : }
1056 :
1057 0 : Window::MouseButtonDown( rMEvt );
1058 : }
1059 :
1060 :
1061 :
1062 0 : void TabBar::MouseButtonUp( const MouseEvent& rMEvt )
1063 : {
1064 0 : mbInSelect = false;
1065 0 : Window::MouseButtonUp( rMEvt );
1066 0 : }
1067 :
1068 :
1069 :
1070 :
1071 : namespace {
1072 :
1073 : class TabBarPaintGuard
1074 : {
1075 : public:
1076 544 : explicit TabBarPaintGuard(TabBar& rParent) :
1077 : mrParent(rParent),
1078 544 : maFont(rParent.GetFont())
1079 : {
1080 : // #i36013# exclude push buttons from painting area
1081 544 : mrParent.SetClipRegion( vcl::Region(mrParent.GetPageArea()) );
1082 544 : }
1083 :
1084 544 : ~TabBarPaintGuard()
1085 544 : {
1086 : // Restore original font.
1087 544 : mrParent.SetFont(maFont);
1088 : // remove clip region
1089 544 : mrParent.SetClipRegion();
1090 544 : }
1091 : private:
1092 : TabBar& mrParent;
1093 : vcl::Font maFont;
1094 : };
1095 :
1096 544 : class TabDrawer
1097 : {
1098 : public:
1099 :
1100 544 : explicit TabDrawer(TabBar& rParent) :
1101 : mrParent(rParent),
1102 544 : mpStyleSettings(&mrParent.GetSettings().GetStyleSettings()),
1103 : maPoly(4),
1104 : mbSelected(false),
1105 : mbCustomColored(false),
1106 : mbSpecialTab(false),
1107 1088 : mbEnabled(false)
1108 : {
1109 544 : }
1110 :
1111 544 : void drawOutputAreaBorder()
1112 : {
1113 544 : WinBits nWinStyle = mrParent.GetStyle();
1114 :
1115 : // draw extra line if above and below border
1116 544 : if ( (nWinStyle & WB_BORDER) || (nWinStyle & WB_TOPBORDER) )
1117 : {
1118 544 : Size aOutputSize = mrParent.GetOutputSizePixel();
1119 544 : Rectangle aOutRect = mrParent.GetPageArea();
1120 :
1121 : // also draw border in 3D for 3D-tabs
1122 544 : if ( nWinStyle & WB_3DTAB )
1123 : {
1124 0 : mrParent.SetLineColor( mpStyleSettings->GetShadowColor() );
1125 0 : mrParent.DrawLine( Point( aOutRect.Left(), 0 ), Point( aOutputSize.Width(), 0 ) );
1126 : }
1127 :
1128 : // draw border (line above and line below)
1129 544 : mrParent.SetLineColor( mpStyleSettings->GetDarkShadowColor() );
1130 544 : mrParent.DrawLine( aOutRect.TopLeft(), Point( aOutputSize.Width()-1, aOutRect.Top() ) );
1131 : }
1132 544 : }
1133 :
1134 1506 : void drawOuterFrame()
1135 : {
1136 1506 : mrParent.DrawPolygon(maPoly);
1137 1506 : }
1138 :
1139 1119 : void drawText(const OUString& aText)
1140 : {
1141 1119 : Rectangle aRect = maRect;
1142 1119 : long nTextWidth = mrParent.GetTextWidth(aText);
1143 1119 : long nTextHeight = mrParent.GetTextHeight();
1144 1119 : Point aPos = aRect.TopLeft();
1145 1119 : aPos.X() += (aRect.getWidth() - nTextWidth) / 2;
1146 1119 : aPos.Y() += (aRect.getHeight() - nTextHeight) / 2;
1147 :
1148 1119 : if (mbEnabled)
1149 1119 : mrParent.DrawText(aPos, aText);
1150 : else
1151 : mrParent.DrawCtrlText( aPos, aText, 0, aText.getLength(),
1152 0 : (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC));
1153 1119 : }
1154 :
1155 544 : void drawOverTopBorder(bool b3DTab)
1156 : {
1157 544 : Point p1 = maPoly[0];
1158 544 : Point p2 = maPoly[3];
1159 544 : p1.X() += 1;
1160 544 : p2.X() -= 1;
1161 544 : Rectangle aDelRect(p1, p2);
1162 544 : mrParent.DrawRect(aDelRect);
1163 544 : if (b3DTab)
1164 : {
1165 0 : aDelRect.Top()--;
1166 0 : mrParent.DrawRect(aDelRect);
1167 : }
1168 544 : }
1169 :
1170 1506 : void drawTab()
1171 : {
1172 1506 : mrParent.SetLineColor(mpStyleSettings->GetDarkShadowColor());
1173 :
1174 : // set correct FillInBrush depending on status
1175 1506 : if ( mbSelected )
1176 : {
1177 : // Currently selected Tab
1178 544 : mrParent.SetFillColor( maSelectedColor );
1179 : }
1180 962 : else if ( mbCustomColored )
1181 : {
1182 0 : mrParent.SetFillColor( maCustomColor );
1183 : }
1184 : else
1185 : {
1186 962 : mrParent.SetFillColor( maUnselectedColor );
1187 : }
1188 :
1189 1506 : drawOuterFrame();
1190 1506 : }
1191 :
1192 387 : void drawPlusImage()
1193 : {
1194 387 : SvtResId id( BMP_LIST_ADD );
1195 387 : Image aPlusImg( id );
1196 : // Center the image within the bounding rectangle.
1197 387 : Size aSize = aPlusImg.GetSizePixel();
1198 387 : Point pt = maRect.TopLeft();
1199 387 : long nXOffSet = (maRect.GetWidth() - aSize.Width()) / 2;
1200 387 : long nYOffset = (maRect.GetHeight() - aSize.Height()) / 2;
1201 387 : pt += Point(nXOffSet, nYOffset);
1202 387 : pt.X() += 1;
1203 387 : mrParent.DrawImage(pt, aPlusImg);
1204 387 : }
1205 :
1206 1506 : void setRect(const Rectangle& rRect)
1207 : {
1208 1506 : maRect = rRect;
1209 :
1210 1506 : long nOffY = mrParent.GetPageArea().getY();
1211 :
1212 : // first draw filled polygon
1213 1506 : maPoly[0] = Point( rRect.Left(), nOffY );
1214 1506 : maPoly[1] = Point( rRect.Left(), rRect.Bottom() );
1215 1506 : maPoly[2] = Point( rRect.Right(), rRect.Bottom() );
1216 1506 : maPoly[3] = Point( rRect.Right(), nOffY );
1217 1506 : }
1218 :
1219 1119 : void setSelected(bool b)
1220 : {
1221 1119 : mbSelected = b;
1222 1119 : }
1223 :
1224 1119 : void setCustomColored(bool b)
1225 : {
1226 1119 : mbCustomColored = b;
1227 1119 : }
1228 :
1229 1119 : void setSpecialTab(bool b)
1230 : {
1231 1119 : mbSpecialTab = b;
1232 1119 : }
1233 :
1234 1119 : void setEnabled(bool b)
1235 : {
1236 1119 : mbEnabled = b;
1237 1119 : }
1238 :
1239 544 : void setSelectedFillColor(const Color& rColor)
1240 : {
1241 544 : maSelectedColor = rColor;
1242 544 : }
1243 :
1244 544 : void setUnselectedFillColor(const Color& rColor)
1245 : {
1246 544 : maUnselectedColor = rColor;
1247 544 : }
1248 :
1249 1119 : void setCustomColor(const Color& rColor)
1250 : {
1251 1119 : maCustomColor = rColor;
1252 1119 : }
1253 :
1254 : private:
1255 : TabBar& mrParent;
1256 : const StyleSettings* mpStyleSettings;
1257 :
1258 : Rectangle maRect;
1259 : Polygon maPoly;
1260 :
1261 : Color maSelectedColor;
1262 : Color maCustomColor;
1263 : Color maUnselectedColor;
1264 :
1265 : bool mbSelected:1;
1266 : bool mbCustomColored:1;
1267 : bool mbSpecialTab:1;
1268 : bool mbEnabled:1;
1269 : };
1270 :
1271 : }
1272 :
1273 544 : void TabBar::Paint( const Rectangle& rect )
1274 : {
1275 544 : if(IsNativeControlSupported(CTRL_WINDOW_BACKGROUND,PART_ENTIRE_CONTROL))
1276 : DrawNativeControl(CTRL_WINDOW_BACKGROUND,PART_ENTIRE_CONTROL,rect,
1277 0 : CTRL_STATE_ENABLED,ImplControlValue(0),OUString());
1278 :
1279 : // calculate items and emit
1280 544 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
1281 544 : if (!nItemCount)
1282 544 : return;
1283 :
1284 544 : ImplPrePaint();
1285 :
1286 544 : Color aFaceColor, aSelectColor, aFaceTextColor, aSelectTextColor;
1287 544 : ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
1288 :
1289 : // select font
1290 544 : vcl::Font aFont = GetFont();
1291 544 : vcl::Font aLightFont = aFont;
1292 544 : aLightFont.SetWeight( WEIGHT_NORMAL );
1293 :
1294 544 : TabBarPaintGuard aGuard(*this);
1295 544 : TabDrawer aDrawer(*this);
1296 :
1297 544 : aDrawer.setSelectedFillColor(aSelectColor);
1298 544 : aDrawer.setUnselectedFillColor(aFaceColor);
1299 :
1300 544 : aDrawer.drawOutputAreaBorder();
1301 :
1302 : // Now, start drawing the tabs.
1303 :
1304 544 : ImplTabBarItem* pItem = ImplGetLastTabBarItem(nItemCount);
1305 :
1306 544 : if (pItem && mbHasInsertTab)
1307 : {
1308 : // Draw the insert tab at the right end.
1309 387 : Rectangle aRect = ImplGetInsertTabRect(pItem);
1310 387 : aDrawer.setRect(aRect);
1311 387 : aDrawer.drawTab();
1312 387 : aDrawer.drawPlusImage();
1313 : }
1314 :
1315 544 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1316 544 : ImplTabBarItem* pCurItem = NULL;
1317 2207 : while ( pItem )
1318 : {
1319 : // emit CurrentItem last, as it covers all others
1320 1663 : if ( !pCurItem && (pItem->mnId == mnCurPageId) )
1321 : {
1322 544 : pCurItem = pItem;
1323 544 : pItem = prev();
1324 544 : if ( !pItem )
1325 518 : pItem = pCurItem;
1326 544 : continue;
1327 : }
1328 :
1329 1119 : bool bCurrent = pItem == pCurItem;
1330 :
1331 1119 : if ( !pItem->maRect.IsEmpty() )
1332 : {
1333 1119 : Rectangle aRect = pItem->maRect;
1334 1119 : bool bSelected = pItem->IsSelected(pCurItem);
1335 : // We disable custom background color in high contrast mode.
1336 1119 : bool bCustomBgColor = !pItem->IsDefaultTabBgColor() && !rStyleSettings.GetHighContrastMode();
1337 1119 : bool bSpecialTab = (pItem->mnBits & TPB_SPECIAL);
1338 1119 : bool bEnabled = pItem->mbEnable;
1339 : OUString aText = pItem->mbShort ?
1340 1119 : GetEllipsisString(pItem->maText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS) : pItem->maText;
1341 :
1342 1119 : aDrawer.setRect(aRect);
1343 1119 : aDrawer.setSelected(bSelected);
1344 1119 : aDrawer.setCustomColored(bCustomBgColor);
1345 1119 : aDrawer.setSpecialTab(bSpecialTab);
1346 1119 : aDrawer.setEnabled(bEnabled);
1347 1119 : aDrawer.setCustomColor(pItem->maTabBgColor);
1348 1119 : aDrawer.drawTab();
1349 :
1350 : // actual page is drawn using a bold font
1351 1119 : if ( bCurrent )
1352 544 : SetFont( aFont );
1353 : else
1354 575 : SetFont( aLightFont );
1355 :
1356 : // Set the correct FillInBrush depending on status
1357 :
1358 1119 : if ( bSelected )
1359 544 : SetTextColor( aSelectTextColor );
1360 575 : else if ( bCustomBgColor )
1361 0 : SetTextColor( pItem->maTabTextColor );
1362 : else
1363 575 : SetTextColor( aFaceTextColor );
1364 :
1365 : // This tab is "special", and a special tab needs a blue text.
1366 1119 : if (bSpecialTab)
1367 0 : SetTextColor(Color(COL_LIGHTBLUE));
1368 :
1369 1119 : aDrawer.drawText(aText);
1370 :
1371 1119 : if ( bCurrent )
1372 : {
1373 544 : SetLineColor();
1374 544 : SetFillColor(aSelectColor);
1375 544 : aDrawer.drawOverTopBorder(mnWinStyle & WB_3DTAB);
1376 544 : return;
1377 : }
1378 :
1379 575 : pItem = prev();
1380 : }
1381 : else
1382 : {
1383 0 : if ( bCurrent )
1384 0 : return;
1385 :
1386 0 : pItem = NULL;
1387 : }
1388 :
1389 575 : if ( !pItem )
1390 26 : pItem = pCurItem;
1391 0 : }
1392 : }
1393 :
1394 :
1395 2656 : void TabBar::Resize()
1396 : {
1397 2656 : Size aNewSize = GetOutputSizePixel();
1398 :
1399 2656 : long nSizerWidth = 0;
1400 2656 : long nButtonWidth = 0;
1401 :
1402 : // Sizer anordnen
1403 2656 : if ( mpImpl->mpSizer )
1404 : {
1405 212 : Size aSizerSize = mpImpl->mpSizer->GetSizePixel();
1406 212 : Point aNewSizerPos( mbMirrored ? 0 : (aNewSize.Width()-aSizerSize.Width()), 0 );
1407 212 : Size aNewSizerSize( aSizerSize.Width(), aNewSize.Height() );
1408 212 : mpImpl->mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize );
1409 212 : nSizerWidth = aSizerSize.Width();
1410 : }
1411 :
1412 : // order the scroll buttons
1413 2656 : long nHeight = aNewSize.Height();
1414 : // adapt font height?
1415 2656 : ImplInitSettings( true, false );
1416 :
1417 2656 : long nX = mbMirrored ? (aNewSize.Width()-nHeight) : 0;
1418 2656 : long nXDiff = mbMirrored ? -nHeight : nHeight;
1419 :
1420 2656 : Size aBtnSize( nHeight, nHeight );
1421 2656 : if ( mpFirstBtn )
1422 : {
1423 2656 : mpFirstBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1424 2656 : nX += nXDiff;
1425 2656 : nButtonWidth += nHeight;
1426 : }
1427 2656 : if ( mpPrevBtn )
1428 : {
1429 2656 : mpPrevBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1430 2656 : nX += nXDiff;
1431 2656 : nButtonWidth += nHeight;
1432 : }
1433 2656 : if ( mpNextBtn )
1434 : {
1435 2656 : mpNextBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1436 2656 : nX += nXDiff;
1437 2656 : nButtonWidth += nHeight;
1438 : }
1439 2656 : if ( mpLastBtn )
1440 : {
1441 2656 : mpLastBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1442 2656 : nX += nXDiff;
1443 2656 : nButtonWidth += nHeight;
1444 : }
1445 :
1446 : // store size
1447 2656 : maWinSize = aNewSize;
1448 :
1449 2656 : if( mbMirrored )
1450 : {
1451 2 : mnOffX = nSizerWidth;
1452 2 : mnLastOffX = maWinSize.Width() - nButtonWidth - 1;
1453 : }
1454 : else
1455 : {
1456 2654 : mnOffX = nButtonWidth;
1457 2654 : mnLastOffX = maWinSize.Width() - nSizerWidth - 1;
1458 : }
1459 :
1460 : // reformat
1461 2656 : mbSizeFormat = true;
1462 2656 : if ( IsReallyVisible() )
1463 : {
1464 1034 : if ( ImplCalcWidth() )
1465 24 : Invalidate();
1466 :
1467 1034 : ImplFormat();
1468 :
1469 : // Ensure as many tabs as possible are visible:
1470 1034 : sal_uInt16 nLastFirstPos = ImplGetLastFirstPos();
1471 1034 : if ( mnFirstPos > nLastFirstPos )
1472 : {
1473 2 : mnFirstPos = nLastFirstPos;
1474 2 : mbFormat = true;
1475 2 : Invalidate();
1476 : }
1477 : // Ensure the currently selected page is visible
1478 1034 : ImplShowPage( GetPagePos( mnCurPageId ) );
1479 :
1480 1034 : ImplFormat();
1481 : }
1482 :
1483 : // enable/disable button
1484 2656 : ImplEnableControls();
1485 2656 : }
1486 :
1487 :
1488 :
1489 0 : void TabBar::RequestHelp( const HelpEvent& rHEvt )
1490 : {
1491 0 : sal_uInt16 nItemId = GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
1492 0 : if ( nItemId )
1493 : {
1494 0 : if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1495 : {
1496 0 : OUString aStr = GetHelpText( nItemId );
1497 0 : if (!aStr.isEmpty())
1498 : {
1499 0 : Rectangle aItemRect = GetPageRect( nItemId );
1500 0 : Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1501 0 : aItemRect.Left() = aPt.X();
1502 0 : aItemRect.Top() = aPt.Y();
1503 0 : aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1504 0 : aItemRect.Right() = aPt.X();
1505 0 : aItemRect.Bottom() = aPt.Y();
1506 0 : Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1507 0 : return;
1508 0 : }
1509 : }
1510 0 : else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
1511 : {
1512 0 : OUString aHelpId( OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) );
1513 0 : if ( !aHelpId.isEmpty() )
1514 : {
1515 : // trigger Help if available
1516 0 : Help* pHelp = Application::GetHelp();
1517 0 : if ( pHelp )
1518 0 : pHelp->Start( aHelpId, this );
1519 0 : return;
1520 0 : }
1521 : }
1522 :
1523 : // show text for quick- or balloon-help
1524 : // if this is isolated or not fully visible
1525 0 : if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
1526 : {
1527 0 : sal_uInt16 nPos = GetPagePos( nItemId );
1528 0 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
1529 0 : if ( pItem->mbShort || (pItem->maRect.Right() - 5 > mnLastOffX) )
1530 : {
1531 0 : Rectangle aItemRect = GetPageRect( nItemId );
1532 0 : Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1533 0 : aItemRect.Left() = aPt.X();
1534 0 : aItemRect.Top() = aPt.Y();
1535 0 : aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1536 0 : aItemRect.Right() = aPt.X();
1537 0 : aItemRect.Bottom() = aPt.Y();
1538 0 : OUString aStr = (*mpItemList)[ nPos ]->maText;
1539 0 : if (!aStr.isEmpty())
1540 : {
1541 0 : if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1542 0 : Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1543 : else
1544 0 : Help::ShowQuickHelp( this, aItemRect, aStr );
1545 0 : return;
1546 0 : }
1547 : }
1548 : }
1549 : }
1550 :
1551 0 : Window::RequestHelp( rHEvt );
1552 : }
1553 :
1554 :
1555 :
1556 2708 : void TabBar::StateChanged( StateChangedType nType )
1557 : {
1558 2708 : Window::StateChanged( nType );
1559 :
1560 2708 : if ( nType == StateChangedType::INITSHOW )
1561 : {
1562 926 : if ( (mbSizeFormat || mbFormat) && !mpItemList->empty() )
1563 918 : ImplFormat();
1564 : }
1565 1782 : else if ( (nType == StateChangedType::ZOOM) ||
1566 : (nType == StateChangedType::CONTROLFONT) )
1567 : {
1568 0 : ImplInitSettings( true, false );
1569 0 : Invalidate();
1570 : }
1571 1782 : else if ( nType == StateChangedType::CONTROLFOREGROUND )
1572 0 : Invalidate();
1573 1782 : else if ( nType == StateChangedType::CONTROLBACKGROUND )
1574 : {
1575 0 : ImplInitSettings( false, true );
1576 0 : Invalidate();
1577 : }
1578 1782 : else if ( nType == StateChangedType::MIRRORING )
1579 : {
1580 : // reacts on calls of EnableRTL, have to mirror all child controls
1581 546 : if( mpFirstBtn ) mpFirstBtn->EnableRTL( IsRTLEnabled() );
1582 546 : if( mpPrevBtn ) mpPrevBtn->EnableRTL( IsRTLEnabled() );
1583 546 : if( mpNextBtn ) mpNextBtn->EnableRTL( IsRTLEnabled() );
1584 546 : if( mpLastBtn ) mpLastBtn->EnableRTL( IsRTLEnabled() );
1585 546 : if( mpImpl->mpSizer ) mpImpl->mpSizer->EnableRTL( IsRTLEnabled() );
1586 546 : if( mpEdit ) mpEdit->EnableRTL( IsRTLEnabled() );
1587 : }
1588 2708 : }
1589 :
1590 :
1591 :
1592 46 : void TabBar::DataChanged( const DataChangedEvent& rDCEvt )
1593 : {
1594 46 : Window::DataChanged( rDCEvt );
1595 :
1596 138 : if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1597 138 : (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1598 92 : ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1599 46 : (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1600 : {
1601 46 : ImplInitSettings( true, true );
1602 46 : Invalidate();
1603 : }
1604 46 : }
1605 :
1606 :
1607 :
1608 0 : void TabBar::ImplSelect()
1609 : {
1610 0 : Select();
1611 :
1612 0 : CallEventListeners( VCLEVENT_TABBAR_PAGESELECTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1613 0 : }
1614 :
1615 :
1616 :
1617 0 : void TabBar::Select()
1618 : {
1619 0 : maSelectHdl.Call( this );
1620 0 : }
1621 :
1622 :
1623 :
1624 0 : void TabBar::DoubleClick()
1625 : {
1626 0 : }
1627 :
1628 :
1629 :
1630 0 : void TabBar::Split()
1631 : {
1632 0 : maSplitHdl.Call( this );
1633 0 : }
1634 :
1635 :
1636 :
1637 0 : void TabBar::ImplActivatePage()
1638 : {
1639 0 : ActivatePage();
1640 :
1641 0 : CallEventListeners( VCLEVENT_TABBAR_PAGEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1642 0 : }
1643 :
1644 :
1645 :
1646 0 : void TabBar::ActivatePage()
1647 : {
1648 0 : }
1649 :
1650 :
1651 :
1652 0 : bool TabBar::ImplDeactivatePage()
1653 : {
1654 0 : bool nRet = DeactivatePage();
1655 :
1656 0 : CallEventListeners( VCLEVENT_TABBAR_PAGEDEACTIVATED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(mnCurPageId)) );
1657 :
1658 0 : return nRet;
1659 : }
1660 :
1661 544 : void TabBar::ImplPrePaint()
1662 : {
1663 544 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
1664 544 : if (!nItemCount)
1665 544 : return;
1666 :
1667 : ImplTabBarItem* pItem;
1668 :
1669 : // tabbar should be formatted
1670 544 : ImplFormat();
1671 :
1672 : // assure the actual tabpage becomes visible at first format
1673 544 : if ( mbFirstFormat )
1674 : {
1675 385 : mbFirstFormat = false;
1676 :
1677 385 : if ( mnCurPageId && (mnFirstPos == 0) && !mbDropPos )
1678 : {
1679 385 : pItem = (*mpItemList)[ GetPagePos( mnCurPageId ) ];
1680 385 : if ( pItem->maRect.IsEmpty() )
1681 : {
1682 : // set mbDropPos (or misuse) to prevent Invalidate()
1683 0 : mbDropPos = true;
1684 0 : SetFirstPageId( mnCurPageId );
1685 0 : mbDropPos = false;
1686 0 : if ( mnFirstPos != 0 )
1687 0 : ImplFormat();
1688 : }
1689 : }
1690 : }
1691 : }
1692 :
1693 544 : ImplTabBarItem* TabBar::ImplGetLastTabBarItem( sal_uInt16 nItemCount )
1694 : {
1695 : // find last visible entry
1696 544 : sal_uInt16 n = mnFirstPos+1;
1697 544 : if ( n >= nItemCount )
1698 236 : n = nItemCount-1;
1699 544 : ImplTabBarItem* pItem = seek( n );
1700 1899 : while ( pItem )
1701 : {
1702 811 : if ( !pItem->maRect.IsEmpty() )
1703 : {
1704 811 : n++;
1705 811 : pItem = next();
1706 : }
1707 : else
1708 0 : break;
1709 : }
1710 :
1711 : // draw all tabs (from back to front and actual last)
1712 544 : if ( pItem )
1713 0 : n--;
1714 544 : else if ( n >= nItemCount )
1715 544 : n = nItemCount-1;
1716 544 : pItem = seek( n );
1717 544 : return pItem;
1718 : }
1719 :
1720 387 : Rectangle TabBar::ImplGetInsertTabRect(ImplTabBarItem* pItem) const
1721 : {
1722 387 : if (mbHasInsertTab && pItem)
1723 : {
1724 387 : Rectangle aInsTabRect = pItem->maRect;
1725 387 : if ( !mbMirrored )
1726 386 : aInsTabRect.setX(aInsTabRect.getX() + aInsTabRect.getWidth());
1727 : else
1728 1 : aInsTabRect.setX(aInsTabRect.getX());
1729 387 : aInsTabRect.setWidth(32);
1730 387 : return aInsTabRect;
1731 : }
1732 0 : return Rectangle();
1733 : }
1734 :
1735 :
1736 :
1737 0 : bool TabBar::DeactivatePage()
1738 : {
1739 0 : return true;
1740 : }
1741 :
1742 :
1743 :
1744 0 : bool TabBar::StartRenaming()
1745 : {
1746 0 : return true;
1747 : }
1748 :
1749 :
1750 :
1751 0 : TabBarAllowRenamingReturnCode TabBar::AllowRenaming()
1752 : {
1753 0 : return TABBAR_RENAMING_YES;
1754 : }
1755 :
1756 :
1757 :
1758 0 : void TabBar::EndRenaming()
1759 : {
1760 0 : }
1761 :
1762 :
1763 :
1764 4 : void TabBar::Mirror()
1765 : {
1766 :
1767 4 : }
1768 :
1769 :
1770 :
1771 4816 : void TabBar::InsertPage( sal_uInt16 nPageId, const OUString& rText,
1772 : TabBarPageBits nBits, sal_uInt16 nPos )
1773 : {
1774 : DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" );
1775 : DBG_ASSERT( GetPagePos( nPageId ) == PAGE_NOT_FOUND,
1776 : "TabBar::InsertPage(): PageId already exists" );
1777 : DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" );
1778 :
1779 : // create PageItem and insert in the item list
1780 4816 : ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits );
1781 4816 : if ( nPos < mpItemList->size() ) {
1782 0 : ImplTabBarList::iterator it = mpItemList->begin();
1783 0 : ::std::advance( it, nPos );
1784 0 : mpItemList->insert( it, pItem );
1785 : } else {
1786 4816 : mpItemList->push_back( pItem );
1787 : }
1788 4816 : mbSizeFormat = true;
1789 :
1790 : // set CurPageId if required
1791 4816 : if ( !mnCurPageId )
1792 2920 : mnCurPageId = nPageId;
1793 :
1794 : // redraw bar
1795 4816 : if ( IsReallyVisible() && IsUpdateMode() )
1796 698 : Invalidate();
1797 :
1798 4816 : CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1799 4816 : }
1800 :
1801 :
1802 :
1803 6138 : Color TabBar::GetTabBgColor( sal_uInt16 nPageId ) const
1804 : {
1805 6138 : sal_uInt16 nPos = GetPagePos( nPageId );
1806 :
1807 6138 : if ( nPos != PAGE_NOT_FOUND )
1808 6132 : return (*mpItemList)[ nPos ]->maTabBgColor;
1809 : else
1810 6 : return Color( COL_AUTO );
1811 : }
1812 :
1813 2 : void TabBar::SetTabBgColor( sal_uInt16 nPageId, const Color& aTabBgColor )
1814 : {
1815 2 : sal_uInt16 nPos = GetPagePos( nPageId );
1816 : ImplTabBarItem* pItem;
1817 2 : if ( nPos != PAGE_NOT_FOUND )
1818 : {
1819 2 : pItem = (*mpItemList)[ nPos ];
1820 2 : if ( aTabBgColor != Color( COL_AUTO ) )
1821 : {
1822 2 : pItem->maTabBgColor = aTabBgColor;
1823 2 : if ( aTabBgColor.GetLuminance() <= 128 ) //Do not use aTabBgColor.IsDark(), because that threshold is way too low...
1824 0 : pItem->maTabTextColor = Color( COL_WHITE );
1825 : else
1826 2 : pItem->maTabTextColor = Color( COL_BLACK );
1827 : }
1828 : else
1829 : {
1830 0 : pItem->maTabBgColor = Color( COL_AUTO );
1831 0 : pItem->maTabTextColor = Color( COL_AUTO );
1832 : }
1833 : }
1834 2 : }
1835 :
1836 :
1837 :
1838 0 : void TabBar::RemovePage( sal_uInt16 nPageId )
1839 : {
1840 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1841 :
1842 : // does item exist
1843 0 : if ( nPos != PAGE_NOT_FOUND )
1844 : {
1845 0 : if ( mnCurPageId == nPageId )
1846 0 : mnCurPageId = 0;
1847 :
1848 : // check if first visibale page should be moved
1849 0 : if ( mnFirstPos > nPos )
1850 0 : mnFirstPos--;
1851 :
1852 : // delete item data
1853 0 : ImplTabBarList::iterator it = mpItemList->begin();
1854 0 : ::std::advance( it, nPos );
1855 0 : delete *it;
1856 0 : mpItemList->erase( it );
1857 :
1858 : // redraw bar
1859 0 : if ( IsReallyVisible() && IsUpdateMode() )
1860 0 : Invalidate();
1861 :
1862 0 : CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1863 : }
1864 0 : }
1865 :
1866 :
1867 :
1868 0 : void TabBar::MovePage( sal_uInt16 nPageId, sal_uInt16 nNewPos )
1869 : {
1870 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1871 0 : Pair aPair( nPos, nNewPos );
1872 :
1873 0 : if ( nPos < nNewPos )
1874 0 : nNewPos--;
1875 :
1876 0 : if ( nPos == nNewPos )
1877 0 : return;
1878 :
1879 : // does item exit
1880 0 : if ( nPos != PAGE_NOT_FOUND )
1881 : {
1882 : // move tabbar item in the list
1883 0 : ImplTabBarList::iterator it = mpItemList->begin();
1884 0 : ::std::advance( it, nPos );
1885 0 : ImplTabBarItem* pItem = *it;
1886 0 : mpItemList->erase( it );
1887 0 : if ( nNewPos < mpItemList->size() ) {
1888 0 : it = mpItemList->begin();
1889 0 : ::std::advance( it, nNewPos );
1890 0 : mpItemList->insert( it, pItem );
1891 : } else {
1892 0 : mpItemList->push_back( pItem );
1893 : }
1894 :
1895 : // redraw bar
1896 0 : if ( IsReallyVisible() && IsUpdateMode() )
1897 0 : Invalidate();
1898 :
1899 0 : CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, (void*) &aPair );
1900 : }
1901 : }
1902 :
1903 :
1904 :
1905 2374 : void TabBar::Clear()
1906 : {
1907 : // delete all items
1908 5620 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1909 3246 : delete (*mpItemList)[ i ];
1910 : }
1911 2374 : mpItemList->clear();
1912 :
1913 : // remove items from the list
1914 2374 : mbSizeFormat = true;
1915 2374 : mnCurPageId = 0;
1916 2374 : mnFirstPos = 0;
1917 2374 : maCurrentItemList = 0;
1918 :
1919 : // redraw bar
1920 2374 : if ( IsReallyVisible() && IsUpdateMode() )
1921 306 : Invalidate();
1922 :
1923 2374 : CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(PAGE_NOT_FOUND)) );
1924 2374 : }
1925 :
1926 :
1927 :
1928 0 : bool TabBar::IsPageEnabled( sal_uInt16 nPageId ) const
1929 : {
1930 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1931 :
1932 0 : if ( nPos != PAGE_NOT_FOUND )
1933 0 : return (*mpItemList)[ nPos ]->mbEnable;
1934 : else
1935 0 : return false;
1936 : }
1937 :
1938 :
1939 :
1940 1760 : void TabBar::SetPageBits( sal_uInt16 nPageId, TabBarPageBits nBits )
1941 : {
1942 1760 : sal_uInt16 nPos = GetPagePos( nPageId );
1943 :
1944 1760 : if ( nPos != PAGE_NOT_FOUND )
1945 : {
1946 1760 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
1947 :
1948 1760 : if ( pItem->mnBits != nBits )
1949 : {
1950 0 : pItem->mnBits = nBits;
1951 :
1952 : // redraw bar
1953 0 : if ( IsReallyVisible() && IsUpdateMode() )
1954 0 : Invalidate( pItem->maRect );
1955 : }
1956 : }
1957 1760 : }
1958 :
1959 :
1960 :
1961 0 : TabBarPageBits TabBar::GetPageBits( sal_uInt16 nPageId ) const
1962 : {
1963 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1964 :
1965 0 : if ( nPos != PAGE_NOT_FOUND )
1966 0 : return (*mpItemList)[ nPos ]->mnBits;
1967 : else
1968 0 : return sal_False;
1969 : }
1970 :
1971 :
1972 :
1973 5524 : sal_uInt16 TabBar::GetPageCount() const
1974 : {
1975 5524 : return (sal_uInt16)mpItemList->size();
1976 : }
1977 :
1978 :
1979 :
1980 4980 : sal_uInt16 TabBar::GetPageId( sal_uInt16 nPos ) const
1981 : {
1982 4980 : return ( nPos < mpItemList->size() ) ? (*mpItemList)[ nPos ]->mnId : 0;
1983 : }
1984 :
1985 :
1986 :
1987 32788 : sal_uInt16 TabBar::GetPagePos( sal_uInt16 nPageId ) const
1988 : {
1989 45028 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1990 44978 : if ( (*mpItemList)[ i ]->mnId == nPageId ) {
1991 32738 : return sal_uInt16( i );
1992 : }
1993 : }
1994 50 : return PAGE_NOT_FOUND;
1995 : }
1996 :
1997 :
1998 :
1999 0 : sal_uInt16 TabBar::GetPageId( const Point& rPos, bool bCheckInsTab ) const
2000 : {
2001 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
2002 : {
2003 0 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
2004 0 : if ( pItem->maRect.IsInside( rPos ) )
2005 0 : return pItem->mnId;
2006 : }
2007 :
2008 0 : if (bCheckInsTab && mbHasInsertTab && !mpItemList->empty())
2009 : {
2010 0 : ImplTabBarItem* pItem = mpItemList->back();
2011 0 : if (ImplGetInsertTabRect(pItem).IsInside(rPos))
2012 0 : return INSERT_TAB_POS;
2013 : }
2014 :
2015 0 : return 0;
2016 : }
2017 :
2018 :
2019 :
2020 0 : Rectangle TabBar::GetPageRect( sal_uInt16 nPageId ) const
2021 : {
2022 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2023 :
2024 0 : if ( nPos != PAGE_NOT_FOUND )
2025 0 : return (*mpItemList)[ nPos ]->maRect;
2026 : else
2027 0 : return Rectangle();
2028 : }
2029 :
2030 :
2031 :
2032 8164 : void TabBar::SetCurPageId( sal_uInt16 nPageId )
2033 : {
2034 8164 : sal_uInt16 nPos = GetPagePos( nPageId );
2035 :
2036 : // do nothing if item does not exit
2037 8164 : if ( nPos != PAGE_NOT_FOUND )
2038 : {
2039 : // do nothing if the actual page did not change
2040 8164 : if ( nPageId == mnCurPageId )
2041 16188 : return;
2042 :
2043 : // make invalide
2044 140 : bool bUpdate = false;
2045 140 : if ( IsReallyVisible() && IsUpdateMode() )
2046 132 : bUpdate = true;
2047 :
2048 140 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2049 : ImplTabBarItem* pOldItem;
2050 :
2051 140 : if ( mnCurPageId )
2052 140 : pOldItem = (*mpItemList)[ GetPagePos( mnCurPageId ) ];
2053 : else
2054 0 : pOldItem = NULL;
2055 :
2056 : // deselect previous page if page was not selected, if this is the
2057 : // only selected page
2058 140 : if ( !pItem->mbSelect && pOldItem )
2059 : {
2060 140 : sal_uInt16 nSelPageCount = GetSelectPageCount();
2061 140 : if ( nSelPageCount == 1 )
2062 58 : pOldItem->mbSelect = false;
2063 140 : pItem->mbSelect = true;
2064 : }
2065 :
2066 140 : mnCurPageId = nPageId;
2067 140 : mbFormat = true;
2068 :
2069 : // assure the actual page becomes visible
2070 140 : if ( IsReallyVisible() )
2071 : {
2072 132 : if ( nPos < mnFirstPos )
2073 0 : SetFirstPageId( nPageId );
2074 : else
2075 : {
2076 : // calculate visible width
2077 132 : long nWidth = mnLastOffX;
2078 132 : if ( nWidth > ADDNEWPAGE_AREAWIDTH )
2079 132 : nWidth -= ADDNEWPAGE_AREAWIDTH;
2080 :
2081 132 : if ( pItem->maRect.IsEmpty() )
2082 80 : ImplFormat();
2083 :
2084 444 : while ( (mbMirrored ? (pItem->maRect.Left() < mnOffX) : (pItem->maRect.Right() > nWidth)) ||
2085 150 : pItem->maRect.IsEmpty() )
2086 : {
2087 32 : sal_uInt16 nNewPos = mnFirstPos+1;
2088 : // assure at least the actual tabpages are visible as first tabpage
2089 32 : if ( nNewPos >= nPos )
2090 : {
2091 2 : SetFirstPageId( nPageId );
2092 2 : break;
2093 : }
2094 : else
2095 30 : SetFirstPageId( GetPageId( nNewPos ) );
2096 30 : ImplFormat();
2097 : // abort if first page is not forwarded
2098 30 : if ( nNewPos != mnFirstPos )
2099 0 : break;
2100 : }
2101 : }
2102 : }
2103 :
2104 : // redraw bar
2105 140 : if ( bUpdate )
2106 : {
2107 132 : Invalidate( pItem->maRect );
2108 132 : if ( pOldItem )
2109 132 : Invalidate( pOldItem->maRect );
2110 : }
2111 : }
2112 : }
2113 :
2114 :
2115 :
2116 0 : void TabBar::MakeVisible( sal_uInt16 nPageId )
2117 : {
2118 0 : if ( !IsReallyVisible() )
2119 0 : return;
2120 :
2121 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2122 :
2123 : // do nothing if item does not exist
2124 0 : if ( nPos != PAGE_NOT_FOUND )
2125 : {
2126 0 : if ( nPos < mnFirstPos )
2127 0 : SetFirstPageId( nPageId );
2128 : else
2129 : {
2130 0 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2131 :
2132 : // calculate visible area
2133 0 : long nWidth = mnLastOffX;
2134 :
2135 0 : if ( mbFormat || pItem->maRect.IsEmpty() )
2136 : {
2137 0 : mbFormat = true;
2138 0 : ImplFormat();
2139 : }
2140 :
2141 0 : while ( (pItem->maRect.Right() > nWidth) ||
2142 0 : pItem->maRect.IsEmpty() )
2143 : {
2144 0 : sal_uInt16 nNewPos = mnFirstPos+1;
2145 : // assure at least the actual tabpages are visible as first tabpage
2146 0 : if ( nNewPos >= nPos )
2147 : {
2148 0 : SetFirstPageId( nPageId );
2149 0 : break;
2150 : }
2151 : else
2152 0 : SetFirstPageId( GetPageId( nNewPos ) );
2153 0 : ImplFormat();
2154 : // abort if first page is not forwarded
2155 0 : if ( nNewPos != mnFirstPos )
2156 0 : break;
2157 : }
2158 : }
2159 : }
2160 : }
2161 :
2162 :
2163 :
2164 44 : void TabBar::SetFirstPageId( sal_uInt16 nPageId )
2165 : {
2166 44 : sal_uInt16 nPos = GetPagePos( nPageId );
2167 :
2168 : // return false if item does not exist
2169 44 : if ( nPos != PAGE_NOT_FOUND )
2170 : {
2171 32 : if ( nPos != mnFirstPos )
2172 : {
2173 : // assure as much pages are visible as possible
2174 32 : ImplFormat();
2175 32 : sal_uInt16 nLastFirstPos = ImplGetLastFirstPos();
2176 : sal_uInt16 nNewPos;
2177 32 : if ( nPos > nLastFirstPos )
2178 0 : nNewPos = nLastFirstPos;
2179 : else
2180 32 : nNewPos = nPos;
2181 :
2182 32 : if ( nNewPos != mnFirstPos )
2183 : {
2184 32 : mnFirstPos = nNewPos;
2185 32 : mbFormat = true;
2186 :
2187 : // redraw bar (attention: check mbDropPos,
2188 : // as if this flag was set, we do not re-paint immediately
2189 32 : if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos )
2190 32 : Invalidate();
2191 : }
2192 : }
2193 : }
2194 44 : }
2195 :
2196 :
2197 :
2198 918 : void TabBar::SelectPage( sal_uInt16 nPageId, bool bSelect )
2199 : {
2200 918 : sal_uInt16 nPos = GetPagePos( nPageId );
2201 :
2202 918 : if ( nPos != PAGE_NOT_FOUND )
2203 : {
2204 916 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2205 :
2206 916 : if ( pItem->mbSelect != bSelect )
2207 : {
2208 656 : pItem->mbSelect = bSelect;
2209 :
2210 : // redraw bar
2211 656 : if ( IsReallyVisible() && IsUpdateMode() )
2212 286 : Invalidate( pItem->maRect );
2213 : }
2214 : }
2215 918 : }
2216 :
2217 :
2218 :
2219 140 : sal_uInt16 TabBar::GetSelectPageCount() const
2220 : {
2221 140 : sal_uInt16 nSelected = 0;
2222 554 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
2223 : {
2224 414 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
2225 414 : if ( pItem->mbSelect )
2226 58 : nSelected++;
2227 : }
2228 :
2229 140 : return nSelected;
2230 : }
2231 :
2232 :
2233 :
2234 6246 : bool TabBar::IsPageSelected( sal_uInt16 nPageId ) const
2235 : {
2236 6246 : sal_uInt16 nPos = GetPagePos( nPageId );
2237 6246 : if ( nPos != PAGE_NOT_FOUND )
2238 6240 : return (*mpItemList)[ nPos ]->mbSelect;
2239 : else
2240 6 : return false;
2241 : }
2242 :
2243 :
2244 :
2245 0 : bool TabBar::StartEditMode( sal_uInt16 nPageId )
2246 : {
2247 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2248 0 : if ( mpEdit || (nPos == PAGE_NOT_FOUND) || (mnLastOffX < 8) )
2249 0 : return false;
2250 :
2251 0 : mnEditId = nPageId;
2252 0 : if ( StartRenaming() )
2253 : {
2254 0 : ImplShowPage( nPos );
2255 0 : ImplFormat();
2256 0 : Update();
2257 :
2258 0 : mpEdit = new TabBarEdit( this, WB_CENTER );
2259 0 : Rectangle aRect = GetPageRect( mnEditId );
2260 0 : long nX = aRect.Left();
2261 0 : long nWidth = aRect.GetWidth();
2262 0 : if ( mnEditId != GetCurPageId() )
2263 0 : nX += 1;
2264 0 : if ( nX+nWidth > mnLastOffX )
2265 0 : nWidth = mnLastOffX-nX;
2266 0 : if ( nWidth < 3 )
2267 : {
2268 0 : nX = aRect.Left();
2269 0 : nWidth = aRect.GetWidth();
2270 : }
2271 0 : mpEdit->SetText( GetPageText( mnEditId ) );
2272 0 : mpEdit->setPosSizePixel( nX, aRect.Top()+mnOffY+1, nWidth, aRect.GetHeight()-3 );
2273 0 : vcl::Font aFont = GetPointFont();
2274 0 : Color aForegroundColor;
2275 0 : Color aBackgroundColor;
2276 0 : Color aFaceColor;
2277 0 : Color aSelectColor;
2278 0 : Color aFaceTextColor;
2279 0 : Color aSelectTextColor;
2280 0 : ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
2281 0 : if ( mnEditId != GetCurPageId() )
2282 0 : aFont.SetWeight( WEIGHT_LIGHT );
2283 0 : if ( IsPageSelected( mnEditId ) || (mnEditId == GetCurPageId()) )
2284 : {
2285 0 : aForegroundColor = aSelectTextColor;
2286 0 : aBackgroundColor = aSelectColor;
2287 : }
2288 : else
2289 : {
2290 0 : aForegroundColor = aFaceTextColor;
2291 0 : aBackgroundColor = aFaceColor;
2292 : }
2293 0 : if ( GetPageBits( mnEditId ) & TPB_SPECIAL )
2294 0 : aForegroundColor = Color( COL_LIGHTBLUE );
2295 0 : mpEdit->SetControlFont( aFont );
2296 0 : mpEdit->SetControlForeground( aForegroundColor );
2297 0 : mpEdit->SetControlBackground( aBackgroundColor );
2298 0 : mpEdit->GrabFocus();
2299 0 : mpEdit->SetSelection( Selection( 0, mpEdit->GetText().getLength() ) );
2300 0 : mpEdit->Show();
2301 0 : return true;
2302 : }
2303 : else
2304 : {
2305 0 : mnEditId = 0;
2306 0 : return false;
2307 : }
2308 : }
2309 :
2310 :
2311 :
2312 2040 : void TabBar::EndEditMode( bool bCancel )
2313 : {
2314 2040 : if ( mpEdit )
2315 : {
2316 : // call hdl
2317 0 : bool bEnd = true;
2318 0 : mbEditCanceled = bCancel;
2319 0 : maEditText = mpEdit->GetText();
2320 0 : mpEdit->SetPostEvent();
2321 0 : if ( !bCancel )
2322 : {
2323 0 : TabBarAllowRenamingReturnCode nAllowRenaming = AllowRenaming();
2324 0 : if ( nAllowRenaming == TABBAR_RENAMING_YES )
2325 0 : SetPageText( mnEditId, maEditText );
2326 0 : else if ( nAllowRenaming == TABBAR_RENAMING_NO )
2327 0 : bEnd = false;
2328 : else // nAllowRenaming == TABBAR_RENAMING_CANCEL
2329 0 : mbEditCanceled = true;
2330 : }
2331 :
2332 : // renaming not allowed, than reset edit data
2333 0 : if ( !bEnd )
2334 : {
2335 0 : mpEdit->ResetPostEvent();
2336 0 : mpEdit->GrabFocus();
2337 : }
2338 : else
2339 : {
2340 : // close edit and call end hdl
2341 0 : delete mpEdit;
2342 0 : mpEdit = NULL;
2343 0 : EndRenaming();
2344 0 : mnEditId = 0;
2345 : }
2346 :
2347 : // reset
2348 0 : maEditText = OUString();
2349 0 : mbEditCanceled = false;
2350 : }
2351 2040 : }
2352 :
2353 :
2354 :
2355 2304 : void TabBar::SetMirrored(bool bMirrored)
2356 : {
2357 2304 : if( mbMirrored != bMirrored )
2358 : {
2359 4 : mbMirrored = bMirrored;
2360 4 : mbSizeFormat = true;
2361 4 : ImplInitControls(); // for button images
2362 4 : Resize(); // recalculates control positions
2363 4 : Mirror();
2364 : }
2365 2304 : }
2366 :
2367 2304 : void TabBar::SetEffectiveRTL( bool bRTL )
2368 : {
2369 2304 : SetMirrored( bRTL != Application::GetSettings().GetLayoutRTL() );
2370 2304 : }
2371 :
2372 0 : bool TabBar::IsEffectiveRTL() const
2373 : {
2374 0 : return IsMirrored() != Application::GetSettings().GetLayoutRTL();
2375 : }
2376 :
2377 :
2378 :
2379 372 : void TabBar::SetMaxPageWidth( long nMaxWidth )
2380 : {
2381 372 : if ( mnMaxPageWidth != nMaxWidth )
2382 : {
2383 372 : mnMaxPageWidth = nMaxWidth;
2384 372 : mbSizeFormat = true;
2385 :
2386 : // redraw bar
2387 372 : if ( IsReallyVisible() && IsUpdateMode() )
2388 0 : Invalidate();
2389 : }
2390 372 : }
2391 :
2392 :
2393 :
2394 0 : void TabBar::SetPageText( sal_uInt16 nPageId, const OUString& rText )
2395 : {
2396 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2397 0 : if ( nPos != PAGE_NOT_FOUND )
2398 : {
2399 0 : (*mpItemList)[ nPos ]->maText = rText;
2400 0 : mbSizeFormat = true;
2401 :
2402 : // redraw bar
2403 0 : if ( IsReallyVisible() && IsUpdateMode() )
2404 0 : Invalidate();
2405 :
2406 0 : CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
2407 : }
2408 0 : }
2409 :
2410 :
2411 :
2412 7957 : OUString TabBar::GetPageText( sal_uInt16 nPageId ) const
2413 : {
2414 7957 : sal_uInt16 nPos = GetPagePos( nPageId );
2415 7957 : if ( nPos != PAGE_NOT_FOUND )
2416 7933 : return (*mpItemList)[ nPos ]->maText;
2417 24 : return OUString();
2418 : }
2419 :
2420 :
2421 :
2422 0 : OUString TabBar::GetHelpText( sal_uInt16 nPageId ) const
2423 : {
2424 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2425 0 : if ( nPos != PAGE_NOT_FOUND )
2426 : {
2427 0 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2428 0 : if (pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty())
2429 : {
2430 0 : Help* pHelp = Application::GetHelp();
2431 0 : if ( pHelp )
2432 0 : pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
2433 : }
2434 :
2435 0 : return pItem->maHelpText;
2436 : }
2437 0 : return OUString();
2438 : }
2439 :
2440 :
2441 :
2442 0 : OString TabBar::GetHelpId( sal_uInt16 nPageId ) const
2443 : {
2444 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2445 0 : OString aRet;
2446 0 : if ( nPos != PAGE_NOT_FOUND )
2447 0 : return (*mpItemList)[ nPos ]->maHelpId;
2448 0 : return aRet;
2449 : }
2450 :
2451 :
2452 :
2453 0 : bool TabBar::StartDrag( const CommandEvent& rCEvt, vcl::Region& rRegion )
2454 : {
2455 0 : if ( !(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != COMMAND_STARTDRAG) )
2456 0 : return false;
2457 :
2458 : // Check if the clicked page was selected. If this is not the case
2459 : // set it as actual entry. We check for this only at a mouse action
2460 : // if Drag and Drop can be triggered from the keyboard.
2461 : // We only do this, if Select() was not triggered, as the Select()
2462 : // could have scrolled the area
2463 0 : if ( rCEvt.IsMouseEvent() && !mbInSelect )
2464 : {
2465 0 : sal_uInt16 nSelId = GetPageId( rCEvt.GetMousePosPixel() );
2466 :
2467 : // do not start dragging if no entry was clicked
2468 0 : if ( !nSelId )
2469 0 : return false;
2470 :
2471 : // check if page was selected. If not set it as actual
2472 : // page and call Select()
2473 0 : if ( !IsPageSelected( nSelId ) )
2474 : {
2475 0 : if ( ImplDeactivatePage() )
2476 : {
2477 0 : SetCurPageId( nSelId );
2478 0 : Update();
2479 0 : ImplActivatePage();
2480 0 : ImplSelect();
2481 : }
2482 : else
2483 0 : return false;
2484 : }
2485 : }
2486 0 : mbInSelect = false;
2487 :
2488 0 : vcl::Region aRegion;
2489 :
2490 : // assign region
2491 0 : rRegion = aRegion;
2492 :
2493 0 : return true;
2494 : }
2495 :
2496 :
2497 :
2498 0 : sal_uInt16 TabBar::ShowDropPos( const Point& rPos )
2499 : {
2500 : ImplTabBarItem* pItem;
2501 : sal_uInt16 nDropId;
2502 : sal_uInt16 nNewDropPos;
2503 0 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
2504 0 : short nScroll = 0;
2505 :
2506 0 : if ( rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF )
2507 : {
2508 0 : pItem = (*mpItemList)[ mpItemList->size()-1 ];
2509 0 : if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) )
2510 0 : nNewDropPos = (sal_uInt16)mpItemList->size();
2511 : else
2512 : {
2513 0 : nNewDropPos = mnFirstPos+1;
2514 0 : nScroll = 1;
2515 : }
2516 : }
2517 0 : else if ( (rPos.X() <= mnOffX) ||
2518 0 : (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)) )
2519 : {
2520 0 : if ( mnFirstPos )
2521 : {
2522 0 : nNewDropPos = mnFirstPos;
2523 0 : nScroll = -1;
2524 : }
2525 : else
2526 0 : nNewDropPos = 0;
2527 : }
2528 : else
2529 : {
2530 0 : nDropId = GetPageId( rPos );
2531 0 : if ( nDropId )
2532 : {
2533 0 : nNewDropPos = GetPagePos( nDropId );
2534 0 : if ( mnFirstPos && (nNewDropPos == mnFirstPos-1) )
2535 0 : nScroll = -1;
2536 : }
2537 : else
2538 0 : nNewDropPos = nItemCount;
2539 : }
2540 :
2541 0 : if ( mbDropPos && (nNewDropPos == mnDropPos) && !nScroll )
2542 0 : return mnDropPos;
2543 :
2544 0 : if ( mbDropPos )
2545 0 : HideDropPos();
2546 0 : mbDropPos = true;
2547 0 : mnDropPos = nNewDropPos;
2548 :
2549 0 : if ( nScroll )
2550 : {
2551 0 : sal_uInt16 nOldFirstPos = mnFirstPos;
2552 0 : SetFirstPageId( GetPageId( mnFirstPos+nScroll ) );
2553 :
2554 : // draw immediately, as Paint not possible during Drag and Drop
2555 0 : if ( nOldFirstPos != mnFirstPos )
2556 : {
2557 0 : Rectangle aRect( mnOffX, 0, mnLastOffX, maWinSize.Height() );
2558 0 : SetFillColor( GetBackground().GetColor() );
2559 0 : DrawRect( aRect );
2560 0 : Paint( aRect );
2561 : }
2562 : }
2563 :
2564 : // draw drop position arrows
2565 0 : Color aBlackColor( COL_BLACK );
2566 : long nX;
2567 0 : long nY = (maWinSize.Height()/2)-1;
2568 0 : sal_uInt16 nCurPos = GetPagePos( mnCurPageId );
2569 :
2570 0 : SetLineColor( aBlackColor );
2571 0 : if ( mnDropPos < nItemCount )
2572 : {
2573 0 : pItem = (*mpItemList)[ mnDropPos ];
2574 0 : nX = pItem->maRect.Left();
2575 0 : if ( mnDropPos == nCurPos )
2576 0 : nX--;
2577 : else
2578 0 : nX++;
2579 0 : if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
2580 0 : SetLineColor( pItem->maTabTextColor );
2581 0 : DrawLine( Point( nX, nY ), Point( nX, nY ) );
2582 0 : DrawLine( Point( nX+1, nY-1 ), Point( nX+1, nY+1 ) );
2583 0 : DrawLine( Point( nX+2, nY-2 ), Point( nX+2, nY+2 ) );
2584 0 : SetLineColor( aBlackColor );
2585 : }
2586 0 : if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2587 : {
2588 0 : pItem = (*mpItemList)[ mnDropPos-1 ];
2589 0 : nX = pItem->maRect.Right();
2590 0 : if ( mnDropPos == nCurPos )
2591 0 : nX++;
2592 0 : if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
2593 0 : SetLineColor( pItem->maTabTextColor );
2594 0 : DrawLine( Point( nX, nY ), Point( nX, nY ) );
2595 0 : DrawLine( Point( nX-1, nY-1 ), Point( nX-1, nY+1 ) );
2596 0 : DrawLine( Point( nX-2, nY-2 ), Point( nX-2, nY+2 ) );
2597 : }
2598 :
2599 0 : return mnDropPos;
2600 : }
2601 :
2602 :
2603 :
2604 0 : void TabBar::HideDropPos()
2605 : {
2606 0 : if ( mbDropPos )
2607 : {
2608 : ImplTabBarItem* pItem;
2609 : long nX;
2610 0 : long nY1 = (maWinSize.Height()/2)-3;
2611 0 : long nY2 = nY1 + 5;
2612 0 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
2613 :
2614 0 : if ( mnDropPos < nItemCount )
2615 : {
2616 0 : pItem = (*mpItemList)[ mnDropPos ];
2617 0 : nX = pItem->maRect.Left();
2618 : // immediately call Paint, as it is not possible during drag and drop
2619 0 : Rectangle aRect( nX-1, nY1, nX+3, nY2 );
2620 0 : vcl::Region aRegion( aRect );
2621 0 : SetClipRegion( aRegion );
2622 0 : Paint( aRect );
2623 0 : SetClipRegion();
2624 : }
2625 0 : if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2626 : {
2627 0 : pItem = (*mpItemList)[ mnDropPos-1 ];
2628 0 : nX = pItem->maRect.Right();
2629 : // immediately call Paint, as it is not possible during drag and drop
2630 0 : Rectangle aRect( nX-2, nY1, nX+1, nY2 );
2631 0 : vcl::Region aRegion( aRect );
2632 0 : SetClipRegion( aRegion );
2633 0 : Paint( aRect );
2634 0 : SetClipRegion();
2635 : }
2636 :
2637 0 : mbDropPos = false;
2638 0 : mnDropPos = 0;
2639 : }
2640 0 : }
2641 :
2642 :
2643 :
2644 0 : bool TabBar::SwitchPage( const Point& rPos )
2645 : {
2646 0 : bool bSwitch = false;
2647 0 : sal_uInt16 nSwitchId = GetPageId( rPos );
2648 0 : if ( !nSwitchId )
2649 0 : EndSwitchPage();
2650 : else
2651 : {
2652 0 : if ( nSwitchId != mnSwitchId )
2653 : {
2654 0 : mnSwitchId = nSwitchId;
2655 0 : mnSwitchTime = tools::Time::GetSystemTicks();
2656 : }
2657 : else
2658 : {
2659 : // change only after 500 ms
2660 0 : if ( mnSwitchId != GetCurPageId() )
2661 : {
2662 0 : if ( tools::Time::GetSystemTicks() > mnSwitchTime+500 )
2663 : {
2664 0 : mbInSwitching = true;
2665 0 : if ( ImplDeactivatePage() )
2666 : {
2667 0 : SetCurPageId( mnSwitchId );
2668 0 : Update();
2669 0 : ImplActivatePage();
2670 0 : ImplSelect();
2671 0 : bSwitch = true;
2672 : }
2673 0 : mbInSwitching = false;
2674 : }
2675 : }
2676 : }
2677 : }
2678 :
2679 0 : return bSwitch;
2680 : }
2681 :
2682 :
2683 :
2684 0 : void TabBar::EndSwitchPage()
2685 : {
2686 0 : mnSwitchTime = 0;
2687 0 : mnSwitchId = 0;
2688 0 : }
2689 :
2690 :
2691 :
2692 1860 : void TabBar::SetStyle( WinBits nStyle )
2693 : {
2694 1860 : mnWinStyle = nStyle;
2695 1860 : ImplInitControls();
2696 : // order possible controls
2697 1860 : if ( IsReallyVisible() && IsUpdateMode() )
2698 578 : Resize();
2699 1860 : }
2700 :
2701 :
2702 :
2703 918 : Size TabBar::CalcWindowSizePixel() const
2704 : {
2705 918 : long nWidth = 0;
2706 :
2707 918 : if ( mpItemList->size() )
2708 : {
2709 0 : ((TabBar*)this)->ImplCalcWidth();
2710 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
2711 : {
2712 0 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
2713 0 : nWidth += pItem->mnWidth;
2714 : }
2715 : }
2716 :
2717 918 : return Size( nWidth, GetSettings().GetStyleSettings().GetScrollBarSize() );
2718 : }
2719 :
2720 :
2721 2594 : Rectangle TabBar::GetPageArea() const
2722 : {
2723 2594 : return Rectangle( Point( mnOffX, mnOffY ), Size( mnLastOffX-mnOffX+1, GetSizePixel().Height()-mnOffY ) );
2724 : }
2725 :
2726 :
2727 :
2728 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabBar::CreateAccessible()
2729 : {
2730 0 : return mpImpl->maAccessibleFactory.getFactory().createAccessibleTabBar( *this );
2731 1227 : }
2732 :
2733 :
2734 :
2735 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|