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 72 : 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 84 : ImplTabBarItem( sal_uInt16 nItemId, const OUString& rText,
64 : TabBarPageBits nPageBits ) :
65 84 : maText( rText )
66 : {
67 84 : mnId = nItemId;
68 84 : mnBits = nPageBits;
69 84 : mnWidth = 0;
70 84 : mbShort = sal_False;
71 84 : mbSelect = sal_False;
72 84 : mbEnable = sal_True;
73 84 : maTabBgColor = Color( COL_AUTO );
74 84 : maTabTextColor = Color( COL_AUTO );
75 84 : }
76 :
77 24 : bool IsDefaultTabBgColor() const
78 : {
79 24 : return maTabBgColor == Color(COL_AUTO);
80 : }
81 :
82 : bool IsDefaultTabTextColor() const
83 : {
84 : return maTabTextColor == Color(COL_AUTO);
85 : }
86 :
87 24 : bool IsSelected(ImplTabBarItem* pCurItem) const
88 : {
89 24 : return mbSelect || (pCurItem == this);
90 : }
91 : };
92 :
93 : // =======================================================================
94 :
95 : // -----------------
96 : // - ImplTabButton -
97 : // -----------------
98 :
99 208 : class ImplTabButton : public PushButton
100 : {
101 : public:
102 120 : ImplTabButton( TabBar* pParent, WinBits nWinStyle = 0 ) :
103 120 : 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 52 : 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 30 : ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle )
153 : : Window( pParent, nWinStyle & WB_3DLOOK )
154 30 : , mnStartWidth(0)
155 : {
156 30 : SetPointer( Pointer( POINTER_HSIZEBAR ) );
157 30 : SetSizePixel( Size( 7, 0 ) );
158 30 : }
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 8 : void ImplTabSizer::Paint( const Rectangle& )
208 : {
209 8 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
210 8 : DecorationView aDecoView( this );
211 8 : long nOffX = 0;
212 8 : Size aOutputSize = GetOutputSizePixel();
213 :
214 8 : if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
215 : {
216 8 : SetLineColor( rStyleSettings.GetDarkShadowColor() );
217 8 : DrawLine( Point( 0, 0 ), Point( 0, aOutputSize.Height()-1 ) );
218 8 : nOffX++;
219 8 : aOutputSize.Width()--;
220 : }
221 8 : aDecoView.DrawButton( Rectangle( Point( nOffX, 0 ), aOutputSize ), BUTTON_DRAW_NOLIGHTBORDER );
222 8 : }
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 30 : TabBar_Impl()
352 30 : :mpSizer( NULL )
353 : {
354 30 : }
355 26 : ~TabBar_Impl()
356 26 : {
357 26 : delete mpSizer;
358 26 : }
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 30 : void TabBar::ImplInit( WinBits nWinStyle )
368 : {
369 30 : mpItemList = new ImplTabBarList;
370 30 : mpFirstBtn = NULL;
371 30 : mpPrevBtn = NULL;
372 30 : mpNextBtn = NULL;
373 30 : mpLastBtn = NULL;
374 30 : mpImpl = new TabBar_Impl;
375 30 : mpEdit = NULL;
376 30 : mnMaxPageWidth = 0;
377 30 : mnCurMaxWidth = 0;
378 30 : mnOffX = 0;
379 30 : mnOffY = 0;
380 30 : mnLastOffX = 0;
381 30 : mnSplitSize = 0;
382 30 : mnSwitchTime = 0;
383 30 : mnWinStyle = nWinStyle;
384 30 : mnCurPageId = 0;
385 30 : mnFirstPos = 0;
386 30 : mnDropPos = 0;
387 30 : mnSwitchId = 0;
388 30 : mnEditId = 0;
389 30 : mbFormat = sal_True;
390 30 : mbFirstFormat = sal_True;
391 30 : mbSizeFormat = sal_True;
392 30 : mbAutoMaxWidth = sal_True;
393 30 : mbInSwitching = sal_False;
394 30 : mbAutoEditMode = sal_False;
395 30 : mbEditCanceled = sal_False;
396 30 : mbDropPos = sal_False;
397 30 : mbInSelect = sal_False;
398 30 : mbSelColor = sal_False;
399 30 : mbSelTextColor = sal_False;
400 30 : mbMirrored = sal_False;
401 :
402 30 : if ( nWinStyle & WB_3DTAB )
403 0 : mnOffY++;
404 :
405 30 : ImplInitControls();
406 :
407 30 : if(mpFirstBtn)
408 30 : mpFirstBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVET0HOME));
409 30 : if(mpPrevBtn)
410 30 : mpPrevBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVELEFT));
411 30 : if(mpNextBtn)
412 30 : mpNextBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVERIGHT));
413 30 : if(mpLastBtn)
414 30 : mpLastBtn->SetAccessibleName(SVT_RESSTR(STR_TABBAR_PUSHBUTTON_MOVETOEND));
415 :
416 30 : SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
417 30 : ImplInitSettings( sal_True, sal_True );
418 30 : }
419 :
420 : // -----------------------------------------------------------------------
421 :
422 30 : TabBar::TabBar( Window* pParent, WinBits nWinStyle ) :
423 30 : Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN )
424 : {
425 30 : ImplInit( nWinStyle );
426 30 : maCurrentItemList = 0;
427 30 : }
428 :
429 : // -----------------------------------------------------------------------
430 :
431 52 : TabBar::~TabBar()
432 : {
433 26 : EndEditMode( sal_True );
434 :
435 : // Controls loeschen
436 26 : if ( mpPrevBtn )
437 26 : delete mpPrevBtn;
438 26 : if ( mpNextBtn )
439 26 : delete mpNextBtn;
440 26 : if ( mpFirstBtn )
441 26 : delete mpFirstBtn;
442 26 : if ( mpLastBtn )
443 26 : delete mpLastBtn;
444 26 : delete mpImpl;
445 :
446 88 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
447 62 : delete (*mpItemList)[ i ];
448 : }
449 26 : delete mpItemList;
450 26 : }
451 :
452 : // -----------------------------------------------------------------------
453 16 : ImplTabBarItem* TabBar::seek( size_t i )
454 : {
455 16 : if ( i < mpItemList->size() )
456 : {
457 16 : maCurrentItemList = i;
458 16 : return (*mpItemList)[ maCurrentItemList ];
459 : }
460 0 : return NULL;
461 : }
462 :
463 24 : ImplTabBarItem* TabBar::prev()
464 : {
465 24 : if ( maCurrentItemList > 0 ) {
466 16 : return (*mpItemList)[ --maCurrentItemList ];
467 : }
468 8 : return NULL;
469 : }
470 :
471 16 : ImplTabBarItem* TabBar::next()
472 : {
473 16 : if ( maCurrentItemList+1 < mpItemList->size() ) {
474 8 : return (*mpItemList)[ ++maCurrentItemList ];
475 : }
476 8 : return NULL;
477 : }
478 :
479 : // -----------------------------------------------------------------------
480 :
481 156 : void TabBar::ImplInitSettings( sal_Bool bFont, sal_Bool bBackground )
482 : {
483 156 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
484 :
485 156 : if ( bFont )
486 : {
487 156 : Font aToolFont;
488 156 : aToolFont = rStyleSettings.GetToolFont();
489 156 : if ( IsControlFont() )
490 0 : aToolFont.Merge( GetControlFont() );
491 156 : aToolFont.SetWeight( WEIGHT_BOLD );
492 156 : SetZoomedPointFont( aToolFont );
493 :
494 : // Font in der groesse Anpassen, wenn Fenster zu klein?
495 462 : while ( GetTextHeight() > (GetOutputSizePixel().Height()-1) )
496 : {
497 180 : Font aFont = GetFont();
498 180 : if ( aFont.GetHeight() <= 6 )
499 : break;
500 150 : aFont.SetHeight( aFont.GetHeight()-1 );
501 150 : SetFont( aFont );
502 336 : }
503 : }
504 :
505 156 : if ( bBackground )
506 : {
507 30 : Color aColor;
508 30 : if ( IsControlBackground() )
509 0 : aColor = GetControlBackground();
510 : else
511 30 : aColor = rStyleSettings.GetFaceColor();
512 30 : SetBackground( aColor );
513 : }
514 156 : }
515 :
516 : // -----------------------------------------------------------------------
517 :
518 8 : void TabBar::ImplGetColors( Color& rFaceColor, Color& rFaceTextColor,
519 : Color& rSelectColor, Color& rSelectTextColor )
520 : {
521 8 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
522 :
523 8 : if ( IsControlBackground() )
524 0 : rFaceColor = GetControlBackground();
525 : else
526 8 : rFaceColor = rStyleSettings.GetInactiveTabColor();
527 8 : if ( IsControlForeground() )
528 0 : rFaceTextColor = GetControlForeground();
529 : else
530 8 : rFaceTextColor = rStyleSettings.GetButtonTextColor();
531 8 : if ( mbSelColor )
532 0 : rSelectColor = maSelColor;
533 : else
534 8 : rSelectColor = rStyleSettings.GetActiveTabColor();
535 8 : if ( mbSelTextColor )
536 0 : rSelectTextColor = maSelTextColor;
537 : else
538 8 : rSelectTextColor = rStyleSettings.GetWindowTextColor();
539 :
540 : // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die
541 : // selektierten Tabs in 3D erscheinen sollen
542 8 : 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 8 : }
552 :
553 : // -----------------------------------------------------------------------
554 :
555 176 : sal_Bool TabBar::ImplCalcWidth()
556 : {
557 : // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder
558 : // wenn der Font geaendert wurde
559 176 : if ( !mbSizeFormat )
560 76 : return sal_False;
561 :
562 : // Breiten der Tabs mit dem fetten Font ermitteln
563 100 : Font aFont = GetFont();
564 100 : if ( aFont.GetWeight() != WEIGHT_BOLD )
565 : {
566 0 : aFont.SetWeight( WEIGHT_BOLD );
567 0 : SetFont( aFont );
568 : }
569 :
570 100 : if ( mnMaxPageWidth )
571 0 : mnCurMaxWidth = mnMaxPageWidth;
572 100 : else if ( mbAutoMaxWidth )
573 : {
574 : mnCurMaxWidth = mnLastOffX-mnOffX-
575 : TABBAR_OFFSET_X-TABBAR_OFFSET_X-
576 100 : TABBAR_OFFSET_X2-TABBAR_OFFSET_X2-TABBAR_OFFSET_X2;
577 100 : if ( mnCurMaxWidth < 1 )
578 0 : mnCurMaxWidth = 1;
579 : }
580 : else
581 0 : mnCurMaxWidth = 0;
582 :
583 100 : sal_Bool bChanged = sal_False;
584 364 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
585 : {
586 264 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
587 264 : long nNewWidth = GetTextWidth( pItem->maText );
588 264 : if ( mnCurMaxWidth && (nNewWidth > mnCurMaxWidth) )
589 : {
590 0 : pItem->mbShort = sal_True;
591 0 : nNewWidth = mnCurMaxWidth;
592 : }
593 : else
594 264 : pItem->mbShort = sal_False;
595 264 : nNewWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
596 264 : if ( pItem->mnWidth != nNewWidth )
597 : {
598 84 : pItem->mnWidth = nNewWidth;
599 84 : if ( !pItem->maRect.IsEmpty() )
600 0 : bChanged = sal_True;
601 : }
602 : }
603 100 : mbSizeFormat = sal_False;
604 100 : mbFormat = sal_True;
605 100 : return bChanged;
606 : }
607 :
608 : // -----------------------------------------------------------------------
609 :
610 110 : void TabBar::ImplFormat()
611 : {
612 110 : ImplCalcWidth();
613 :
614 110 : if ( !mbFormat )
615 116 : return;
616 :
617 104 : sal_uInt16 n = 0;
618 104 : long x = mnOffX;
619 380 : for ( size_t i = 0, nL = mpItemList->size(); i < nL; ++i )
620 : {
621 276 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
622 : // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck
623 : // gesetzt
624 276 : if ( (n+1 < mnFirstPos) || (x > mnLastOffX) )
625 8 : pItem->maRect.SetEmpty();
626 : else
627 : {
628 : // Etwas von der Tab vor der ersten sichtbaren Page
629 : // muss auch zu sehen sein
630 268 : if ( n+1 == mnFirstPos )
631 0 : pItem->maRect.Left() = x-pItem->mnWidth;
632 : else
633 : {
634 268 : pItem->maRect.Left() = x;
635 268 : x += pItem->mnWidth;
636 : }
637 268 : pItem->maRect.Right() = x+TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
638 268 : pItem->maRect.Bottom() = maWinSize.Height()-1;
639 :
640 268 : 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 276 : n++;
649 : }
650 :
651 104 : mbFormat = sal_False;
652 :
653 : // Button enablen/disablen
654 104 : ImplEnableControls();
655 : }
656 :
657 : // -----------------------------------------------------------------------
658 :
659 172 : sal_uInt16 TabBar::ImplGetLastFirstPos()
660 : {
661 172 : sal_uInt16 nCount = (sal_uInt16)(mpItemList->size());
662 172 : if ( !nCount || mbSizeFormat || mbFormat )
663 0 : return 0;
664 :
665 172 : sal_uInt16 nLastFirstPos = nCount-1;
666 172 : long nWinWidth = mnLastOffX-mnOffX-TABBAR_OFFSET_X-ADDNEWPAGE_AREAWIDTH;
667 172 : long nWidth = (*mpItemList)[ nLastFirstPos ]->mnWidth;
668 582 : while ( nLastFirstPos && (nWidth < nWinWidth) )
669 : {
670 238 : nLastFirstPos--;
671 238 : nWidth += (*mpItemList)[ nLastFirstPos ]->mnWidth;
672 : }
673 172 : if ( (nLastFirstPos != (sal_uInt16)(mpItemList->size()-1)) &&
674 : (nWidth > nWinWidth) )
675 26 : nLastFirstPos++;
676 172 : return nLastFirstPos;
677 : }
678 :
679 : // -----------------------------------------------------------------------
680 :
681 128 : void TabBar::ImplInitControls()
682 : {
683 128 : if ( mnWinStyle & WB_SIZEABLE )
684 : {
685 128 : if ( !mpImpl->mpSizer )
686 30 : mpImpl->mpSizer = new ImplTabSizer( this, mnWinStyle & (WB_DRAG | WB_3DLOOK) );
687 128 : mpImpl->mpSizer->Show();
688 : }
689 : else
690 : {
691 0 : DELETEZ( mpImpl->mpSizer );
692 : }
693 :
694 128 : Link aLink = LINK( this, TabBar, ImplClickHdl );
695 :
696 128 : if ( mnWinStyle & (WB_MINSCROLL | WB_SCROLL) )
697 : {
698 128 : if ( !mpPrevBtn )
699 : {
700 30 : mpPrevBtn = new ImplTabButton( this, WB_REPEAT );
701 30 : mpPrevBtn->SetClickHdl( aLink );
702 : }
703 128 : mpPrevBtn->SetSymbol( mbMirrored ? SYMBOL_NEXT : SYMBOL_PREV );
704 128 : mpPrevBtn->Show();
705 :
706 128 : if ( !mpNextBtn )
707 : {
708 30 : mpNextBtn = new ImplTabButton( this, WB_REPEAT );
709 30 : mpNextBtn->SetClickHdl( aLink );
710 : }
711 128 : mpNextBtn->SetSymbol( mbMirrored ? SYMBOL_PREV : SYMBOL_NEXT );
712 128 : mpNextBtn->Show();
713 : }
714 : else
715 : {
716 0 : DELETEZ( mpPrevBtn );
717 0 : DELETEZ( mpNextBtn );
718 : }
719 :
720 128 : if ( mnWinStyle & WB_SCROLL )
721 : {
722 128 : if ( !mpFirstBtn )
723 : {
724 30 : mpFirstBtn = new ImplTabButton( this );
725 30 : mpFirstBtn->SetClickHdl( aLink );
726 : }
727 128 : mpFirstBtn->SetSymbol( mbMirrored ? SYMBOL_LAST : SYMBOL_FIRST );
728 128 : mpFirstBtn->Show();
729 :
730 128 : if ( !mpLastBtn )
731 : {
732 30 : mpLastBtn = new ImplTabButton( this );
733 30 : mpLastBtn->SetClickHdl( aLink );
734 : }
735 128 : mpLastBtn->SetSymbol( mbMirrored ? SYMBOL_FIRST : SYMBOL_LAST );
736 128 : mpLastBtn->Show();
737 : }
738 : else
739 : {
740 0 : DELETEZ( mpFirstBtn );
741 0 : DELETEZ( mpLastBtn );
742 : }
743 :
744 128 : mbHasInsertTab = (mnWinStyle & WB_INSERTTAB);
745 128 : }
746 :
747 : // -----------------------------------------------------------------------
748 :
749 230 : void TabBar::ImplEnableControls()
750 : {
751 230 : if ( mbSizeFormat || mbFormat )
752 290 : return;
753 :
754 : // Buttons enablen/disblen
755 170 : sal_Bool bEnableBtn = mnFirstPos > 0;
756 170 : if ( mpFirstBtn )
757 170 : mpFirstBtn->Enable( bEnableBtn );
758 170 : if ( mpPrevBtn )
759 170 : mpPrevBtn->Enable( bEnableBtn );
760 :
761 170 : bEnableBtn = mnFirstPos < ImplGetLastFirstPos();
762 170 : if ( mpNextBtn )
763 170 : mpNextBtn->Enable( bEnableBtn );
764 170 : if ( mpLastBtn )
765 170 : 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 8 : explicit TabBarPaintGuard(TabBar& rParent) :
1056 : mrParent(rParent),
1057 8 : maFont(rParent.GetFont())
1058 : {
1059 : // #i36013# exclude push buttons from painting area
1060 8 : mrParent.SetClipRegion( Region(mrParent.GetPageArea()) );
1061 8 : }
1062 :
1063 8 : ~TabBarPaintGuard()
1064 8 : {
1065 : // Restore original font.
1066 8 : mrParent.SetFont(maFont);
1067 : // remove clip region
1068 8 : mrParent.SetClipRegion();
1069 8 : }
1070 : private:
1071 : TabBar& mrParent;
1072 : Font maFont;
1073 : };
1074 :
1075 8 : class TabDrawer
1076 : {
1077 : public:
1078 :
1079 8 : explicit TabDrawer(TabBar& rParent) :
1080 : mrParent(rParent),
1081 8 : mpStyleSettings(&mrParent.GetSettings().GetStyleSettings()),
1082 : maPoly(4),
1083 : mbSelected(false),
1084 : mbCustomColored(false),
1085 : mbSpecialTab(false),
1086 16 : mbEnabled(false)
1087 : {
1088 8 : }
1089 :
1090 8 : void drawOutputAreaBorder()
1091 : {
1092 8 : WinBits nWinStyle = mrParent.GetStyle();
1093 :
1094 : // Bei Border oben und unten einen Strich extra malen
1095 8 : if ( (nWinStyle & WB_BORDER) || (nWinStyle & WB_TOPBORDER) )
1096 : {
1097 8 : Size aOutputSize = mrParent.GetOutputSizePixel();
1098 8 : Rectangle aOutRect = mrParent.GetPageArea();
1099 :
1100 : // Bei 3D-Tabs wird auch der Border in 3D gemalt
1101 8 : 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 8 : mrParent.SetLineColor( mpStyleSettings->GetDarkShadowColor() );
1109 8 : mrParent.DrawLine( aOutRect.TopLeft(), Point( aOutputSize.Width()-1, aOutRect.Top() ) );
1110 : }
1111 8 : }
1112 :
1113 64 : void drawOuterFrame()
1114 : {
1115 64 : mrParent.DrawPolygon(maPoly);
1116 64 : }
1117 :
1118 32 : void drawLeftShadow()
1119 : {
1120 32 : Point p1 = maPoly[0], p2 = maPoly[1];
1121 32 : p1.X()++;
1122 32 : p2.X()++;
1123 32 : p2.Y()--;
1124 32 : mrParent.DrawLine(p1, p2);
1125 32 : }
1126 :
1127 32 : void drawRightShadow()
1128 : {
1129 32 : Point p1 = maPoly[2];
1130 32 : Point p2 = maPoly[3];
1131 32 : p1.X()--;
1132 32 : p2.X()--;
1133 32 : mrParent.DrawLine(p1, p2);
1134 32 : }
1135 :
1136 24 : void drawTopInnerShadow()
1137 : {
1138 24 : Point p1 = maPoly[0], p2 = maPoly[3];
1139 24 : p1.Y()++;
1140 24 : p2.Y()++;
1141 24 : mrParent.DrawLine(p1, p2);
1142 24 : }
1143 :
1144 32 : void drawBottomShadow(bool bColored)
1145 : {
1146 32 : Point p1 = maPoly[1], p2 = maPoly[2];
1147 32 : p1.X() += 1;
1148 32 : p1.Y() -= 1;
1149 32 : p2.X() -= 1;
1150 32 : p2.Y() -= 1;
1151 32 : mrParent.DrawLine(p1, p2);
1152 32 : if (bColored)
1153 : {
1154 0 : p1 += Point(-1, -1);
1155 0 : p2 += Point(1, -1);
1156 0 : mrParent.DrawLine(p1, p2);
1157 : }
1158 32 : }
1159 :
1160 24 : void drawText(const String& aText)
1161 : {
1162 24 : Rectangle aRect = maRect;
1163 24 : long nTextWidth = mrParent.GetTextWidth(aText);
1164 24 : long nTextHeight = mrParent.GetTextHeight();
1165 24 : Point aPos = aRect.TopLeft();
1166 24 : aPos.X() += (aRect.getWidth() - nTextWidth) / 2;
1167 24 : aPos.Y() += (aRect.getHeight() - nTextHeight) / 2;
1168 :
1169 24 : if (mbEnabled)
1170 24 : mrParent.DrawText(aPos, aText);
1171 : else
1172 : mrParent.DrawCtrlText(
1173 0 : aPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC));
1174 24 : }
1175 :
1176 8 : void drawOverTopBorder(bool b3DTab)
1177 : {
1178 8 : Point p1 = maPoly[0], p2 = maPoly[3];
1179 8 : p1.X() += 1;
1180 8 : p2.X() -= 1;
1181 8 : Rectangle aDelRect(p1, p2);
1182 8 : mrParent.DrawRect(aDelRect);
1183 8 : if (b3DTab)
1184 : {
1185 0 : aDelRect.Top()--;
1186 0 : mrParent.DrawRect(aDelRect);
1187 : }
1188 8 : }
1189 :
1190 32 : void drawTab()
1191 : {
1192 32 : mrParent.SetLineColor(mpStyleSettings->GetDarkShadowColor());
1193 :
1194 : // Je nach Status die richtige FillInBrush setzen
1195 : // Set the correct FillInBrush depending upon status
1196 32 : if ( mbSelected )
1197 : {
1198 : // Currently selected Tab
1199 8 : mrParent.SetFillColor( maSelectedColor );
1200 : }
1201 24 : else if ( mbCustomColored )
1202 : {
1203 0 : mrParent.SetFillColor( maCustomColor );
1204 : }
1205 : else
1206 : {
1207 24 : mrParent.SetFillColor( maUnselectedColor );
1208 : }
1209 :
1210 32 : 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 32 : Color aColor = mpStyleSettings->GetLightColor();
1215 32 : if (mbCustomColored && !mbSelected)
1216 0 : aColor = maCustomColor;
1217 :
1218 32 : mrParent.SetLineColor(aColor);
1219 32 : drawLeftShadow();
1220 :
1221 32 : if ( !mbSelected )
1222 24 : drawTopInnerShadow();
1223 :
1224 32 : mrParent.SetLineColor( mpStyleSettings->GetShadowColor() );
1225 32 : drawRightShadow();
1226 32 : if ( mbCustomColored && mbSelected )
1227 : {
1228 0 : mrParent.SetLineColor(maCustomColor);
1229 0 : drawBottomShadow(true);
1230 : }
1231 : else
1232 32 : drawBottomShadow(false);
1233 :
1234 : // Draw the outer frame once more. In some environments, the outer frame
1235 : // gets overpainted.
1236 32 : mrParent.SetLineColor( mpStyleSettings->GetDarkShadowColor() );
1237 32 : mrParent.SetFillColor();
1238 32 : drawOuterFrame();
1239 32 : }
1240 :
1241 8 : void drawPlusImage()
1242 : {
1243 8 : SvtResId id( BMP_LIST_ADD );
1244 8 : Image aPlusImg( id );
1245 : // Center the image within the bounding rectangle.
1246 8 : Size aSize = aPlusImg.GetSizePixel();
1247 8 : Point pt = maRect.TopLeft();
1248 8 : long nXOffSet = (maRect.GetWidth() - aSize.Width()) / 2;
1249 8 : long nYOffset = (maRect.GetHeight() - aSize.Height()) / 2;
1250 8 : pt += Point(nXOffSet, nYOffset);
1251 8 : pt.X() += 1;
1252 8 : mrParent.DrawImage(pt, aPlusImg);
1253 8 : }
1254 :
1255 32 : void setRect(const Rectangle& rRect)
1256 : {
1257 32 : maRect = rRect;
1258 :
1259 32 : long nOffY = mrParent.GetPageArea().getY();
1260 :
1261 : // Zuerst geben wir das Polygon gefuellt aus
1262 32 : maPoly[0] = Point( rRect.Left(), nOffY );
1263 32 : maPoly[1] = Point( rRect.Left()+TABBAR_OFFSET_X, rRect.Bottom() );
1264 32 : maPoly[2] = Point( rRect.Right()-TABBAR_OFFSET_X, rRect.Bottom() );
1265 32 : maPoly[3] = Point( rRect.Right(), nOffY );
1266 32 : }
1267 :
1268 24 : void setSelected(bool b)
1269 : {
1270 24 : mbSelected = b;
1271 24 : }
1272 :
1273 24 : void setCustomColored(bool b)
1274 : {
1275 24 : mbCustomColored = b;
1276 24 : }
1277 :
1278 24 : void setSpecialTab(bool b)
1279 : {
1280 24 : mbSpecialTab = b;
1281 24 : }
1282 :
1283 24 : void setEnabled(bool b)
1284 : {
1285 24 : mbEnabled = b;
1286 24 : }
1287 :
1288 8 : void setSelectedFillColor(const Color& rColor)
1289 : {
1290 8 : maSelectedColor = rColor;
1291 8 : }
1292 :
1293 8 : void setUnselectedFillColor(const Color& rColor)
1294 : {
1295 8 : maUnselectedColor = rColor;
1296 8 : }
1297 :
1298 24 : void setCustomColor(const Color& rColor)
1299 : {
1300 24 : maCustomColor = rColor;
1301 24 : }
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 8 : void TabBar::Paint( const Rectangle& rect )
1323 : {
1324 8 : 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 8 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
1330 8 : if (!nItemCount)
1331 : return;
1332 :
1333 8 : ImplPrePaint();
1334 :
1335 8 : Color aFaceColor, aSelectColor, aFaceTextColor, aSelectTextColor;
1336 8 : ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
1337 :
1338 : // Font selektieren
1339 8 : Font aFont = GetFont();
1340 8 : Font aLightFont = aFont;
1341 8 : aLightFont.SetWeight( WEIGHT_NORMAL );
1342 :
1343 8 : TabBarPaintGuard aGuard(*this);
1344 8 : TabDrawer aDrawer(*this);
1345 8 : aDrawer.setSelectedFillColor(aSelectColor);
1346 8 : aDrawer.setUnselectedFillColor(aFaceColor);
1347 8 : aDrawer.drawOutputAreaBorder();
1348 :
1349 : // Now, start drawing the tabs.
1350 :
1351 8 : ImplTabBarItem* pItem = ImplGetLastTabBarItem(nItemCount);
1352 :
1353 8 : if (pItem && mbHasInsertTab)
1354 : {
1355 : // Draw the insert tab at the right end.
1356 8 : Rectangle aRect = ImplGetInsertTabRect(pItem);
1357 8 : aDrawer.setRect(aRect);
1358 8 : aDrawer.drawTab();
1359 8 : aDrawer.drawPlusImage();
1360 : }
1361 :
1362 8 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1363 8 : ImplTabBarItem* pCurItem = NULL;
1364 40 : while ( pItem )
1365 : {
1366 : // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
1367 32 : if ( !pCurItem && (pItem->mnId == mnCurPageId) )
1368 : {
1369 8 : pCurItem = pItem;
1370 8 : pItem = prev();
1371 8 : if ( !pItem )
1372 6 : pItem = pCurItem;
1373 8 : continue;
1374 : }
1375 :
1376 24 : bool bCurrent = pItem == pCurItem;
1377 :
1378 24 : if ( !pItem->maRect.IsEmpty() )
1379 : {
1380 24 : Rectangle aRect = pItem->maRect;
1381 24 : bool bSelected = pItem->IsSelected(pCurItem);
1382 : // We disable custom background color in high contrast mode.
1383 24 : bool bCustomBgColor = !pItem->IsDefaultTabBgColor() && !rStyleSettings.GetHighContrastMode();
1384 24 : bool bSpecialTab = (pItem->mnBits & TPB_SPECIAL);
1385 24 : bool bEnabled = pItem->mbEnable;
1386 : OUString aText = pItem->mbShort ?
1387 24 : GetEllipsisString(pItem->maText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS) : pItem->maText;
1388 :
1389 24 : aDrawer.setRect(aRect);
1390 24 : aDrawer.setSelected(bSelected);
1391 24 : aDrawer.setCustomColored(bCustomBgColor);
1392 24 : aDrawer.setSpecialTab(bSpecialTab);
1393 24 : aDrawer.setEnabled(bEnabled);
1394 24 : aDrawer.setCustomColor(pItem->maTabBgColor);
1395 24 : aDrawer.drawTab();
1396 :
1397 : // Aktuelle Page wird mit einem fetten Font ausgegeben
1398 24 : if ( bCurrent )
1399 8 : SetFont( aFont );
1400 : else
1401 16 : SetFont( aLightFont );
1402 :
1403 : // Je nach Status die richtige FillInBrush setzen
1404 : // Set the correct FillInBrush depending upon status
1405 24 : if ( bSelected )
1406 8 : SetTextColor( aSelectTextColor );
1407 16 : else if ( bCustomBgColor )
1408 0 : SetTextColor( pItem->maTabTextColor );
1409 : else
1410 16 : SetTextColor( aFaceTextColor );
1411 :
1412 : // This tab is "special", and a special tab needs a blue text.
1413 24 : if (bSpecialTab)
1414 0 : SetTextColor(Color(COL_LIGHTBLUE));
1415 :
1416 24 : aDrawer.drawText(aText);
1417 :
1418 24 : if ( bCurrent )
1419 : {
1420 8 : SetLineColor();
1421 8 : SetFillColor(aSelectColor);
1422 8 : aDrawer.drawOverTopBorder(mnWinStyle & WB_3DTAB);
1423 : return;
1424 : }
1425 :
1426 16 : pItem = prev();
1427 : }
1428 : else
1429 : {
1430 0 : if ( bCurrent )
1431 : return;
1432 :
1433 0 : pItem = NULL;
1434 : }
1435 :
1436 16 : if ( !pItem )
1437 2 : pItem = pCurItem;
1438 8 : }
1439 : }
1440 :
1441 : // -----------------------------------------------------------------------
1442 126 : void TabBar::Resize()
1443 : {
1444 126 : Size aNewSize = GetOutputSizePixel();
1445 :
1446 126 : long nSizerWidth = 0;
1447 126 : long nButtonWidth = 0;
1448 :
1449 : // Sizer anordnen
1450 126 : if ( mpImpl->mpSizer )
1451 : {
1452 126 : Size aSizerSize = mpImpl->mpSizer->GetSizePixel();
1453 126 : Point aNewSizerPos( mbMirrored ? 0 : (aNewSize.Width()-aSizerSize.Width()), 0 );
1454 126 : Size aNewSizerSize( aSizerSize.Width(), aNewSize.Height() );
1455 126 : mpImpl->mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize );
1456 126 : nSizerWidth = aSizerSize.Width();
1457 : }
1458 :
1459 : // Scroll-Buttons anordnen
1460 126 : long nHeight = aNewSize.Height();
1461 : // Font in der groesse Anpassen?
1462 126 : ImplInitSettings( sal_True, sal_False );
1463 :
1464 126 : long nX = mbMirrored ? (aNewSize.Width()-nHeight) : 0;
1465 126 : long nXDiff = mbMirrored ? -nHeight : nHeight;
1466 :
1467 126 : Size aBtnSize( nHeight, nHeight );
1468 126 : if ( mpFirstBtn )
1469 : {
1470 126 : mpFirstBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1471 126 : nX += nXDiff;
1472 126 : nButtonWidth += nHeight;
1473 : }
1474 126 : if ( mpPrevBtn )
1475 : {
1476 126 : mpPrevBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1477 126 : nX += nXDiff;
1478 126 : nButtonWidth += nHeight;
1479 : }
1480 126 : if ( mpNextBtn )
1481 : {
1482 126 : mpNextBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1483 126 : nX += nXDiff;
1484 126 : nButtonWidth += nHeight;
1485 : }
1486 126 : if ( mpLastBtn )
1487 : {
1488 126 : mpLastBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
1489 126 : nX += nXDiff;
1490 126 : nButtonWidth += nHeight;
1491 : }
1492 :
1493 : // Groesse merken
1494 126 : maWinSize = aNewSize;
1495 :
1496 126 : if( mbMirrored )
1497 : {
1498 0 : mnOffX = nSizerWidth;
1499 0 : mnLastOffX = maWinSize.Width() - nButtonWidth - 1;
1500 : }
1501 : else
1502 : {
1503 126 : mnOffX = nButtonWidth;
1504 126 : mnLastOffX = maWinSize.Width() - nSizerWidth - 1;
1505 : }
1506 :
1507 : // Neu formatieren
1508 126 : mbSizeFormat = sal_True;
1509 126 : if ( IsReallyVisible() )
1510 : {
1511 66 : if ( ImplCalcWidth() )
1512 0 : Invalidate();
1513 66 : ImplFormat();
1514 : }
1515 :
1516 : // Button enablen/disablen
1517 126 : ImplEnableControls();
1518 126 : }
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 90 : void TabBar::StateChanged( StateChangedType nType )
1591 : {
1592 90 : Window::StateChanged( nType );
1593 :
1594 90 : if ( nType == STATE_CHANGE_INITSHOW )
1595 : {
1596 30 : if ( (mbSizeFormat || mbFormat) && !mpItemList->empty() )
1597 30 : ImplFormat();
1598 : }
1599 60 : else if ( (nType == STATE_CHANGE_ZOOM) ||
1600 : (nType == STATE_CHANGE_CONTROLFONT) )
1601 : {
1602 0 : ImplInitSettings( sal_True, sal_False );
1603 0 : Invalidate();
1604 : }
1605 60 : else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1606 0 : Invalidate();
1607 60 : else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1608 : {
1609 0 : ImplInitSettings( sal_False, sal_True );
1610 0 : Invalidate();
1611 : }
1612 60 : else if ( nType == STATE_CHANGE_MIRRORING )
1613 : {
1614 : // reacts on calls of EnableRTL, have to mirror all child controls
1615 30 : if( mpFirstBtn ) mpFirstBtn->EnableRTL( IsRTLEnabled() );
1616 30 : if( mpPrevBtn ) mpPrevBtn->EnableRTL( IsRTLEnabled() );
1617 30 : if( mpNextBtn ) mpNextBtn->EnableRTL( IsRTLEnabled() );
1618 30 : if( mpLastBtn ) mpLastBtn->EnableRTL( IsRTLEnabled() );
1619 30 : if( mpImpl->mpSizer ) mpImpl->mpSizer->EnableRTL( IsRTLEnabled() );
1620 30 : if( mpEdit ) mpEdit->EnableRTL( IsRTLEnabled() );
1621 : }
1622 90 : }
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 8 : void TabBar::ImplPrePaint()
1698 : {
1699 8 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
1700 8 : if (!nItemCount)
1701 8 : return;
1702 :
1703 : ImplTabBarItem* pItem;
1704 :
1705 : // TabBar muss formatiert sein
1706 8 : ImplFormat();
1707 :
1708 : // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage
1709 : // sichtbar wird
1710 8 : if ( mbFirstFormat )
1711 : {
1712 8 : mbFirstFormat = sal_False;
1713 :
1714 8 : if ( mnCurPageId && (mnFirstPos == 0) && !mbDropPos )
1715 : {
1716 8 : pItem = (*mpItemList)[ GetPagePos( mnCurPageId ) ];
1717 8 : 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 8 : ImplTabBarItem* TabBar::ImplGetLastTabBarItem( sal_uInt16 nItemCount )
1732 : {
1733 : // letzten sichtbaren Eintrag suchen
1734 8 : sal_uInt16 n = mnFirstPos+1;
1735 8 : if ( n >= nItemCount )
1736 0 : n = nItemCount-1;
1737 8 : ImplTabBarItem* pItem = seek( n );
1738 32 : while ( pItem )
1739 : {
1740 16 : if ( !pItem->maRect.IsEmpty() )
1741 : {
1742 16 : n++;
1743 16 : pItem = next();
1744 : }
1745 : else
1746 0 : break;
1747 : }
1748 :
1749 : // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
1750 8 : if ( pItem )
1751 0 : n--;
1752 8 : else if ( n >= nItemCount )
1753 8 : n = nItemCount-1;
1754 8 : pItem = seek( n );
1755 8 : return pItem;
1756 : }
1757 :
1758 8 : Rectangle TabBar::ImplGetInsertTabRect(ImplTabBarItem* pItem) const
1759 : {
1760 8 : if (mbHasInsertTab && pItem)
1761 : {
1762 8 : Rectangle aInsTabRect = pItem->maRect;
1763 : aInsTabRect.setX(
1764 8 : aInsTabRect.getX() + aInsTabRect.getWidth() - TABBAR_OFFSET_X - TABBAR_OFFSET_X2);
1765 8 : aInsTabRect.setWidth(32);
1766 8 : return aInsTabRect;
1767 : }
1768 0 : return Rectangle();
1769 : }
1770 :
1771 : // -----------------------------------------------------------------------
1772 :
1773 0 : long TabBar::DeactivatePage()
1774 : {
1775 0 : if ( maDeactivatePageHdl.IsSet() )
1776 0 : return maDeactivatePageHdl.Call( this );
1777 : else
1778 0 : return sal_True;
1779 : }
1780 :
1781 : // -----------------------------------------------------------------------
1782 :
1783 0 : long TabBar::StartRenaming()
1784 : {
1785 0 : if ( maStartRenamingHdl.IsSet() )
1786 0 : return maStartRenamingHdl.Call( this );
1787 : else
1788 0 : return sal_True;
1789 : }
1790 :
1791 : // -----------------------------------------------------------------------
1792 :
1793 0 : long TabBar::AllowRenaming()
1794 : {
1795 0 : if ( maAllowRenamingHdl.IsSet() )
1796 0 : return maAllowRenamingHdl.Call( this );
1797 : else
1798 0 : return sal_True;
1799 : }
1800 :
1801 : // -----------------------------------------------------------------------
1802 :
1803 0 : void TabBar::EndRenaming()
1804 : {
1805 0 : maEndRenamingHdl.Call( this );
1806 0 : }
1807 :
1808 : // -----------------------------------------------------------------------
1809 :
1810 0 : void TabBar::Mirror()
1811 : {
1812 :
1813 0 : }
1814 :
1815 : // -----------------------------------------------------------------------
1816 :
1817 84 : void TabBar::InsertPage( sal_uInt16 nPageId, const OUString& rText,
1818 : TabBarPageBits nBits, sal_uInt16 nPos )
1819 : {
1820 : DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" );
1821 : DBG_ASSERT( GetPagePos( nPageId ) == PAGE_NOT_FOUND,
1822 : "TabBar::InsertPage(): PageId already exists" );
1823 : DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" );
1824 :
1825 : // PageItem anlegen und in die Item-Liste eintragen
1826 84 : ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits );
1827 84 : if ( nPos < mpItemList->size() ) {
1828 0 : ImplTabBarList::iterator it = mpItemList->begin();
1829 0 : ::std::advance( it, nPos );
1830 0 : mpItemList->insert( it, pItem );
1831 : } else {
1832 84 : mpItemList->push_back( pItem );
1833 : }
1834 84 : mbSizeFormat = sal_True;
1835 :
1836 : // CurPageId gegebenenfalls setzen
1837 84 : if ( !mnCurPageId )
1838 34 : mnCurPageId = nPageId;
1839 :
1840 : // Leiste neu ausgeben
1841 84 : if ( IsReallyVisible() && IsUpdateMode() )
1842 10 : Invalidate();
1843 :
1844 84 : CallEventListeners( VCLEVENT_TABBAR_PAGEINSERTED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1845 84 : }
1846 :
1847 : // -----------------------------------------------------------------------
1848 :
1849 236 : Color TabBar::GetTabBgColor( sal_uInt16 nPageId ) const
1850 : {
1851 236 : sal_uInt16 nPos = GetPagePos( nPageId );
1852 :
1853 236 : if ( nPos != PAGE_NOT_FOUND )
1854 236 : return (*mpItemList)[ nPos ]->maTabBgColor;
1855 : else
1856 0 : return Color( COL_AUTO );
1857 : }
1858 :
1859 0 : void TabBar::SetTabBgColor( sal_uInt16 nPageId, const Color& aTabBgColor )
1860 : {
1861 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1862 : ImplTabBarItem* pItem;
1863 0 : if ( nPos != PAGE_NOT_FOUND )
1864 : {
1865 0 : pItem = (*mpItemList)[ nPos ];
1866 0 : if ( aTabBgColor != Color( COL_AUTO ) )
1867 : {
1868 0 : pItem->maTabBgColor = aTabBgColor;
1869 0 : if ( aTabBgColor.GetLuminance() <= 128 ) //Do not use aTabBgColor.IsDark(), because that threshold is way too low...
1870 0 : pItem->maTabTextColor = Color( COL_WHITE );
1871 : else
1872 0 : pItem->maTabTextColor = Color( COL_BLACK );
1873 : }
1874 : else
1875 : {
1876 0 : pItem->maTabBgColor = Color( COL_AUTO );
1877 0 : pItem->maTabTextColor = Color( COL_AUTO );
1878 : }
1879 : }
1880 0 : }
1881 :
1882 : // -----------------------------------------------------------------------
1883 :
1884 0 : void TabBar::RemovePage( sal_uInt16 nPageId )
1885 : {
1886 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1887 :
1888 : // Existiert Item
1889 0 : if ( nPos != PAGE_NOT_FOUND )
1890 : {
1891 0 : if ( mnCurPageId == nPageId )
1892 0 : mnCurPageId = 0;
1893 :
1894 : // Testen, ob erste sichtbare Seite verschoben werden muss
1895 0 : if ( mnFirstPos > nPos )
1896 0 : mnFirstPos--;
1897 :
1898 : // Item-Daten loeschen
1899 0 : ImplTabBarList::iterator it = mpItemList->begin();
1900 0 : ::std::advance( it, nPos );
1901 0 : delete *it;
1902 0 : mpItemList->erase( it );
1903 :
1904 : // Leiste neu ausgeben
1905 0 : if ( IsReallyVisible() && IsUpdateMode() )
1906 0 : Invalidate();
1907 :
1908 0 : CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
1909 : }
1910 0 : }
1911 :
1912 : // -----------------------------------------------------------------------
1913 :
1914 0 : void TabBar::MovePage( sal_uInt16 nPageId, sal_uInt16 nNewPos )
1915 : {
1916 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1917 0 : Pair aPair( nPos, nNewPos );
1918 :
1919 0 : if ( nPos < nNewPos )
1920 0 : nNewPos--;
1921 :
1922 0 : if ( nPos == nNewPos )
1923 0 : return;
1924 :
1925 : // Existiert Item
1926 0 : if ( nPos != PAGE_NOT_FOUND )
1927 : {
1928 : // TabBar-Item in der Liste verschieben
1929 0 : ImplTabBarList::iterator it = mpItemList->begin();
1930 0 : ::std::advance( it, nPos );
1931 0 : ImplTabBarItem* pItem = *it;
1932 0 : mpItemList->erase( it );
1933 0 : if ( nNewPos < mpItemList->size() ) {
1934 0 : it = mpItemList->begin();
1935 0 : ::std::advance( it, nNewPos );
1936 0 : mpItemList->insert( it, pItem );
1937 : } else {
1938 0 : mpItemList->push_back( pItem );
1939 : }
1940 :
1941 : // Leiste neu ausgeben
1942 0 : if ( IsReallyVisible() && IsUpdateMode() )
1943 0 : Invalidate();
1944 :
1945 0 : CallEventListeners( VCLEVENT_TABBAR_PAGEMOVED, (void*) &aPair );
1946 : }
1947 : }
1948 :
1949 : // -----------------------------------------------------------------------
1950 :
1951 4 : void TabBar::Clear()
1952 : {
1953 : // Alle Items loeschen
1954 14 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1955 10 : delete (*mpItemList)[ i ];
1956 : }
1957 4 : mpItemList->clear();
1958 :
1959 : // Items aus der Liste loeschen
1960 4 : mbSizeFormat = sal_True;
1961 4 : mnCurPageId = 0;
1962 4 : mnFirstPos = 0;
1963 4 : maCurrentItemList = 0;
1964 :
1965 : // Leiste neu ausgeben
1966 4 : if ( IsReallyVisible() && IsUpdateMode() )
1967 4 : Invalidate();
1968 :
1969 4 : CallEventListeners( VCLEVENT_TABBAR_PAGEREMOVED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(PAGE_NOT_FOUND)) );
1970 4 : }
1971 :
1972 : // -----------------------------------------------------------------------
1973 :
1974 0 : sal_Bool TabBar::IsPageEnabled( sal_uInt16 nPageId ) const
1975 : {
1976 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1977 :
1978 0 : if ( nPos != PAGE_NOT_FOUND )
1979 0 : return (*mpItemList)[ nPos ]->mbEnable;
1980 : else
1981 0 : return sal_False;
1982 : }
1983 :
1984 : // -----------------------------------------------------------------------
1985 :
1986 0 : void TabBar::SetPageBits( sal_uInt16 nPageId, TabBarPageBits nBits )
1987 : {
1988 0 : sal_uInt16 nPos = GetPagePos( nPageId );
1989 :
1990 0 : if ( nPos != PAGE_NOT_FOUND )
1991 : {
1992 0 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
1993 :
1994 0 : if ( pItem->mnBits != nBits )
1995 : {
1996 0 : pItem->mnBits = nBits;
1997 :
1998 : // Leiste neu ausgeben
1999 0 : if ( IsReallyVisible() && IsUpdateMode() )
2000 0 : Invalidate( pItem->maRect );
2001 : }
2002 : }
2003 0 : }
2004 :
2005 : // -----------------------------------------------------------------------
2006 :
2007 0 : TabBarPageBits TabBar::GetPageBits( sal_uInt16 nPageId ) const
2008 : {
2009 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2010 :
2011 0 : if ( nPos != PAGE_NOT_FOUND )
2012 0 : return (*mpItemList)[ nPos ]->mnBits;
2013 : else
2014 0 : return sal_False;
2015 : }
2016 :
2017 : // -----------------------------------------------------------------------
2018 :
2019 98 : sal_uInt16 TabBar::GetPageCount() const
2020 : {
2021 98 : return (sal_uInt16)mpItemList->size();
2022 : }
2023 :
2024 : // -----------------------------------------------------------------------
2025 :
2026 98 : sal_uInt16 TabBar::GetPageId( sal_uInt16 nPos ) const
2027 : {
2028 98 : return ( nPos < mpItemList->size() ) ? (*mpItemList)[ nPos ]->mnId : 0;
2029 : }
2030 :
2031 : // -----------------------------------------------------------------------
2032 :
2033 890 : sal_uInt16 TabBar::GetPagePos( sal_uInt16 nPageId ) const
2034 : {
2035 1514 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
2036 1514 : if ( (*mpItemList)[ i ]->mnId == nPageId ) {
2037 890 : return sal_uInt16( i );
2038 : }
2039 : }
2040 0 : return PAGE_NOT_FOUND;
2041 : }
2042 :
2043 : // -----------------------------------------------------------------------
2044 :
2045 0 : sal_uInt16 TabBar::GetPageId( const Point& rPos, bool bCheckInsTab ) const
2046 : {
2047 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
2048 : {
2049 0 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
2050 0 : if ( pItem->maRect.IsInside( rPos ) )
2051 0 : return pItem->mnId;
2052 : }
2053 :
2054 0 : if (bCheckInsTab && mbHasInsertTab && !mpItemList->empty())
2055 : {
2056 0 : ImplTabBarItem* pItem = mpItemList->back();
2057 0 : if (ImplGetInsertTabRect(pItem).IsInside(rPos))
2058 0 : return INSERT_TAB_POS;
2059 : }
2060 :
2061 0 : return 0;
2062 : }
2063 :
2064 : // -----------------------------------------------------------------------
2065 :
2066 0 : Rectangle TabBar::GetPageRect( sal_uInt16 nPageId ) const
2067 : {
2068 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2069 :
2070 0 : if ( nPos != PAGE_NOT_FOUND )
2071 0 : return (*mpItemList)[ nPos ]->maRect;
2072 : else
2073 0 : return Rectangle();
2074 : }
2075 :
2076 : // -----------------------------------------------------------------------
2077 :
2078 128 : void TabBar::SetCurPageId( sal_uInt16 nPageId )
2079 : {
2080 128 : sal_uInt16 nPos = GetPagePos( nPageId );
2081 :
2082 : // Wenn Item nicht existiert, dann nichts machen
2083 128 : if ( nPos != PAGE_NOT_FOUND )
2084 : {
2085 : // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir
2086 : // jetzt nichts mehr machen
2087 128 : if ( nPageId == mnCurPageId )
2088 246 : return;
2089 :
2090 : // Muss invalidiert werden
2091 10 : sal_Bool bUpdate = sal_False;
2092 10 : if ( IsReallyVisible() && IsUpdateMode() )
2093 10 : bUpdate = sal_True;
2094 :
2095 10 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2096 : ImplTabBarItem* pOldItem;
2097 :
2098 10 : if ( mnCurPageId )
2099 10 : pOldItem = (*mpItemList)[ GetPagePos( mnCurPageId ) ];
2100 : else
2101 0 : pOldItem = NULL;
2102 :
2103 : // Wenn Page nicht selektiert, dann vorher selektierte Seite
2104 : // deselktieren, wenn dies die einzige selektierte Seite ist
2105 10 : if ( !pItem->mbSelect && pOldItem )
2106 : {
2107 10 : sal_uInt16 nSelPageCount = GetSelectPageCount();
2108 10 : if ( nSelPageCount == 1 )
2109 6 : pOldItem->mbSelect = sal_False;
2110 10 : pItem->mbSelect = sal_True;
2111 : }
2112 :
2113 10 : mnCurPageId = nPageId;
2114 10 : mbFormat = sal_True;
2115 :
2116 : // Dafuer sorgen, das aktuelle Page sichtbar wird
2117 10 : if ( IsReallyVisible() )
2118 : {
2119 10 : if ( nPos < mnFirstPos )
2120 0 : SetFirstPageId( nPageId );
2121 : else
2122 : {
2123 : // sichtbare Breite berechnen
2124 10 : long nWidth = mnLastOffX;
2125 10 : if ( nWidth > TABBAR_OFFSET_X )
2126 10 : nWidth -= TABBAR_OFFSET_X;
2127 10 : if ( nWidth > ADDNEWPAGE_AREAWIDTH )
2128 10 : nWidth -= ADDNEWPAGE_AREAWIDTH;
2129 :
2130 10 : if ( pItem->maRect.IsEmpty() )
2131 4 : ImplFormat();
2132 :
2133 28 : while ( (mbMirrored ? (pItem->maRect.Left() < mnOffX) : (pItem->maRect.Right() > nWidth)) ||
2134 8 : pItem->maRect.IsEmpty() )
2135 : {
2136 2 : sal_uInt16 nNewPos = mnFirstPos+1;
2137 : // Dafuer sorgen, das min. die aktuelle TabPages als
2138 : // erste TabPage sichtbar ist
2139 2 : if ( nNewPos >= nPos )
2140 : {
2141 2 : SetFirstPageId( nPageId );
2142 2 : break;
2143 : }
2144 : else
2145 0 : SetFirstPageId( GetPageId( nNewPos ) );
2146 0 : ImplFormat();
2147 : // Falls erste Seite nicht weitergeschaltet wird, dann
2148 : // koennen wir abbrechen
2149 0 : if ( nNewPos != mnFirstPos )
2150 0 : break;
2151 : }
2152 : }
2153 : }
2154 :
2155 : // Leiste neu ausgeben
2156 10 : if ( bUpdate )
2157 : {
2158 10 : Invalidate( pItem->maRect );
2159 10 : if ( pOldItem )
2160 10 : Invalidate( pOldItem->maRect );
2161 : }
2162 : }
2163 : }
2164 :
2165 : // -----------------------------------------------------------------------
2166 :
2167 0 : void TabBar::MakeVisible( sal_uInt16 nPageId )
2168 : {
2169 0 : if ( !IsReallyVisible() )
2170 0 : return;
2171 :
2172 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2173 :
2174 : // Wenn Item nicht existiert, dann nichts machen
2175 0 : if ( nPos != PAGE_NOT_FOUND )
2176 : {
2177 0 : if ( nPos < mnFirstPos )
2178 0 : SetFirstPageId( nPageId );
2179 : else
2180 : {
2181 0 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2182 :
2183 : // sichtbare Breite berechnen
2184 0 : long nWidth = mnLastOffX;
2185 0 : if ( nWidth > TABBAR_OFFSET_X )
2186 0 : nWidth -= TABBAR_OFFSET_X;
2187 :
2188 0 : if ( mbFormat || pItem->maRect.IsEmpty() )
2189 : {
2190 0 : mbFormat = sal_True;
2191 0 : ImplFormat();
2192 : }
2193 :
2194 0 : while ( (pItem->maRect.Right() > nWidth) ||
2195 0 : pItem->maRect.IsEmpty() )
2196 : {
2197 0 : sal_uInt16 nNewPos = mnFirstPos+1;
2198 : // Dafuer sorgen, das min. die aktuelle TabPages als
2199 : // erste TabPage sichtbar ist
2200 0 : if ( nNewPos >= nPos )
2201 : {
2202 0 : SetFirstPageId( nPageId );
2203 0 : break;
2204 : }
2205 : else
2206 0 : SetFirstPageId( GetPageId( nNewPos ) );
2207 0 : ImplFormat();
2208 : // Falls erste Seite nicht weitergeschaltet wird, dann
2209 : // koennen wir abbrechen
2210 0 : if ( nNewPos != mnFirstPos )
2211 0 : break;
2212 : }
2213 : }
2214 : }
2215 : }
2216 :
2217 : // -----------------------------------------------------------------------
2218 :
2219 2 : void TabBar::SetFirstPageId( sal_uInt16 nPageId )
2220 : {
2221 2 : sal_uInt16 nPos = GetPagePos( nPageId );
2222 :
2223 : // Wenn Item nicht existiert, dann sal_False zurueckgeben
2224 2 : if ( nPos != PAGE_NOT_FOUND )
2225 : {
2226 2 : if ( nPos != mnFirstPos )
2227 : {
2228 : // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie
2229 : // moeglich sichtbar sind
2230 2 : ImplFormat();
2231 2 : sal_uInt16 nLastFirstPos = ImplGetLastFirstPos();
2232 : sal_uInt16 nNewPos;
2233 2 : if ( nPos > nLastFirstPos )
2234 0 : nNewPos = nLastFirstPos;
2235 : else
2236 2 : nNewPos = nPos;
2237 :
2238 2 : if ( nNewPos != mnFirstPos )
2239 : {
2240 2 : mnFirstPos = nNewPos;
2241 2 : mbFormat = sal_True;
2242 :
2243 : // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn
2244 : // dieses Flag gesetzt ist, wird direkt gepaintet)
2245 2 : if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos )
2246 2 : Invalidate();
2247 : }
2248 : }
2249 : }
2250 2 : }
2251 :
2252 : // -----------------------------------------------------------------------
2253 :
2254 74 : void TabBar::SelectPage( sal_uInt16 nPageId, sal_Bool bSelect )
2255 : {
2256 74 : sal_uInt16 nPos = GetPagePos( nPageId );
2257 :
2258 74 : if ( nPos != PAGE_NOT_FOUND )
2259 : {
2260 74 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2261 :
2262 74 : if ( pItem->mbSelect != bSelect )
2263 : {
2264 30 : pItem->mbSelect = bSelect;
2265 :
2266 : // Leiste neu ausgeben
2267 30 : if ( IsReallyVisible() && IsUpdateMode() )
2268 26 : Invalidate( pItem->maRect );
2269 : }
2270 : }
2271 74 : }
2272 :
2273 : // -----------------------------------------------------------------------
2274 :
2275 10 : sal_uInt16 TabBar::GetSelectPageCount() const
2276 : {
2277 10 : sal_uInt16 nSelected = 0;
2278 36 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
2279 : {
2280 26 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
2281 26 : if ( pItem->mbSelect )
2282 6 : nSelected++;
2283 : }
2284 :
2285 10 : return nSelected;
2286 : }
2287 :
2288 : // -----------------------------------------------------------------------
2289 :
2290 192 : sal_Bool TabBar::IsPageSelected( sal_uInt16 nPageId ) const
2291 : {
2292 192 : sal_uInt16 nPos = GetPagePos( nPageId );
2293 192 : if ( nPos != PAGE_NOT_FOUND )
2294 192 : return (*mpItemList)[ nPos ]->mbSelect;
2295 : else
2296 0 : return sal_False;
2297 : }
2298 :
2299 : // -----------------------------------------------------------------------
2300 :
2301 0 : sal_Bool TabBar::StartEditMode( sal_uInt16 nPageId )
2302 : {
2303 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2304 0 : if ( mpEdit || (nPos == PAGE_NOT_FOUND) || (mnLastOffX < 8) )
2305 0 : return sal_False;
2306 :
2307 0 : mnEditId = nPageId;
2308 0 : if ( StartRenaming() )
2309 : {
2310 0 : ImplShowPage( nPos );
2311 0 : ImplFormat();
2312 0 : Update();
2313 :
2314 0 : mpEdit = new TabBarEdit( this, WB_CENTER );
2315 0 : Rectangle aRect = GetPageRect( mnEditId );
2316 0 : long nX = aRect.Left()+TABBAR_OFFSET_X+(TABBAR_OFFSET_X2/2);
2317 0 : long nWidth = aRect.GetWidth()-(TABBAR_OFFSET_X*2)-TABBAR_OFFSET_X2;
2318 0 : if ( mnEditId != GetCurPageId() )
2319 0 : nX += 1;
2320 0 : if ( nX+nWidth > mnLastOffX )
2321 0 : nWidth = mnLastOffX-nX;
2322 0 : if ( nWidth < 3 )
2323 : {
2324 0 : nX = aRect.Left();
2325 0 : nWidth = aRect.GetWidth();
2326 : }
2327 0 : mpEdit->SetText( GetPageText( mnEditId ) );
2328 0 : mpEdit->setPosSizePixel( nX, aRect.Top()+mnOffY+1, nWidth, aRect.GetHeight()-3 );
2329 0 : Font aFont = GetPointFont();
2330 0 : Color aForegroundColor;
2331 0 : Color aBackgroundColor;
2332 0 : Color aFaceColor;
2333 0 : Color aSelectColor;
2334 0 : Color aFaceTextColor;
2335 0 : Color aSelectTextColor;
2336 0 : ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
2337 0 : if ( mnEditId != GetCurPageId() )
2338 0 : aFont.SetWeight( WEIGHT_LIGHT );
2339 0 : if ( IsPageSelected( mnEditId ) || (mnEditId == GetCurPageId()) )
2340 : {
2341 0 : aForegroundColor = aSelectTextColor;
2342 0 : aBackgroundColor = aSelectColor;
2343 : }
2344 : else
2345 : {
2346 0 : aForegroundColor = aFaceTextColor;
2347 0 : aBackgroundColor = aFaceColor;
2348 : }
2349 0 : if ( GetPageBits( mnEditId ) & TPB_SPECIAL )
2350 0 : aForegroundColor = Color( COL_LIGHTBLUE );
2351 0 : mpEdit->SetControlFont( aFont );
2352 0 : mpEdit->SetControlForeground( aForegroundColor );
2353 0 : mpEdit->SetControlBackground( aBackgroundColor );
2354 0 : mpEdit->GrabFocus();
2355 0 : mpEdit->SetSelection( Selection( 0, mpEdit->GetText().Len() ) );
2356 0 : mpEdit->Show();
2357 0 : return sal_True;
2358 : }
2359 : else
2360 : {
2361 0 : mnEditId = 0;
2362 0 : return sal_False;
2363 : }
2364 : }
2365 :
2366 : // -----------------------------------------------------------------------
2367 :
2368 26 : void TabBar::EndEditMode( sal_Bool bCancel )
2369 : {
2370 26 : if ( mpEdit )
2371 : {
2372 : // call hdl
2373 0 : sal_Bool bEnd = sal_True;
2374 0 : mbEditCanceled = bCancel;
2375 0 : maEditText = mpEdit->GetText();
2376 0 : mpEdit->SetPostEvent();
2377 0 : if ( !bCancel )
2378 : {
2379 0 : long nAllowRenaming = AllowRenaming();
2380 0 : if ( nAllowRenaming == TABBAR_RENAMING_YES )
2381 0 : SetPageText( mnEditId, maEditText );
2382 0 : else if ( nAllowRenaming == TABBAR_RENAMING_NO )
2383 0 : bEnd = sal_False;
2384 : else // nAllowRenaming == TABBAR_RENAMING_CANCEL
2385 0 : mbEditCanceled = sal_True;
2386 : }
2387 :
2388 : // renaming not allowed, than reset edit data
2389 0 : if ( !bEnd )
2390 : {
2391 0 : mpEdit->ResetPostEvent();
2392 0 : mpEdit->GrabFocus();
2393 : }
2394 : else
2395 : {
2396 : // close edit and call end hdl
2397 0 : delete mpEdit;
2398 0 : mpEdit = NULL;
2399 0 : EndRenaming();
2400 0 : mnEditId = 0;
2401 : }
2402 :
2403 : // reset
2404 0 : maEditText.Erase();
2405 0 : mbEditCanceled = sal_False;
2406 : }
2407 26 : }
2408 :
2409 : // -----------------------------------------------------------------------
2410 :
2411 174 : void TabBar::SetMirrored(bool bMirrored)
2412 : {
2413 174 : if( mbMirrored != bMirrored )
2414 : {
2415 0 : mbMirrored = bMirrored;
2416 0 : mbSizeFormat = true;
2417 0 : ImplInitControls(); // for button images
2418 0 : Resize(); // recalculates control positions
2419 0 : Mirror();
2420 : }
2421 174 : }
2422 :
2423 174 : void TabBar::SetEffectiveRTL( bool bRTL )
2424 : {
2425 174 : SetMirrored( bRTL != Application::GetSettings().GetLayoutRTL() );
2426 174 : }
2427 :
2428 0 : bool TabBar::IsEffectiveRTL() const
2429 : {
2430 0 : return IsMirrored() != Application::GetSettings().GetLayoutRTL();
2431 : }
2432 :
2433 : // -----------------------------------------------------------------------
2434 :
2435 0 : void TabBar::SetMaxPageWidth( long nMaxWidth )
2436 : {
2437 0 : if ( mnMaxPageWidth != nMaxWidth )
2438 : {
2439 0 : mnMaxPageWidth = nMaxWidth;
2440 0 : mbSizeFormat = sal_True;
2441 :
2442 : // Leiste neu ausgeben
2443 0 : if ( IsReallyVisible() && IsUpdateMode() )
2444 0 : Invalidate();
2445 : }
2446 0 : }
2447 :
2448 : // -----------------------------------------------------------------------
2449 :
2450 0 : void TabBar::SetPageText( sal_uInt16 nPageId, const OUString& rText )
2451 : {
2452 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2453 0 : if ( nPos != PAGE_NOT_FOUND )
2454 : {
2455 0 : (*mpItemList)[ nPos ]->maText = rText;
2456 0 : mbSizeFormat = sal_True;
2457 :
2458 : // Leiste neu ausgeben
2459 0 : if ( IsReallyVisible() && IsUpdateMode() )
2460 0 : Invalidate();
2461 :
2462 0 : CallEventListeners( VCLEVENT_TABBAR_PAGETEXTCHANGED, reinterpret_cast<void*>(sal::static_int_cast<sal_IntPtr>(nPageId)) );
2463 : }
2464 0 : }
2465 :
2466 : // -----------------------------------------------------------------------
2467 :
2468 240 : OUString TabBar::GetPageText( sal_uInt16 nPageId ) const
2469 : {
2470 240 : sal_uInt16 nPos = GetPagePos( nPageId );
2471 240 : if ( nPos != PAGE_NOT_FOUND )
2472 240 : return (*mpItemList)[ nPos ]->maText;
2473 0 : return OUString();
2474 : }
2475 :
2476 : // -----------------------------------------------------------------------
2477 :
2478 0 : XubString TabBar::GetHelpText( sal_uInt16 nPageId ) const
2479 : {
2480 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2481 0 : if ( nPos != PAGE_NOT_FOUND )
2482 : {
2483 0 : ImplTabBarItem* pItem = (*mpItemList)[ nPos ];
2484 0 : if (pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty())
2485 : {
2486 0 : Help* pHelp = Application::GetHelp();
2487 0 : if ( pHelp )
2488 0 : pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
2489 : }
2490 :
2491 0 : return pItem->maHelpText;
2492 : }
2493 0 : return OUString();
2494 : }
2495 :
2496 : // -----------------------------------------------------------------------
2497 :
2498 0 : rtl::OString TabBar::GetHelpId( sal_uInt16 nPageId ) const
2499 : {
2500 0 : sal_uInt16 nPos = GetPagePos( nPageId );
2501 0 : rtl::OString aRet;
2502 0 : if ( nPos != PAGE_NOT_FOUND )
2503 0 : return (*mpItemList)[ nPos ]->maHelpId;
2504 0 : return aRet;
2505 : }
2506 :
2507 : // -----------------------------------------------------------------------
2508 :
2509 0 : sal_Bool TabBar::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
2510 : {
2511 0 : if ( !(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != COMMAND_STARTDRAG) )
2512 0 : return sal_False;
2513 :
2514 : // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
2515 : // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
2516 : // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
2517 : // dies nur bei einer Mausaktion.
2518 : // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde,
2519 : // da der Select schon den Bereich gescrollt haben kann
2520 0 : if ( rCEvt.IsMouseEvent() && !mbInSelect )
2521 : {
2522 0 : sal_uInt16 nSelId = GetPageId( rCEvt.GetMousePosPixel() );
2523 :
2524 : // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
2525 0 : if ( !nSelId )
2526 0 : return sal_False;
2527 :
2528 : // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
2529 : // Seite setzen und Select rufen.
2530 0 : if ( !IsPageSelected( nSelId ) )
2531 : {
2532 0 : if ( ImplDeactivatePage() )
2533 : {
2534 0 : SetCurPageId( nSelId );
2535 0 : Update();
2536 0 : ImplActivatePage();
2537 0 : ImplSelect();
2538 : }
2539 : else
2540 0 : return sal_False;
2541 : }
2542 : }
2543 0 : mbInSelect = sal_False;
2544 :
2545 0 : Region aRegion;
2546 :
2547 : // Region zuweisen
2548 0 : rRegion = aRegion;
2549 :
2550 0 : return sal_True;
2551 : }
2552 :
2553 : // -----------------------------------------------------------------------
2554 :
2555 0 : sal_uInt16 TabBar::ShowDropPos( const Point& rPos )
2556 : {
2557 : ImplTabBarItem* pItem;
2558 : sal_uInt16 nDropId;
2559 : sal_uInt16 nNewDropPos;
2560 0 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
2561 0 : short nScroll = 0;
2562 :
2563 0 : if ( rPos.X() > mnLastOffX-TABBAR_DRAG_SCROLLOFF )
2564 : {
2565 0 : pItem = (*mpItemList)[ mpItemList->size()-1 ];
2566 0 : if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) )
2567 0 : nNewDropPos = (sal_uInt16)mpItemList->size();
2568 : else
2569 : {
2570 0 : nNewDropPos = mnFirstPos+1;
2571 0 : nScroll = 1;
2572 : }
2573 : }
2574 0 : else if ( (rPos.X() <= mnOffX) ||
2575 0 : (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)) )
2576 : {
2577 0 : if ( mnFirstPos )
2578 : {
2579 0 : nNewDropPos = mnFirstPos;
2580 0 : nScroll = -1;
2581 : }
2582 : else
2583 0 : nNewDropPos = 0;
2584 : }
2585 : else
2586 : {
2587 0 : nDropId = GetPageId( rPos );
2588 0 : if ( nDropId )
2589 : {
2590 0 : nNewDropPos = GetPagePos( nDropId );
2591 0 : if ( mnFirstPos && (nNewDropPos == mnFirstPos-1) )
2592 0 : nScroll = -1;
2593 : }
2594 : else
2595 0 : nNewDropPos = nItemCount;
2596 : }
2597 :
2598 0 : if ( mbDropPos && (nNewDropPos == mnDropPos) && !nScroll )
2599 0 : return mnDropPos;
2600 :
2601 0 : if ( mbDropPos )
2602 0 : HideDropPos();
2603 0 : mbDropPos = sal_True;
2604 0 : mnDropPos = nNewDropPos;
2605 :
2606 0 : if ( nScroll )
2607 : {
2608 0 : sal_uInt16 nOldFirstPos = mnFirstPos;
2609 0 : SetFirstPageId( GetPageId( mnFirstPos+nScroll ) );
2610 :
2611 : // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich
2612 0 : if ( nOldFirstPos != mnFirstPos )
2613 : {
2614 0 : Rectangle aRect( mnOffX, 0, mnLastOffX, maWinSize.Height() );
2615 0 : SetFillColor( GetBackground().GetColor() );
2616 0 : DrawRect( aRect );
2617 0 : Paint( aRect );
2618 : }
2619 : }
2620 :
2621 : // Drop-Position-Pfeile ausgeben
2622 0 : Color aBlackColor( COL_BLACK );
2623 : long nX;
2624 0 : long nY = (maWinSize.Height()/2)-1;
2625 0 : sal_uInt16 nCurPos = GetPagePos( mnCurPageId );
2626 :
2627 0 : SetLineColor( aBlackColor );
2628 0 : if ( mnDropPos < nItemCount )
2629 : {
2630 0 : pItem = (*mpItemList)[ mnDropPos ];
2631 0 : nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
2632 0 : if ( mnDropPos == nCurPos )
2633 0 : nX--;
2634 : else
2635 0 : nX++;
2636 0 : if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
2637 0 : SetLineColor( pItem->maTabTextColor );
2638 0 : DrawLine( Point( nX, nY ), Point( nX, nY ) );
2639 0 : DrawLine( Point( nX+1, nY-1 ), Point( nX+1, nY+1 ) );
2640 0 : DrawLine( Point( nX+2, nY-2 ), Point( nX+2, nY+2 ) );
2641 0 : SetLineColor( aBlackColor );
2642 : }
2643 0 : if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2644 : {
2645 0 : pItem = (*mpItemList)[ mnDropPos-1 ];
2646 0 : nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
2647 0 : if ( mnDropPos == nCurPos )
2648 0 : nX++;
2649 0 : if ( !pItem->IsDefaultTabBgColor() && !pItem->mbSelect)
2650 0 : SetLineColor( pItem->maTabTextColor );
2651 0 : DrawLine( Point( nX, nY ), Point( nX, nY ) );
2652 0 : DrawLine( Point( nX-1, nY-1 ), Point( nX-1, nY+1 ) );
2653 0 : DrawLine( Point( nX-2, nY-2 ), Point( nX-2, nY+2 ) );
2654 : }
2655 :
2656 0 : return mnDropPos;
2657 : }
2658 :
2659 : // -----------------------------------------------------------------------
2660 :
2661 0 : void TabBar::HideDropPos()
2662 : {
2663 0 : if ( mbDropPos )
2664 : {
2665 : ImplTabBarItem* pItem;
2666 : long nX;
2667 0 : long nY1 = (maWinSize.Height()/2)-3;
2668 0 : long nY2 = nY1 + 5;
2669 0 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
2670 :
2671 0 : if ( mnDropPos < nItemCount )
2672 : {
2673 0 : pItem = (*mpItemList)[ mnDropPos ];
2674 0 : nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
2675 : // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2676 : // moeglich
2677 0 : Rectangle aRect( nX-1, nY1, nX+3, nY2 );
2678 0 : Region aRegion( aRect );
2679 0 : SetClipRegion( aRegion );
2680 0 : Paint( aRect );
2681 0 : SetClipRegion();
2682 : }
2683 0 : if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
2684 : {
2685 0 : pItem = (*mpItemList)[ mnDropPos-1 ];
2686 0 : nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
2687 : // Paint direkt aufrufen, da bei Drag and Drop kein Paint
2688 : // moeglich
2689 0 : Rectangle aRect( nX-2, nY1, nX+1, nY2 );
2690 0 : Region aRegion( aRect );
2691 0 : SetClipRegion( aRegion );
2692 0 : Paint( aRect );
2693 0 : SetClipRegion();
2694 : }
2695 :
2696 0 : mbDropPos = sal_False;
2697 0 : mnDropPos = 0;
2698 : }
2699 0 : }
2700 :
2701 : // -----------------------------------------------------------------------
2702 :
2703 0 : sal_Bool TabBar::SwitchPage( const Point& rPos )
2704 : {
2705 0 : sal_Bool bSwitch = sal_False;
2706 0 : sal_uInt16 nSwitchId = GetPageId( rPos );
2707 0 : if ( !nSwitchId )
2708 0 : EndSwitchPage();
2709 : else
2710 : {
2711 0 : if ( nSwitchId != mnSwitchId )
2712 : {
2713 0 : mnSwitchId = nSwitchId;
2714 0 : mnSwitchTime = Time::GetSystemTicks();
2715 : }
2716 : else
2717 : {
2718 : // Erst nach 500 ms umschalten
2719 0 : if ( mnSwitchId != GetCurPageId() )
2720 : {
2721 0 : if ( Time::GetSystemTicks() > mnSwitchTime+500 )
2722 : {
2723 0 : mbInSwitching = sal_True;
2724 0 : if ( ImplDeactivatePage() )
2725 : {
2726 0 : SetCurPageId( mnSwitchId );
2727 0 : Update();
2728 0 : ImplActivatePage();
2729 0 : ImplSelect();
2730 0 : bSwitch = sal_True;
2731 : }
2732 0 : mbInSwitching = sal_False;
2733 : }
2734 : }
2735 : }
2736 : }
2737 :
2738 0 : return bSwitch;
2739 : }
2740 :
2741 : // -----------------------------------------------------------------------
2742 :
2743 0 : void TabBar::EndSwitchPage()
2744 : {
2745 0 : mnSwitchTime = 0;
2746 0 : mnSwitchId = 0;
2747 0 : }
2748 :
2749 : // -----------------------------------------------------------------------
2750 :
2751 98 : void TabBar::SetStyle( WinBits nStyle )
2752 : {
2753 98 : mnWinStyle = nStyle;
2754 98 : ImplInitControls();
2755 : // Evt. Controls neu anordnen
2756 98 : if ( IsReallyVisible() && IsUpdateMode() )
2757 60 : Resize();
2758 98 : }
2759 :
2760 : // -----------------------------------------------------------------------
2761 :
2762 30 : Size TabBar::CalcWindowSizePixel() const
2763 : {
2764 30 : long nWidth = 0;
2765 :
2766 30 : if ( mpItemList->size() )
2767 : {
2768 0 : ((TabBar*)this)->ImplCalcWidth();
2769 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
2770 : {
2771 0 : ImplTabBarItem* pItem = (*mpItemList)[ i ];
2772 0 : nWidth += pItem->mnWidth;
2773 : }
2774 0 : nWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
2775 : }
2776 :
2777 30 : return Size( nWidth, GetSettings().GetStyleSettings().GetScrollBarSize() );
2778 : }
2779 : // -----------------------------------------------------------------------
2780 :
2781 48 : Rectangle TabBar::GetPageArea() const
2782 : {
2783 48 : return Rectangle( Point( mnOffX, mnOffY ), Size( mnLastOffX-mnOffX+1, GetSizePixel().Height()-mnOffY ) );
2784 : }
2785 :
2786 : // -----------------------------------------------------------------------
2787 :
2788 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > TabBar::CreateAccessible()
2789 : {
2790 0 : return mpImpl->maAccessibleFactory.getFactory().createAccessibleTabBar( *this );
2791 : }
2792 :
2793 : // -----------------------------------------------------------------------
2794 :
2795 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|