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 : #define _SV_HEADBAR_CXX
22 : #include <svtools/headbar.hxx>
23 : #include <tools/debug.hxx>
24 :
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/help.hxx>
27 : #include <vcl/image.hxx>
28 : #include <vcl/salnativewidgets.hxx>
29 : #include <com/sun/star/accessibility/XAccessible.hpp>
30 :
31 : // =======================================================================
32 :
33 0 : class ImplHeadItem
34 : {
35 : public:
36 : sal_uInt16 mnId;
37 : HeaderBarItemBits mnBits;
38 : long mnSize;
39 : rtl::OString maHelpId;
40 : Image maImage;
41 : XubString maOutText;
42 : XubString maText;
43 : XubString maHelpText;
44 : };
45 :
46 : // =======================================================================
47 :
48 : #define HEAD_ARROWSIZE1 4
49 : #define HEAD_ARROWSIZE2 7
50 :
51 : #define HEADERBAR_TEXTOFF 2
52 : #define HEADERBAR_ARROWOFF 5
53 : #define HEADERBAR_SPLITOFF 3
54 :
55 : #define HEADERBAR_DRAGOFF 4
56 : #define HEADERBAR_DRAGOUTOFF 15
57 :
58 : #define HEAD_HITTEST_ITEM ((sal_uInt16)0x0001)
59 : #define HEAD_HITTEST_DIVIDER ((sal_uInt16)0x0002)
60 :
61 : // =======================================================================
62 :
63 0 : void HeaderBar::ImplInit( WinBits nWinStyle )
64 : {
65 0 : mpItemList = new ImplHeadItemList;
66 0 : mnBorderOff1 = 0;
67 0 : mnBorderOff2 = 0;
68 0 : mnOffset = 0;
69 0 : mnDX = 0;
70 0 : mnDY = 0;
71 0 : mnDragSize = 0;
72 0 : mnStartPos = 0;
73 0 : mnDragPos = 0;
74 0 : mnMouseOff = 0;
75 0 : mnCurItemId = 0;
76 0 : mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
77 0 : mbDrag = sal_False;
78 0 : mbItemDrag = sal_False;
79 0 : mbOutDrag = sal_False;
80 0 : mbItemMode = sal_False;
81 :
82 : // StyleBits auswerten
83 0 : if ( nWinStyle & WB_DRAG )
84 0 : mbDragable = sal_True;
85 : else
86 0 : mbDragable = sal_False;
87 0 : if ( nWinStyle & WB_BUTTONSTYLE )
88 0 : mbButtonStyle = sal_True;
89 : else
90 0 : mbButtonStyle = sal_False;
91 0 : if ( nWinStyle & WB_BORDER )
92 : {
93 0 : mnBorderOff1 = 1;
94 0 : mnBorderOff2 = 1;
95 : }
96 : else
97 : {
98 0 : if ( nWinStyle & WB_BOTTOMBORDER )
99 0 : mnBorderOff2 = 1;
100 : }
101 :
102 0 : ImplInitSettings( sal_True, sal_True, sal_True );
103 0 : }
104 :
105 : // -----------------------------------------------------------------------
106 :
107 0 : HeaderBar::HeaderBar( Window* pParent, WinBits nWinStyle ) :
108 0 : Window( pParent, nWinStyle & WB_3DLOOK )
109 : {
110 0 : ImplInit( nWinStyle );
111 0 : SetSizePixel( CalcWindowSizePixel() );
112 0 : }
113 :
114 : // -----------------------------------------------------------------------
115 :
116 0 : HeaderBar::HeaderBar( Window* pParent, const ResId& rResId ) :
117 0 : Window( pParent, rResId )
118 : {
119 0 : ImplInit( rResId.GetWinBits() );
120 0 : }
121 :
122 : // -----------------------------------------------------------------------
123 :
124 0 : HeaderBar::~HeaderBar()
125 : {
126 : // Alle Items loeschen
127 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
128 0 : delete (*mpItemList)[ i ];
129 : }
130 0 : mpItemList->clear();
131 0 : delete mpItemList;
132 0 : }
133 :
134 : // -----------------------------------------------------------------------
135 :
136 0 : void HeaderBar::ImplInitSettings( sal_Bool bFont,
137 : sal_Bool bForeground, sal_Bool bBackground )
138 : {
139 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
140 :
141 0 : if ( bFont )
142 : {
143 0 : Font aFont;
144 0 : aFont = rStyleSettings.GetToolFont();
145 0 : if ( IsControlFont() )
146 0 : aFont.Merge( GetControlFont() );
147 0 : SetZoomedPointFont( aFont );
148 : }
149 :
150 0 : if ( bForeground || bFont )
151 : {
152 0 : Color aColor;
153 0 : if ( IsControlForeground() )
154 0 : aColor = GetControlForeground();
155 : else
156 0 : aColor = rStyleSettings.GetButtonTextColor();
157 0 : SetTextColor( aColor );
158 0 : SetTextFillColor();
159 : }
160 :
161 0 : if ( bBackground )
162 : {
163 0 : Color aColor;
164 0 : if ( IsControlBackground() )
165 0 : aColor = GetControlBackground();
166 : else
167 0 : aColor = rStyleSettings.GetFaceColor();
168 0 : SetBackground( aColor );
169 : }
170 0 : }
171 :
172 : // -----------------------------------------------------------------------
173 :
174 0 : long HeaderBar::ImplGetItemPos( sal_uInt16 nPos ) const
175 : {
176 0 : long nX = -mnOffset;
177 0 : for ( size_t i = 0; i < nPos; i++ )
178 0 : nX += (*mpItemList)[ i ]->mnSize;
179 0 : return nX;
180 : }
181 :
182 : // -----------------------------------------------------------------------
183 :
184 0 : Rectangle HeaderBar::ImplGetItemRect( sal_uInt16 nPos ) const
185 : {
186 0 : Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 );
187 0 : aRect.Right() = aRect.Left() + (*mpItemList)[ nPos ]->mnSize - 1;
188 : // Gegen Ueberlauf auf einigen Systemen testen
189 0 : if ( aRect.Right() > 16000 )
190 0 : aRect.Right() = 16000;
191 0 : return aRect;
192 : }
193 :
194 : // -----------------------------------------------------------------------
195 :
196 0 : sal_uInt16 HeaderBar::ImplHitTest( const Point& rPos,
197 : long& nMouseOff, sal_uInt16& nPos ) const
198 : {
199 : ImplHeadItem* pItem;
200 0 : size_t nCount = (sal_uInt16)mpItemList->size();
201 0 : sal_Bool bLastFixed = sal_True;
202 0 : long nX = -mnOffset;
203 :
204 0 : for ( size_t i = 0; i < nCount; i++ )
205 : {
206 0 : pItem = (*mpItemList)[ i ];
207 :
208 0 : if ( rPos.X() < (nX+pItem->mnSize) )
209 : {
210 : sal_uInt16 nMode;
211 :
212 0 : if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
213 : {
214 0 : nMode = HEAD_HITTEST_DIVIDER;
215 0 : nPos = i-1;
216 0 : nMouseOff = rPos.X()-nX+1;
217 : }
218 : else
219 : {
220 0 : nPos = i;
221 :
222 0 : if ( !(pItem->mnBits & HIB_FIXED) && (rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF)) )
223 : {
224 0 : nMode = HEAD_HITTEST_DIVIDER;
225 0 : nMouseOff = rPos.X()-(nX+pItem->mnSize);
226 : }
227 : else
228 : {
229 0 : nMode = HEAD_HITTEST_ITEM;
230 0 : nMouseOff = rPos.X()-nX;
231 : }
232 : }
233 :
234 0 : return nMode;
235 : }
236 :
237 0 : if ( pItem->mnBits & HIB_FIXED )
238 0 : bLastFixed = sal_True;
239 : else
240 0 : bLastFixed = sal_False;
241 :
242 0 : nX += pItem->mnSize;
243 : }
244 :
245 0 : if ( !bLastFixed )
246 : {
247 0 : pItem = (*mpItemList)[ nCount-1 ];
248 0 : if ( (pItem->mnSize < 4) && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
249 : {
250 0 : nPos = nCount-1;
251 0 : nMouseOff = rPos.X()-nX+1;
252 0 : return HEAD_HITTEST_DIVIDER;
253 : }
254 : }
255 :
256 0 : return 0;
257 : }
258 :
259 : // -----------------------------------------------------------------------
260 :
261 0 : void HeaderBar::ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos )
262 : {
263 0 : Rectangle aRect1 = ImplGetItemRect( nStartPos );
264 0 : Rectangle aRect2 = ImplGetItemRect( nEndPos );
265 0 : Point aStartPos = aRect1.Center();
266 0 : Point aEndPos = aStartPos;
267 0 : Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2,
268 0 : aStartPos.X()+2, aStartPos.Y()+2 );
269 :
270 0 : if ( nEndPos > nStartPos )
271 : {
272 0 : aStartPos.X() += 3;
273 0 : aEndPos.X() = aRect2.Right()-6;
274 : }
275 : else
276 : {
277 0 : aStartPos.X() -= 3;
278 0 : aEndPos.X() = aRect2.Left()+6;
279 : }
280 :
281 0 : SetRasterOp( ROP_INVERT );
282 0 : DrawRect( aStartRect );
283 0 : DrawLine( aStartPos, aEndPos );
284 0 : if ( nEndPos > nStartPos )
285 : {
286 0 : DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ),
287 0 : Point( aEndPos.X()+1, aEndPos.Y()+3 ) );
288 0 : DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ),
289 0 : Point( aEndPos.X()+2, aEndPos.Y()+2 ) );
290 0 : DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ),
291 0 : Point( aEndPos.X()+3, aEndPos.Y()+1 ) );
292 0 : DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) );
293 : }
294 : else
295 : {
296 0 : DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ),
297 0 : Point( aEndPos.X()-1, aEndPos.Y()+3 ) );
298 0 : DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ),
299 0 : Point( aEndPos.X()-2, aEndPos.Y()+2 ) );
300 0 : DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ),
301 0 : Point( aEndPos.X()-3, aEndPos.Y()+1 ) );
302 0 : DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) );
303 : }
304 0 : SetRasterOp( ROP_OVERPAINT );
305 0 : }
306 :
307 : // -----------------------------------------------------------------------
308 :
309 0 : void HeaderBar::ImplDrawItem( OutputDevice* pDev,
310 : sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag,
311 : const Rectangle& rItemRect,
312 : const Rectangle* pRect,
313 : sal_uLong )
314 : {
315 0 : Window *const pWin = (pDev->GetOutDevType()==OUTDEV_WINDOW) ? (Window*) pDev : NULL;
316 0 : ImplControlValue aControlValue(0);
317 0 : Rectangle aCtrlRegion;
318 0 : ControlState nState(0);
319 :
320 0 : Rectangle aRect = rItemRect;
321 :
322 : // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
323 0 : if ( aRect.GetWidth() <= 1 )
324 : return;
325 :
326 : // Feststellen, ob Rectangle ueberhaupt sichtbar
327 0 : if ( pRect )
328 : {
329 0 : if ( aRect.Right() < pRect->Left() )
330 : return;
331 0 : else if ( aRect.Left() > pRect->Right() )
332 : return;
333 : }
334 : else
335 : {
336 0 : if ( aRect.Right() < 0 )
337 : return;
338 0 : else if ( aRect.Left() > mnDX )
339 : return;
340 : }
341 :
342 0 : ImplHeadItem* pItem = (*mpItemList)[ nPos ];
343 0 : HeaderBarItemBits nBits = pItem->mnBits;
344 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
345 :
346 0 : if( pWin && pWin->IsNativeControlSupported(CTRL_WINDOW_BACKGROUND, PART_ENTIRE_CONTROL) )
347 : {
348 0 : aCtrlRegion=aRect;
349 : pWin->DrawNativeControl( CTRL_WINDOW_BACKGROUND, PART_ENTIRE_CONTROL,
350 : aCtrlRegion, nState, aControlValue,
351 0 : rtl::OUString() );
352 :
353 : }
354 : else
355 : {
356 : // Border muss nicht gemalt werden
357 0 : aRect.Top() += mnBorderOff1;
358 0 : aRect.Bottom() -= mnBorderOff2;
359 :
360 : // Hintergrund loeschen
361 0 : if ( !pRect || bDrag )
362 : {
363 0 : if ( bDrag )
364 : {
365 0 : pDev->SetLineColor();
366 0 : pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
367 0 : pDev->DrawRect( aRect );
368 : }
369 : else
370 0 : pDev->DrawWallpaper( aRect, GetBackground() );
371 : }
372 : }
373 :
374 0 : Color aSelectionTextColor( COL_TRANSPARENT );
375 :
376 0 : if( pWin && pWin->IsNativeControlSupported(CTRL_LISTHEADER, PART_BUTTON) )
377 : {
378 0 : aCtrlRegion=aRect;
379 0 : aControlValue.setTristateVal(BUTTONVALUE_ON);
380 0 : nState|=CTRL_STATE_ENABLED;
381 0 : if(bHigh)
382 0 : nState|=CTRL_STATE_PRESSED;
383 : pWin->DrawNativeControl( CTRL_LISTHEADER, PART_BUTTON,
384 : aCtrlRegion, nState, aControlValue,
385 0 : rtl::OUString() );
386 : }
387 : else
388 : {
389 : // Trennlinie malen
390 0 : pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
391 0 : pDev->DrawLine( Point( aRect.Right(), aRect.Top() ),
392 0 : Point( aRect.Right(), aRect.Bottom() ) );
393 :
394 : // ButtonStyle malen
395 : // avoid 3D borders
396 0 : if( bHigh )
397 0 : DrawSelectionBackground( aRect, 1, sal_True, sal_False, sal_False, &aSelectionTextColor );
398 0 : else if ( !mbButtonStyle || (nBits & HIB_FLAT) )
399 0 : DrawSelectionBackground( aRect, 0, sal_True, sal_False, sal_False, &aSelectionTextColor );
400 : }
401 :
402 : // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
403 0 : if ( aRect.GetWidth() < 1 )
404 : return;
405 :
406 : // Positionen und Groessen berechnen und Inhalt ausgeben
407 0 : pItem->maOutText = pItem->maText;
408 0 : Size aImageSize = pItem->maImage.GetSizePixel();
409 0 : Size aTxtSize( pDev->GetTextWidth( pItem->maOutText ), 0 );
410 0 : if ( pItem->maOutText.Len() )
411 0 : aTxtSize.Height() = pDev->GetTextHeight();
412 0 : long nArrowWidth = 0;
413 0 : if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
414 0 : nArrowWidth = HEAD_ARROWSIZE2+HEADERBAR_ARROWOFF;
415 :
416 : // Wenn kein Platz fuer Image, dann nicht ausgeben
417 0 : long nTestHeight = aImageSize.Height();
418 0 : if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
419 0 : nTestHeight += aTxtSize.Height();
420 0 : if ( (aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()) )
421 : {
422 0 : aImageSize.Width() = 0;
423 0 : aImageSize.Height() = 0;
424 : }
425 :
426 : // Text auf entsprechende Laenge kuerzen
427 0 : sal_Bool bLeftText = sal_False;
428 0 : long nMaxTxtWidth = aRect.GetWidth()-(HEADERBAR_TEXTOFF*2)-nArrowWidth;
429 0 : if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
430 0 : nMaxTxtWidth -= aImageSize.Width();
431 0 : long nTxtWidth = aTxtSize.Width();
432 0 : if ( nTxtWidth > nMaxTxtWidth )
433 : {
434 0 : bLeftText = sal_True;
435 : // 3 == Len of "..."
436 0 : pItem->maOutText.AppendAscii( "..." );
437 0 : do
438 : {
439 0 : pItem->maOutText.Erase( pItem->maOutText.Len()-3-1, 1 );
440 0 : nTxtWidth = pDev->GetTextWidth( pItem->maOutText );
441 : }
442 0 : while ( (nTxtWidth > nMaxTxtWidth) && (pItem->maOutText.Len() > 3) );
443 0 : if ( pItem->maOutText.Len() == 3 )
444 : {
445 0 : nTxtWidth = 0;
446 0 : pItem->maOutText.Erase();
447 : }
448 : }
449 :
450 : // Text/Imageposition berechnen
451 : long nTxtPos;
452 0 : if ( !bLeftText && (nBits & HIB_RIGHT) )
453 : {
454 0 : nTxtPos = aRect.Right()-nTxtWidth-HEADERBAR_TEXTOFF;
455 0 : if ( nBits & HIB_RIGHTIMAGE )
456 0 : nTxtPos -= aImageSize.Width();
457 : }
458 0 : else if ( !bLeftText && (nBits & HIB_CENTER) )
459 : {
460 0 : long nTempWidth = nTxtWidth;
461 0 : if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
462 0 : nTempWidth += aImageSize.Width();
463 0 : nTxtPos = aRect.Left()+(aRect.GetWidth()-nTempWidth)/2;
464 0 : if ( nBits & HIB_LEFTIMAGE )
465 0 : nTxtPos += aImageSize.Width();
466 0 : if ( nArrowWidth )
467 : {
468 0 : if ( nTxtPos+nTxtWidth+nArrowWidth >= aRect.Right() )
469 : {
470 0 : nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
471 0 : if ( nBits & HIB_LEFTIMAGE )
472 0 : nTxtPos += aImageSize.Width();
473 : }
474 0 : }
475 : }
476 : else
477 : {
478 0 : nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
479 0 : if ( nBits & HIB_LEFTIMAGE )
480 0 : nTxtPos += aImageSize.Width();
481 0 : if ( nBits & HIB_RIGHT )
482 0 : nTxtPos += nArrowWidth;
483 : }
484 :
485 : // TextPosition berechnen
486 0 : long nTxtPosY = 0;
487 0 : if ( pItem->maOutText.Len() || (nArrowWidth && aTxtSize.Height()) )
488 : {
489 0 : if ( nBits & HIB_TOP )
490 : {
491 0 : nTxtPosY = aRect.Top();
492 0 : if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
493 0 : nTxtPosY += aImageSize.Height();
494 : }
495 0 : else if ( nBits & HIB_BOTTOM )
496 0 : nTxtPosY = aRect.Bottom()-aTxtSize.Height();
497 : else
498 : {
499 0 : long nTempHeight = aTxtSize.Height();
500 0 : if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
501 0 : nTempHeight += aImageSize.Height();
502 0 : nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
503 0 : if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
504 0 : nTxtPosY += aImageSize.Height();
505 : }
506 : }
507 :
508 : // Text ausgebeben
509 0 : if ( pItem->maOutText.Len() )
510 : {
511 0 : if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
512 : {
513 0 : pDev->Push( PUSH_TEXTCOLOR );
514 0 : pDev->SetTextColor( aSelectionTextColor );
515 : }
516 0 : if ( IsEnabled() )
517 0 : pDev->DrawText( Point( nTxtPos, nTxtPosY ), pItem->maOutText );
518 : else
519 0 : pDev->DrawCtrlText( Point( nTxtPos, nTxtPosY ), pItem->maOutText, 0, STRING_LEN, TEXT_DRAW_DISABLE );
520 0 : if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
521 0 : pDev->Pop();
522 : }
523 :
524 : // Wenn Image vorhanden, Position berechnen und ausgeben
525 0 : long nImagePosY = 0;
526 0 : if ( aImageSize.Width() && aImageSize.Height() )
527 : {
528 0 : long nImagePos = nTxtPos;
529 0 : if ( nBits & HIB_LEFTIMAGE )
530 : {
531 0 : nImagePos -= aImageSize.Width();
532 0 : if ( nBits & HIB_RIGHT )
533 0 : nImagePos -= nArrowWidth;
534 : }
535 0 : else if ( nBits & HIB_RIGHTIMAGE )
536 : {
537 0 : nImagePos += nTxtWidth;
538 0 : if ( !(nBits & HIB_RIGHT) )
539 0 : nImagePos += nArrowWidth;
540 : }
541 : else
542 : {
543 0 : if ( nBits & HIB_RIGHT )
544 0 : nImagePos = aRect.Right()-aImageSize.Width();
545 0 : else if ( nBits & HIB_CENTER )
546 0 : nImagePos = aRect.Left()+(aRect.GetWidth()-aImageSize.Width())/2;
547 : else
548 0 : nImagePos = aRect.Left()+HEADERBAR_TEXTOFF;
549 : }
550 :
551 0 : if ( nBits & HIB_TOP )
552 0 : nImagePosY = aRect.Top();
553 0 : else if ( nBits & HIB_BOTTOM )
554 : {
555 0 : nImagePosY = aRect.Bottom()-aImageSize.Height();
556 0 : if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
557 0 : nImagePosY -= aTxtSize.Height();
558 : }
559 : else
560 : {
561 0 : long nTempHeight = aImageSize.Height();
562 0 : if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
563 0 : nTempHeight += aTxtSize.Height();
564 0 : nImagePosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
565 : }
566 0 : if ( nImagePos+aImageSize.Width() <= aRect.Right() )
567 : {
568 0 : sal_uInt16 nStyle = 0;
569 0 : if ( !IsEnabled() )
570 0 : nStyle |= IMAGE_DRAW_DISABLE;
571 0 : pDev->DrawImage( Point( nImagePos, nImagePosY ), pItem->maImage, nStyle );
572 : }
573 : }
574 :
575 0 : if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
576 : {
577 0 : long nArrowX = nTxtPos;
578 0 : if ( nBits & HIB_RIGHT )
579 0 : nArrowX -= nArrowWidth;
580 : else
581 0 : nArrowX += nTxtWidth+HEADERBAR_ARROWOFF;
582 0 : if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && !pItem->maText.Len() )
583 : {
584 0 : if ( nBits & HIB_RIGHT )
585 0 : nArrowX -= aImageSize.Width();
586 : else
587 0 : nArrowX += aImageSize.Width();
588 : }
589 :
590 : // Feststellen, ob Platz genug ist, das Item zu malen
591 0 : sal_Bool bDraw = sal_True;
592 0 : if ( nArrowX < aRect.Left()+HEADERBAR_TEXTOFF )
593 0 : bDraw = sal_False;
594 0 : else if ( nArrowX+HEAD_ARROWSIZE2 > aRect.Right() )
595 0 : bDraw = sal_False;
596 :
597 0 : if ( bDraw )
598 : {
599 0 : if( pWin && pWin->IsNativeControlSupported(CTRL_LISTHEADER, PART_ARROW) )
600 : {
601 0 : aCtrlRegion=Rectangle(Point(nArrowX,aRect.Top()),Size(nArrowWidth,aRect.GetHeight()));
602 : // control value passes 1 if arrow points down, 0 otherwise
603 0 : aControlValue.setNumericVal((nBits&HIB_DOWNARROW)?1:0);
604 0 : nState|=CTRL_STATE_ENABLED;
605 0 : if(bHigh)
606 0 : nState|=CTRL_STATE_PRESSED;
607 : pWin->DrawNativeControl( CTRL_LISTHEADER, PART_ARROW,
608 : aCtrlRegion, nState, aControlValue,
609 0 : rtl::OUString() );
610 : }
611 : else
612 : {
613 : long nArrowY;
614 0 : if ( aTxtSize.Height() )
615 0 : nArrowY = nTxtPosY+(aTxtSize.Height()/2);
616 0 : else if ( aImageSize.Width() && aImageSize.Height() )
617 0 : nArrowY = nImagePosY+(aImageSize.Height()/2);
618 : else
619 : {
620 0 : if ( nBits & HIB_TOP )
621 0 : nArrowY = aRect.Top()+1;
622 0 : else if ( nBits & HIB_BOTTOM )
623 0 : nArrowY = aRect.Bottom()-HEAD_ARROWSIZE2-1;
624 : else
625 0 : nArrowY = aRect.Top()+((aRect.GetHeight()-HEAD_ARROWSIZE2)/2);
626 : }
627 0 : nArrowY -= HEAD_ARROWSIZE1-1;
628 0 : if ( nBits & HIB_DOWNARROW )
629 : {
630 0 : pDev->SetLineColor( rStyleSettings.GetLightColor() );
631 : pDev->DrawLine( Point( nArrowX, nArrowY ),
632 0 : Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
633 : pDev->DrawLine( Point( nArrowX, nArrowY ),
634 0 : Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ) );
635 0 : pDev->SetLineColor( rStyleSettings.GetShadowColor() );
636 : pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ),
637 0 : Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
638 : }
639 : else
640 : {
641 0 : pDev->SetLineColor( rStyleSettings.GetLightColor() );
642 : pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
643 0 : Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
644 0 : pDev->SetLineColor( rStyleSettings.GetShadowColor() );
645 : pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
646 0 : Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ) );
647 : pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ),
648 0 : Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
649 : }
650 : }
651 : }
652 : }
653 :
654 : // Gegebenenfalls auch UserDraw aufrufen
655 0 : if ( nBits & HIB_USERDRAW )
656 : {
657 0 : Region aRegion( aRect );
658 0 : if ( pRect )
659 0 : aRegion.Intersect( *pRect );
660 0 : pDev->SetClipRegion( aRegion );
661 0 : UserDrawEvent aODEvt( pDev, aRect, pItem->mnId );
662 0 : UserDraw( aODEvt );
663 0 : pDev->SetClipRegion();
664 0 : }
665 : }
666 :
667 : // -----------------------------------------------------------------------
668 :
669 0 : void HeaderBar::ImplDrawItem( sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag,
670 : const Rectangle* pRect )
671 : {
672 0 : Rectangle aRect = ImplGetItemRect( nPos );
673 0 : ImplDrawItem( this, nPos, bHigh, bDrag, aRect, pRect, 0 );
674 0 : }
675 :
676 : // -----------------------------------------------------------------------
677 :
678 0 : void HeaderBar::ImplUpdate( sal_uInt16 nPos, sal_Bool bEnd, sal_Bool bDirect )
679 : {
680 0 : if ( IsVisible() && IsUpdateMode() )
681 : {
682 0 : if ( !bDirect )
683 : {
684 0 : Rectangle aRect;
685 0 : size_t nItemCount = mpItemList->size();
686 0 : if ( nPos < nItemCount )
687 0 : aRect = ImplGetItemRect( nPos );
688 : else
689 : {
690 0 : aRect.Bottom() = mnDY-1;
691 0 : if ( nItemCount )
692 0 : aRect.Left() = ImplGetItemRect( nItemCount-1 ).Right();
693 : }
694 0 : if ( bEnd )
695 0 : aRect.Right() = mnDX-1;
696 0 : aRect.Top() += mnBorderOff1;
697 0 : aRect.Bottom() -= mnBorderOff2;
698 0 : Invalidate( aRect );
699 : }
700 : else
701 : {
702 0 : for ( size_t i = nPos; i < mpItemList->size(); i++ )
703 0 : ImplDrawItem( i );
704 0 : if ( bEnd )
705 : {
706 0 : Rectangle aRect = ImplGetItemRect( (sal_uInt16)mpItemList->size() );
707 0 : aRect.Left() = aRect.Right();
708 0 : aRect.Right() = mnDX-1;
709 0 : if ( aRect.Left() < aRect.Right() )
710 : {
711 0 : aRect.Top() += mnBorderOff1;
712 0 : aRect.Bottom() -= mnBorderOff2;
713 0 : Erase( aRect );
714 : }
715 : }
716 : }
717 : }
718 0 : }
719 :
720 : // -----------------------------------------------------------------------
721 :
722 0 : void HeaderBar::ImplStartDrag( const Point& rMousePos, sal_Bool bCommand )
723 : {
724 : sal_uInt16 nPos;
725 0 : sal_uInt16 nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos );
726 0 : if ( nHitTest )
727 : {
728 0 : mbDrag = sal_False;
729 0 : ImplHeadItem* pItem = (*mpItemList)[ nPos ];
730 0 : if ( nHitTest & HEAD_HITTEST_DIVIDER )
731 0 : mbDrag = sal_True;
732 : else
733 : {
734 0 : if ( ((pItem->mnBits & HIB_CLICKABLE) && !(pItem->mnBits & HIB_FLAT)) ||
735 0 : (mbDragable && !(pItem->mnBits & HIB_FIXEDPOS)) )
736 : {
737 0 : mbItemMode = sal_True;
738 0 : mbDrag = sal_True;
739 0 : if ( bCommand )
740 : {
741 0 : if ( mbDragable )
742 0 : mbItemDrag = sal_True;
743 : else
744 : {
745 0 : mbItemMode = sal_False;
746 0 : mbDrag = sal_False;
747 : }
748 : }
749 : }
750 : else
751 : {
752 0 : if ( !bCommand )
753 : {
754 0 : mnCurItemId = pItem->mnId;
755 0 : Select();
756 0 : mnCurItemId = 0;
757 : }
758 : }
759 : }
760 :
761 0 : if ( mbDrag )
762 : {
763 0 : mbOutDrag = sal_False;
764 0 : mnCurItemId = pItem->mnId;
765 0 : mnItemDragPos = nPos;
766 0 : StartTracking();
767 0 : mnStartPos = rMousePos.X()-mnMouseOff;
768 0 : mnDragPos = mnStartPos;
769 0 : StartDrag();
770 0 : if ( mbItemMode )
771 0 : ImplDrawItem( nPos, sal_True, mbItemDrag );
772 : else
773 : {
774 0 : Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
775 0 : ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
776 : }
777 : }
778 : else
779 0 : mnMouseOff = 0;
780 : }
781 0 : }
782 :
783 : // -----------------------------------------------------------------------
784 :
785 0 : void HeaderBar::ImplDrag( const Point& rMousePos )
786 : {
787 : sal_Bool bNewOutDrag;
788 0 : sal_uInt16 nPos = GetItemPos( mnCurItemId );
789 :
790 0 : mnDragPos = rMousePos.X()-mnMouseOff;
791 0 : if ( mbItemMode )
792 : {
793 0 : Rectangle aItemRect = ImplGetItemRect( nPos );
794 0 : if ( aItemRect.IsInside( rMousePos ) )
795 0 : bNewOutDrag = sal_False;
796 : else
797 0 : bNewOutDrag = sal_True;
798 :
799 : // Evt. ItemDrag anschalten
800 0 : if ( bNewOutDrag && mbDragable && !mbItemDrag &&
801 0 : !((*mpItemList)[ nPos ]->mnBits & HIB_FIXEDPOS) )
802 : {
803 0 : if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) )
804 : {
805 0 : mbItemDrag = sal_True;
806 0 : ImplDrawItem( nPos, sal_True, mbItemDrag );
807 : }
808 : }
809 :
810 0 : sal_uInt16 nOldItemDragPos = mnItemDragPos;
811 0 : if ( mbItemDrag )
812 : {
813 0 : if ( (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF) )
814 0 : bNewOutDrag = sal_True;
815 : else
816 0 : bNewOutDrag = sal_False;
817 :
818 0 : if ( bNewOutDrag )
819 0 : mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
820 : else
821 : {
822 0 : sal_uInt16 nTempId = GetItemId( Point( rMousePos.X(), 2 ) );
823 0 : if ( nTempId )
824 0 : mnItemDragPos = GetItemPos( nTempId );
825 : else
826 : {
827 0 : if ( rMousePos.X() <= 0 )
828 0 : mnItemDragPos = 0;
829 : else
830 0 : mnItemDragPos = GetItemCount()-1;
831 : }
832 :
833 : // Nicht verschiebbare Items aussparen
834 0 : if ( mnItemDragPos < nPos )
835 : {
836 0 : while ( ((*mpItemList)[ mnItemDragPos ]->mnBits & HIB_FIXEDPOS) &&
837 : (mnItemDragPos < nPos) )
838 0 : mnItemDragPos++;
839 : }
840 0 : else if ( mnItemDragPos > nPos )
841 : {
842 0 : while ( ((*mpItemList)[ mnItemDragPos ]->mnBits & HIB_FIXEDPOS) &&
843 : (mnItemDragPos > nPos) )
844 0 : mnItemDragPos--;
845 : }
846 : }
847 :
848 0 : if ( (mnItemDragPos != nOldItemDragPos) &&
849 : (nOldItemDragPos != nPos) &&
850 : (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
851 : {
852 0 : ImplInvertDrag( nPos, nOldItemDragPos );
853 0 : ImplDrawItem( nOldItemDragPos );
854 : }
855 : }
856 :
857 0 : if ( bNewOutDrag != mbOutDrag )
858 0 : ImplDrawItem( nPos, !bNewOutDrag, mbItemDrag );
859 :
860 0 : if ( mbItemDrag )
861 : {
862 0 : if ( (mnItemDragPos != nOldItemDragPos) &&
863 : (mnItemDragPos != nPos) &&
864 : (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
865 : {
866 0 : ImplDrawItem( mnItemDragPos, sal_False, sal_True );
867 0 : ImplInvertDrag( nPos, mnItemDragPos );
868 : }
869 : }
870 :
871 0 : mbOutDrag = bNewOutDrag;
872 : }
873 : else
874 : {
875 0 : Rectangle aItemRect = ImplGetItemRect( nPos );
876 0 : if ( mnDragPos < aItemRect.Left() )
877 0 : mnDragPos = aItemRect.Left();
878 0 : if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) )
879 0 : HideTracking();
880 : else
881 : {
882 0 : Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
883 0 : ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
884 : }
885 : }
886 :
887 0 : Drag();
888 0 : }
889 :
890 : // -----------------------------------------------------------------------
891 :
892 0 : void HeaderBar::ImplEndDrag( sal_Bool bCancel )
893 : {
894 0 : HideTracking();
895 :
896 0 : if ( bCancel || mbOutDrag )
897 : {
898 0 : if ( mbItemMode && (!mbOutDrag || mbItemDrag) )
899 : {
900 0 : sal_uInt16 nPos = GetItemPos( mnCurItemId );
901 0 : ImplDrawItem( nPos );
902 : }
903 :
904 0 : mnCurItemId = 0;
905 : }
906 : else
907 : {
908 0 : sal_uInt16 nPos = GetItemPos( mnCurItemId );
909 0 : if ( mbItemMode )
910 : {
911 0 : if ( mbItemDrag )
912 : {
913 0 : Pointer aPointer( POINTER_ARROW );
914 0 : SetPointer( aPointer );
915 0 : if ( (mnItemDragPos != nPos) &&
916 : (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
917 : {
918 0 : ImplInvertDrag( nPos, mnItemDragPos );
919 0 : MoveItem( mnCurItemId, mnItemDragPos );
920 : }
921 : else
922 0 : ImplDrawItem( nPos );
923 : }
924 : else
925 : {
926 0 : Select();
927 0 : ImplUpdate( nPos );
928 : }
929 : }
930 : else
931 : {
932 0 : long nDelta = mnDragPos - mnStartPos;
933 0 : if ( nDelta )
934 : {
935 0 : ImplHeadItem* pItem = (*mpItemList)[ nPos ];
936 0 : pItem->mnSize += nDelta;
937 0 : ImplUpdate( nPos, sal_True );
938 : }
939 : }
940 : }
941 :
942 0 : mbDrag = sal_False;
943 0 : EndDrag();
944 0 : mnCurItemId = 0;
945 0 : mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
946 0 : mbOutDrag = sal_False;
947 0 : mbItemMode = sal_False;
948 0 : mbItemDrag = sal_False;
949 0 : }
950 :
951 : // -----------------------------------------------------------------------
952 :
953 0 : void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt )
954 : {
955 0 : if ( rMEvt.IsLeft() )
956 : {
957 0 : if ( rMEvt.GetClicks() == 2 )
958 : {
959 : long nTemp;
960 : sal_uInt16 nPos;
961 0 : sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos );
962 0 : if ( nHitTest )
963 : {
964 0 : ImplHeadItem* pItem = (*mpItemList)[ nPos ];
965 0 : if ( nHitTest & HEAD_HITTEST_DIVIDER )
966 0 : mbItemMode = sal_False;
967 : else
968 0 : mbItemMode = sal_True;
969 0 : mnCurItemId = pItem->mnId;
970 0 : DoubleClick();
971 0 : mbItemMode = sal_False;
972 0 : mnCurItemId = 0;
973 : }
974 : }
975 : else
976 0 : ImplStartDrag( rMEvt.GetPosPixel(), sal_False );
977 : }
978 0 : }
979 :
980 : // -----------------------------------------------------------------------
981 :
982 0 : void HeaderBar::MouseMove( const MouseEvent& rMEvt )
983 : {
984 : long nTemp1;
985 : sal_uInt16 nTemp2;
986 0 : PointerStyle eStyle = POINTER_ARROW;
987 0 : sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 );
988 :
989 0 : if ( nHitTest & HEAD_HITTEST_DIVIDER )
990 0 : eStyle = POINTER_HSIZEBAR;
991 0 : Pointer aPtr( eStyle );
992 0 : SetPointer( aPtr );
993 0 : }
994 :
995 : // -----------------------------------------------------------------------
996 :
997 0 : void HeaderBar::Tracking( const TrackingEvent& rTEvt )
998 : {
999 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
1000 :
1001 0 : if ( rTEvt.IsTrackingEnded() )
1002 0 : ImplEndDrag( rTEvt.IsTrackingCanceled() );
1003 : else
1004 0 : ImplDrag( aMousePos );
1005 0 : }
1006 :
1007 : // -----------------------------------------------------------------------
1008 :
1009 0 : void HeaderBar::Paint( const Rectangle& rRect )
1010 : {
1011 0 : if ( mnBorderOff1 || mnBorderOff2 )
1012 : {
1013 0 : SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
1014 0 : if ( mnBorderOff1 )
1015 0 : DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
1016 0 : if ( mnBorderOff2 )
1017 0 : DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
1018 : // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
1019 0 : if ( mnBorderOff1 && mnBorderOff2 )
1020 : {
1021 0 : DrawLine( Point( 0, 0 ), Point( 0, mnDY-1 ) );
1022 0 : DrawLine( Point( mnDX-1, 0 ), Point( mnDX-1, mnDY-1 ) );
1023 : }
1024 : }
1025 :
1026 : sal_uInt16 nCurItemPos;
1027 0 : if ( mbDrag )
1028 0 : nCurItemPos = GetItemPos( mnCurItemId );
1029 : else
1030 0 : nCurItemPos = HEADERBAR_ITEM_NOTFOUND;
1031 0 : sal_uInt16 nItemCount = (sal_uInt16)mpItemList->size();
1032 0 : for ( sal_uInt16 i = 0; i < nItemCount; i++ )
1033 0 : ImplDrawItem( i, (i == nCurItemPos) ? sal_True : sal_False, sal_False, &rRect );
1034 0 : }
1035 :
1036 : // -----------------------------------------------------------------------
1037 :
1038 0 : void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
1039 : sal_uLong nFlags )
1040 : {
1041 0 : Point aPos = pDev->LogicToPixel( rPos );
1042 0 : Size aSize = pDev->LogicToPixel( rSize );
1043 0 : Rectangle aRect( aPos, aSize );
1044 0 : Font aFont = GetDrawPixelFont( pDev );
1045 :
1046 0 : pDev->Push();
1047 0 : pDev->SetMapMode();
1048 0 : pDev->SetFont( aFont );
1049 0 : if ( nFlags & WINDOW_DRAW_MONO )
1050 0 : pDev->SetTextColor( Color( COL_BLACK ) );
1051 : else
1052 0 : pDev->SetTextColor( GetTextColor() );
1053 0 : pDev->SetTextFillColor();
1054 :
1055 0 : if ( !(nFlags & WINDOW_DRAW_NOBACKGROUND) )
1056 : {
1057 0 : pDev->DrawWallpaper( aRect, GetBackground() );
1058 0 : if ( mnBorderOff1 || mnBorderOff2 )
1059 : {
1060 0 : pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
1061 0 : if ( mnBorderOff1 )
1062 0 : pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
1063 0 : if ( mnBorderOff2 )
1064 0 : pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) );
1065 : // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
1066 0 : if ( mnBorderOff1 && mnBorderOff2 )
1067 : {
1068 0 : pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
1069 0 : pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) );
1070 : }
1071 : }
1072 : }
1073 :
1074 0 : Rectangle aItemRect( aRect );
1075 0 : size_t nItemCount = mpItemList->size();
1076 0 : for ( size_t i = 0; i < nItemCount; i++ )
1077 : {
1078 0 : aItemRect.Left() = aRect.Left()+ImplGetItemPos( i );
1079 0 : aItemRect.Right() = aItemRect.Left() + (*mpItemList)[ i ]->mnSize - 1;
1080 : // Gegen Ueberlauf auf einigen Systemen testen
1081 0 : if ( aItemRect.Right() > 16000 )
1082 0 : aItemRect.Right() = 16000;
1083 0 : Region aRegion( aRect );
1084 0 : pDev->SetClipRegion( aRegion );
1085 0 : ImplDrawItem( pDev, i, sal_False, sal_False, aItemRect, &aRect, nFlags );
1086 0 : pDev->SetClipRegion();
1087 0 : }
1088 :
1089 0 : pDev->Pop();
1090 0 : }
1091 :
1092 : // -----------------------------------------------------------------------
1093 :
1094 0 : void HeaderBar::Resize()
1095 : {
1096 0 : Size aSize = GetOutputSizePixel();
1097 0 : if ( IsVisible() && (mnDY != aSize.Height()) )
1098 0 : Invalidate();
1099 0 : mnDX = aSize.Width();
1100 0 : mnDY = aSize.Height();
1101 0 : }
1102 :
1103 : // -----------------------------------------------------------------------
1104 :
1105 0 : void HeaderBar::Command( const CommandEvent& rCEvt )
1106 : {
1107 0 : if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == COMMAND_STARTDRAG) && !mbDrag )
1108 : {
1109 0 : ImplStartDrag( rCEvt.GetMousePosPixel(), sal_True );
1110 0 : return;
1111 : }
1112 :
1113 0 : Window::Command( rCEvt );
1114 : }
1115 :
1116 : // -----------------------------------------------------------------------
1117 :
1118 0 : void HeaderBar::RequestHelp( const HelpEvent& rHEvt )
1119 : {
1120 0 : sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
1121 0 : if ( nItemId )
1122 : {
1123 0 : if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
1124 : {
1125 0 : Rectangle aItemRect = GetItemRect( nItemId );
1126 0 : Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
1127 0 : aItemRect.Left() = aPt.X();
1128 0 : aItemRect.Top() = aPt.Y();
1129 0 : aPt = OutputToScreenPixel( aItemRect.BottomRight() );
1130 0 : aItemRect.Right() = aPt.X();
1131 0 : aItemRect.Bottom() = aPt.Y();
1132 :
1133 0 : XubString aStr = GetHelpText( nItemId );
1134 0 : if ( !aStr.Len() || !(rHEvt.GetMode() & HELPMODE_BALLOON) )
1135 : {
1136 0 : ImplHeadItem* pItem = (*mpItemList)[ GetItemPos( nItemId ) ];
1137 : // Wir zeigen die Quick-Hilfe nur an, wenn Text nicht
1138 : // vollstaendig sichtbar, ansonsten zeigen wir den Hilfetext
1139 : // an, wenn das Item keinen Text besitzt
1140 0 : if ( pItem->maOutText != pItem->maText )
1141 0 : aStr = pItem->maText;
1142 0 : else if ( pItem->maText.Len() )
1143 0 : aStr.Erase();
1144 : }
1145 :
1146 0 : if ( aStr.Len() )
1147 : {
1148 0 : if ( rHEvt.GetMode() & HELPMODE_BALLOON )
1149 0 : Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
1150 : else
1151 0 : Help::ShowQuickHelp( this, aItemRect, aStr );
1152 : return;
1153 0 : }
1154 : }
1155 0 : else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
1156 : {
1157 0 : rtl::OUString aHelpId( rtl::OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) );
1158 0 : if ( !aHelpId.isEmpty() )
1159 : {
1160 : // Wenn eine Hilfe existiert, dann ausloesen
1161 0 : Help* pHelp = Application::GetHelp();
1162 0 : if ( pHelp )
1163 0 : pHelp->Start( aHelpId, this );
1164 : return;
1165 0 : }
1166 : }
1167 : }
1168 :
1169 0 : Window::RequestHelp( rHEvt );
1170 : }
1171 :
1172 : // -----------------------------------------------------------------------
1173 :
1174 0 : void HeaderBar::StateChanged( StateChangedType nType )
1175 : {
1176 0 : Window::StateChanged( nType );
1177 :
1178 0 : if ( nType == STATE_CHANGE_ENABLE )
1179 0 : Invalidate();
1180 0 : else if ( (nType == STATE_CHANGE_ZOOM) ||
1181 : (nType == STATE_CHANGE_CONTROLFONT) )
1182 : {
1183 0 : ImplInitSettings( sal_True, sal_False, sal_False );
1184 0 : Invalidate();
1185 : }
1186 0 : else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1187 : {
1188 0 : ImplInitSettings( sal_False, sal_True, sal_False );
1189 0 : Invalidate();
1190 : }
1191 0 : else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1192 : {
1193 0 : ImplInitSettings( sal_False, sal_False, sal_True );
1194 0 : Invalidate();
1195 : }
1196 0 : }
1197 :
1198 : // -----------------------------------------------------------------------
1199 :
1200 0 : void HeaderBar::DataChanged( const DataChangedEvent& rDCEvt )
1201 : {
1202 0 : Window::DataChanged( rDCEvt );
1203 :
1204 0 : if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1205 0 : (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1206 0 : ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1207 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1208 : {
1209 0 : ImplInitSettings( sal_True, sal_True, sal_True );
1210 0 : Invalidate();
1211 : }
1212 0 : }
1213 :
1214 : // -----------------------------------------------------------------------
1215 :
1216 0 : void HeaderBar::UserDraw( const UserDrawEvent& )
1217 : {
1218 0 : }
1219 :
1220 : // -----------------------------------------------------------------------
1221 :
1222 0 : void HeaderBar::StartDrag()
1223 : {
1224 0 : maStartDragHdl.Call( this );
1225 0 : }
1226 :
1227 : // -----------------------------------------------------------------------
1228 :
1229 0 : void HeaderBar::Drag()
1230 : {
1231 0 : maDragHdl.Call( this );
1232 0 : }
1233 :
1234 : // -----------------------------------------------------------------------
1235 :
1236 0 : void HeaderBar::EndDrag()
1237 : {
1238 0 : maEndDragHdl.Call( this );
1239 0 : }
1240 :
1241 : // -----------------------------------------------------------------------
1242 :
1243 0 : void HeaderBar::Select()
1244 : {
1245 0 : maSelectHdl.Call( this );
1246 0 : }
1247 :
1248 : // -----------------------------------------------------------------------
1249 :
1250 0 : void HeaderBar::DoubleClick()
1251 : {
1252 0 : maDoubleClickHdl.Call( this );
1253 0 : }
1254 :
1255 : // -----------------------------------------------------------------------
1256 :
1257 0 : void HeaderBar::InsertItem( sal_uInt16 nItemId, const XubString& rText,
1258 : long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos )
1259 : {
1260 : DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
1261 : DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
1262 : "HeaderBar::InsertItem(): ItemId already exists" );
1263 :
1264 : // Item anlegen und in die Liste einfuegen
1265 0 : ImplHeadItem* pItem = new ImplHeadItem;
1266 0 : pItem->mnId = nItemId;
1267 0 : pItem->mnBits = nBits;
1268 0 : pItem->mnSize = nSize;
1269 0 : pItem->maText = rText;
1270 0 : if ( nPos < mpItemList->size() ) {
1271 0 : ImplHeadItemList::iterator it = mpItemList->begin();
1272 0 : ::std::advance( it, nPos );
1273 0 : mpItemList->insert( it, pItem );
1274 : } else {
1275 0 : mpItemList->push_back( pItem );
1276 : }
1277 :
1278 : // Ausgabe updaten
1279 0 : ImplUpdate( nPos, sal_True );
1280 0 : }
1281 :
1282 : // -----------------------------------------------------------------------
1283 :
1284 0 : void HeaderBar::RemoveItem( sal_uInt16 nItemId )
1285 : {
1286 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1287 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1288 : {
1289 0 : if ( nPos < mpItemList->size() ) {
1290 0 : ImplHeadItemList::iterator it = mpItemList->begin();
1291 0 : ::std::advance( it, nPos );
1292 0 : delete *it;
1293 0 : mpItemList->erase( it );
1294 : }
1295 : }
1296 0 : }
1297 :
1298 : // -----------------------------------------------------------------------
1299 :
1300 0 : void HeaderBar::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos )
1301 : {
1302 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1303 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1304 : {
1305 0 : if ( nPos != nNewPos )
1306 : {
1307 0 : ImplHeadItemList::iterator it = mpItemList->begin();
1308 0 : ::std::advance( it, nPos );
1309 0 : ImplHeadItem* pItem = *it;
1310 0 : mpItemList->erase( it );
1311 0 : if ( nNewPos < nPos )
1312 0 : nPos = nNewPos;
1313 0 : it = mpItemList->begin();
1314 0 : ::std::advance( it, nPos );
1315 0 : mpItemList->insert( it, pItem );
1316 : }
1317 : }
1318 0 : }
1319 :
1320 : // -----------------------------------------------------------------------
1321 :
1322 0 : void HeaderBar::Clear()
1323 : {
1324 : // Alle Items loeschen
1325 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1326 0 : delete (*mpItemList)[ i ];
1327 : }
1328 0 : mpItemList->clear();
1329 :
1330 0 : ImplUpdate( 0, sal_True );
1331 0 : }
1332 :
1333 : // -----------------------------------------------------------------------
1334 :
1335 0 : void HeaderBar::SetOffset( long nNewOffset )
1336 : {
1337 : // Bereich verschieben
1338 0 : Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 );
1339 0 : long nDelta = mnOffset-nNewOffset;
1340 0 : mnOffset = nNewOffset;
1341 0 : Scroll( nDelta, 0, aRect );
1342 0 : }
1343 :
1344 : // -----------------------------------------------------------------------
1345 :
1346 0 : sal_uInt16 HeaderBar::GetItemCount() const
1347 : {
1348 0 : return (sal_uInt16)mpItemList->size();
1349 : }
1350 :
1351 : // -----------------------------------------------------------------------
1352 :
1353 0 : sal_uInt16 HeaderBar::GetItemPos( sal_uInt16 nItemId ) const
1354 : {
1355 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1356 0 : ImplHeadItem* pItem = (*mpItemList)[ i ];
1357 0 : if ( pItem->mnId == nItemId )
1358 0 : return (sal_uInt16)i;
1359 : }
1360 0 : return HEADERBAR_ITEM_NOTFOUND;
1361 : }
1362 :
1363 : // -----------------------------------------------------------------------
1364 :
1365 0 : sal_uInt16 HeaderBar::GetItemId( sal_uInt16 nPos ) const
1366 : {
1367 0 : ImplHeadItem* pItem = (nPos < mpItemList->size() ) ? (*mpItemList)[ nPos ] : NULL;
1368 0 : if ( pItem )
1369 0 : return pItem->mnId;
1370 : else
1371 0 : return 0;
1372 : }
1373 :
1374 : // -----------------------------------------------------------------------
1375 :
1376 0 : sal_uInt16 HeaderBar::GetItemId( const Point& rPos ) const
1377 : {
1378 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i ) {
1379 0 : if ( ImplGetItemRect( i ).IsInside( rPos ) ) {
1380 0 : return GetItemId( i );
1381 : }
1382 : }
1383 0 : return 0;
1384 : }
1385 :
1386 : // -----------------------------------------------------------------------
1387 :
1388 0 : Rectangle HeaderBar::GetItemRect( sal_uInt16 nItemId ) const
1389 : {
1390 0 : Rectangle aRect;
1391 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1392 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1393 0 : aRect = ImplGetItemRect( nPos );
1394 0 : return aRect;
1395 : }
1396 :
1397 : // -----------------------------------------------------------------------
1398 :
1399 0 : void HeaderBar::SetItemSize( sal_uInt16 nItemId, long nNewSize )
1400 : {
1401 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1402 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1403 : {
1404 0 : ImplHeadItem* pItem = (*mpItemList)[ nPos ];
1405 0 : if ( pItem->mnSize != nNewSize )
1406 : {
1407 0 : pItem->mnSize = nNewSize;
1408 0 : ImplUpdate( nPos, sal_True );
1409 : }
1410 : }
1411 0 : }
1412 :
1413 : // -----------------------------------------------------------------------
1414 :
1415 0 : long HeaderBar::GetItemSize( sal_uInt16 nItemId ) const
1416 : {
1417 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1418 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1419 0 : return (*mpItemList)[ nPos ]->mnSize;
1420 : else
1421 0 : return 0;
1422 : }
1423 :
1424 : // -----------------------------------------------------------------------
1425 :
1426 0 : void HeaderBar::SetItemBits( sal_uInt16 nItemId, HeaderBarItemBits nNewBits )
1427 : {
1428 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1429 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1430 : {
1431 0 : ImplHeadItem* pItem = (*mpItemList)[ nPos ];
1432 0 : if ( pItem->mnBits != nNewBits )
1433 : {
1434 0 : pItem->mnBits = nNewBits;
1435 0 : ImplUpdate( nPos );
1436 : }
1437 : }
1438 0 : }
1439 :
1440 : // -----------------------------------------------------------------------
1441 :
1442 0 : HeaderBarItemBits HeaderBar::GetItemBits( sal_uInt16 nItemId ) const
1443 : {
1444 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1445 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1446 0 : return (*mpItemList)[ nPos ]->mnBits;
1447 : else
1448 0 : return 0;
1449 : }
1450 :
1451 : // -----------------------------------------------------------------------
1452 :
1453 0 : void HeaderBar::SetItemText( sal_uInt16 nItemId, const XubString& rText )
1454 : {
1455 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1456 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1457 : {
1458 0 : (*mpItemList)[ nPos ]->maText = rText;
1459 0 : ImplUpdate( nPos );
1460 : }
1461 0 : }
1462 :
1463 : // -----------------------------------------------------------------------
1464 :
1465 0 : XubString HeaderBar::GetItemText( sal_uInt16 nItemId ) const
1466 : {
1467 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1468 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1469 0 : return (*mpItemList)[ nPos ]->maText;
1470 : else
1471 0 : return String();
1472 : }
1473 :
1474 : // -----------------------------------------------------------------------
1475 :
1476 0 : XubString HeaderBar::GetHelpText( sal_uInt16 nItemId ) const
1477 : {
1478 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1479 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1480 : {
1481 0 : ImplHeadItem* pItem = (*mpItemList)[ nPos ];
1482 0 : if ( !pItem->maHelpText.Len() && !pItem->maHelpId.isEmpty() )
1483 : {
1484 0 : Help* pHelp = Application::GetHelp();
1485 0 : if ( pHelp )
1486 0 : pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1487 : }
1488 :
1489 0 : return pItem->maHelpText;
1490 : }
1491 : else
1492 0 : return XubString();
1493 : }
1494 :
1495 : // -----------------------------------------------------------------------
1496 :
1497 0 : rtl::OString HeaderBar::GetHelpId( sal_uInt16 nItemId ) const
1498 : {
1499 0 : sal_uInt16 nPos = GetItemPos( nItemId );
1500 0 : rtl::OString aRet;
1501 0 : if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1502 0 : return (*mpItemList)[ nPos ]->maHelpId;
1503 0 : return aRet;
1504 : }
1505 :
1506 : // -----------------------------------------------------------------------
1507 :
1508 0 : Size HeaderBar::CalcWindowSizePixel() const
1509 : {
1510 0 : long nMaxImageSize = 0;
1511 0 : Size aSize( 0, GetTextHeight() );
1512 :
1513 0 : for ( size_t i = 0, n = mpItemList->size(); i < n; ++i )
1514 : {
1515 0 : ImplHeadItem* pItem = (*mpItemList)[ i ];
1516 : // Image-Groessen beruecksichtigen
1517 0 : long nImageHeight = pItem->maImage.GetSizePixel().Height();
1518 0 : if ( !(pItem->mnBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && pItem->maText.Len() )
1519 0 : nImageHeight += aSize.Height();
1520 0 : if ( nImageHeight > nMaxImageSize )
1521 0 : nMaxImageSize = nImageHeight;
1522 :
1523 : // Breite aufaddieren
1524 0 : aSize.Width() += pItem->mnSize;
1525 : }
1526 :
1527 0 : if ( nMaxImageSize > aSize.Height() )
1528 0 : aSize.Height() = nMaxImageSize;
1529 :
1530 : // Border aufaddieren
1531 0 : if ( mbButtonStyle )
1532 0 : aSize.Height() += 4;
1533 : else
1534 0 : aSize.Height() += 2;
1535 0 : aSize.Height() += mnBorderOff1+mnBorderOff2;
1536 :
1537 0 : return aSize;
1538 : }
1539 :
1540 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HeaderBar::CreateAccessible()
1541 : {
1542 0 : if ( !mxAccessible.is() )
1543 : {
1544 0 : if ( maCreateAccessibleHdl.IsSet() )
1545 0 : maCreateAccessibleHdl.Call( this );
1546 :
1547 0 : if ( !mxAccessible.is() )
1548 0 : mxAccessible = Window::CreateAccessible();
1549 : }
1550 :
1551 0 : return mxAccessible;
1552 : }
1553 :
1554 0 : void HeaderBar::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > _xAccessible )
1555 : {
1556 0 : mxAccessible = _xAccessible;
1557 0 : }
1558 :
1559 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|