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