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