1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26
27 #define _SV_SALNATIVEWIDGETS_KDE_CXX
28
29 #define Region QtXRegion
30
31 #include <QStyle>
32 #include <QStyleOption>
33 #include <QPainter>
34 #include <QFrame>
35 #include <QLabel>
36
37 #include <kapplication.h>
38
39 #undef Region
40
41 #include "KDESalGraphics.hxx"
42
43 #include "vcl/settings.hxx"
44 #include "vcl/decoview.hxx"
45 #include "rtl/ustrbuf.hxx"
46
47 using namespace ::rtl;
48
49 /**
50 Conversion function between VCL ControlState together with
51 ImplControlValue and Qt state flags.
52 @param nControlState State of the widget (default, focused, ...) in Native Widget Framework.
53 @param aValue Value held by the widget (on, off, ...)
54 */
vclStateValue2StateFlag(ControlState nControlState,const ImplControlValue & aValue)55 QStyle::State vclStateValue2StateFlag( ControlState nControlState,
56 const ImplControlValue& aValue )
57 {
58 QStyle::State nState =
59 ( (nControlState & CTRL_STATE_DEFAULT)? QStyle::State_None: QStyle::State_None ) |
60 ( (nControlState & CTRL_STATE_ENABLED)? QStyle::State_Enabled: QStyle::State_None ) |
61 ( (nControlState & CTRL_STATE_FOCUSED)? QStyle::State_HasFocus: QStyle::State_None ) |
62 ( (nControlState & CTRL_STATE_PRESSED)? QStyle::State_Sunken: QStyle::State_None ) |
63 ( (nControlState & CTRL_STATE_SELECTED)? QStyle::State_Selected : QStyle::State_None ) |
64 ( (nControlState & CTRL_STATE_ROLLOVER)? QStyle::State_MouseOver: QStyle::State_None );
65 //TODO ( (nControlState & CTRL_STATE_HIDDEN)? QStyle::State_: QStyle::State_None ) |
66
67 switch ( aValue.getTristateVal() )
68 {
69 case BUTTONVALUE_ON: nState |= QStyle::State_On; break;
70 case BUTTONVALUE_OFF: nState |= QStyle::State_Off; break;
71 case BUTTONVALUE_MIXED: nState |= QStyle::State_NoChange; break;
72 default: break;
73 }
74
75 return nState;
76 }
77
78 /**
79 Convert VCL Rectangle to QRect.
80 @param rControlRegion The Rectangle to convert.
81 @return The matching QRect
82 */
region2QRect(const Rectangle & rControlRegion)83 QRect region2QRect( const Rectangle& rControlRegion )
84 {
85 return QRect(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.GetWidth(), rControlRegion.GetHeight());
86 }
87
KDESalGraphics()88 KDESalGraphics::KDESalGraphics() :
89 m_image(0)
90 {
91 }
92
~KDESalGraphics()93 KDESalGraphics::~KDESalGraphics()
94 {
95 if (m_image)
96 delete m_image;
97 }
98
IsNativeControlSupported(ControlType type,ControlPart part)99 sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart part )
100 {
101 if (type == CTRL_PUSHBUTTON) return true;
102
103 if (type == CTRL_MENUBAR) return true;
104
105 if (type == CTRL_MENU_POPUP) return true;
106
107 if (type == CTRL_EDITBOX) return true;
108
109 if (type == CTRL_COMBOBOX) return true;
110
111 if (type == CTRL_TOOLBAR) return true;
112
113 if (type == CTRL_CHECKBOX) return true;
114
115 if (type == CTRL_LISTBOX) return true;
116
117 if (type == CTRL_LISTNODE) return true;
118
119 if (type == CTRL_FRAME) return true;
120
121 if (type == CTRL_SCROLLBAR) return true;
122
123 if (type == CTRL_WINDOW_BACKGROUND) return true;
124
125 if (type == CTRL_SPINBOX && (part == PART_ENTIRE_CONTROL || part == HAS_BACKGROUND_TEXTURE) ) return true;
126
127 // no spinbuttons for KDE, paint spinbox complete
128 //if (type == CTRL_SPINBUTTONS) return true;
129
130 if (type == CTRL_GROUPBOX) return true;
131
132 if (type == CTRL_FIXEDLINE) return true;
133
134 if (type == CTRL_FIXEDBORDER) return true;
135
136 if (type == CTRL_TOOLTIP) return true;
137
138 if (type == CTRL_RADIOBUTTON) return true;
139
140 if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA) )
141 return true;
142
143 return false;
144
145 if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true;
146 if ( (type == CTRL_TAB_PANE) && (part == PART_ENTIRE_CONTROL) ) return true;
147 // no CTRL_TAB_BODY for KDE
148 if ( (type == CTRL_PROGRESS) && (part == PART_ENTIRE_CONTROL) ) return true;
149
150 return false;
151 }
152
hitTestNativeControl(ControlType,ControlPart,const Rectangle &,const Point &,sal_Bool &)153 sal_Bool KDESalGraphics::hitTestNativeControl( ControlType, ControlPart,
154 const Rectangle&, const Point&,
155 sal_Bool& )
156 {
157 return FALSE;
158 }
159
160 /// helper drawing methods
161 namespace
162 {
draw(QStyle::ControlElement element,QStyleOption * option,QImage * image,QStyle::State state)163 void draw( QStyle::ControlElement element, QStyleOption* option, QImage* image, QStyle::State state )
164 {
165 option->state |= state;
166 option->rect = image->rect();
167
168 QPainter painter(image);
169 kapp->style()->drawControl(element, option, &painter);
170 }
171
draw(QStyle::PrimitiveElement element,QStyleOption * option,QImage * image,QStyle::State state,int nAdjust=0)172 void draw( QStyle::PrimitiveElement element, QStyleOption* option, QImage* image, QStyle::State state, int nAdjust = 0 )
173 {
174 option->state |= state;
175 option->rect = image->rect();
176 if( nAdjust )
177 option->rect.adjust( nAdjust, nAdjust, -nAdjust, -nAdjust );
178
179 QPainter painter(image);
180 kapp->style()->drawPrimitive(element, option, &painter);
181 }
182
draw(QStyle::ComplexControl element,QStyleOptionComplex * option,QImage * image,QStyle::State state)183 void draw( QStyle::ComplexControl element, QStyleOptionComplex* option, QImage* image, QStyle::State state )
184 {
185 option->state |= state;
186 option->rect = image->rect();
187
188 QPainter painter(image);
189 kapp->style()->drawComplexControl(element, option, &painter);
190 }
191
getFrameWidth()192 int getFrameWidth()
193 {
194 static int s_nFrameWidth = -1;
195 if( s_nFrameWidth < 0 )
196 {
197 // fill in a default
198 s_nFrameWidth = 2;
199 QFrame aFrame( NULL );
200 aFrame.setFrameRect( QRect(0, 0, 100, 30) );
201 aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
202 aFrame.ensurePolished();
203 s_nFrameWidth = aFrame.frameWidth();
204 }
205 return s_nFrameWidth;
206 }
207
lcl_drawFrame(QStyle::PrimitiveElement element,QImage * image,QStyle::State state)208 void lcl_drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State state)
209 {
210 #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) )
211 QStyleOptionFrameV3 option;
212 option.frameShape = QFrame::StyledPanel;
213 option.state = QStyle::State_Sunken;
214 #else
215 QStyleOptionFrame option;
216
217 QFrame aFrame( NULL );
218 aFrame.setFrameRect( QRect(0, 0, image->width(), image->height()) );
219 aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
220 aFrame.ensurePolished();
221
222 option.initFrom( &aFrame );
223 option.lineWidth = aFrame.lineWidth();
224 option.midLineWidth = aFrame.midLineWidth();
225 #endif
226
227 draw(element, &option, image, state);
228 }
229 }
230
drawNativeControl(ControlType type,ControlPart part,const Rectangle & rControlRegion,ControlState nControlState,const ImplControlValue & value,const OUString &)231 sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
232 const Rectangle& rControlRegion, ControlState nControlState,
233 const ImplControlValue& value,
234 const OUString& )
235 {
236 // put not implemented types here
237 if (type == CTRL_SPINBUTTONS)
238 {
239 return false;
240 }
241
242 sal_Bool returnVal = true;
243
244 QRect widgetRect = region2QRect(rControlRegion);
245 if( type == CTRL_SPINBOX && part == PART_ALL_BUTTONS )
246 type = CTRL_SPINBUTTONS;
247 if( type == CTRL_SPINBUTTONS )
248 {
249 OSL_ASSERT( value.getType() != CTRL_SPINBUTTONS );
250 const SpinbuttonValue* pSpinVal = static_cast<const SpinbuttonValue *>(&value);
251 Rectangle aButtonRect( pSpinVal->maUpperRect);
252 aButtonRect.Union( pSpinVal->maLowerRect );;
253 widgetRect = QRect( aButtonRect.Left(), aButtonRect.Top(),
254 aButtonRect.Right(), aButtonRect.Bottom() );
255 }
256
257 //if no image, or resized, make a new image
258 if (!m_image || m_image->size() != widgetRect.size())
259 {
260 if (m_image)
261 delete m_image;
262
263 m_image = new QImage( widgetRect.width(),
264 widgetRect.height(),
265 QImage::Format_ARGB32 );
266 }
267 m_image->fill(KApplication::palette().color(QPalette::Window).rgb());
268
269
270 XLIB_Region pTempClipRegion = 0;
271
272 if (type == CTRL_PUSHBUTTON)
273 {
274 QStyleOptionButton option;
275 draw( QStyle::CE_PushButton, &option, m_image,
276 vclStateValue2StateFlag(nControlState, value) );
277 }
278 else if ( (type == CTRL_MENUBAR))
279 {
280 if (part == PART_MENU_ITEM)
281 {
282 QStyleOptionMenuItem option;
283 draw( QStyle::CE_MenuBarItem, &option, m_image,
284 vclStateValue2StateFlag(nControlState, value) );
285 }
286 else if (part == PART_ENTIRE_CONTROL)
287 {
288 }
289 else
290 {
291 returnVal = false;
292 }
293 }
294 else if (type == CTRL_MENU_POPUP)
295 {
296 if (part == PART_MENU_ITEM)
297 {
298 QStyleOptionMenuItem option;
299 draw( QStyle::CE_MenuItem, &option, m_image,
300 vclStateValue2StateFlag(nControlState, value) );
301 }
302 else if (part == PART_MENU_ITEM_CHECK_MARK && (nControlState & CTRL_STATE_PRESSED) )
303 {
304 QStyleOptionButton option;
305 draw( QStyle::PE_IndicatorMenuCheckMark, &option, m_image,
306 vclStateValue2StateFlag(nControlState, value) );
307 }
308 else if (part == PART_MENU_ITEM_RADIO_MARK && (nControlState & CTRL_STATE_PRESSED) )
309 {
310 QStyleOptionButton option;
311 draw( QStyle::PE_IndicatorRadioButton, &option, m_image,
312 vclStateValue2StateFlag(nControlState, value) );
313 }
314 else
315 {
316 #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) )
317 QStyleOptionFrameV3 option;
318 option.frameShape = QFrame::StyledPanel;
319 #else
320 QStyleOptionFrameV2 option;
321 #endif
322 draw( QStyle::PE_FrameMenu, &option, m_image,
323 vclStateValue2StateFlag(nControlState, value) );
324 }
325 }
326 else if ( (type == CTRL_TOOLBAR) && (part == PART_BUTTON) )
327 {
328 QStyleOptionToolButton option;
329
330 option.arrowType = Qt::NoArrow;
331 option.subControls = QStyle::SC_ToolButton;
332
333 option.state = vclStateValue2StateFlag( nControlState, value );
334 option.state |= QStyle::State_Raised | QStyle::State_Enabled | QStyle::State_AutoRaise;
335
336 draw( QStyle::CC_ToolButton, &option, m_image,
337 vclStateValue2StateFlag(nControlState, value) );
338 }
339 else if ( (type == CTRL_TOOLBAR) && (part == PART_ENTIRE_CONTROL) )
340 {
341 QStyleOptionToolBar option;
342
343 option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height());
344 option.state = vclStateValue2StateFlag( nControlState, value );
345
346 draw( QStyle::CE_ToolBar, &option, m_image,
347 vclStateValue2StateFlag(nControlState, value) );
348 }
349 else if ( (type == CTRL_TOOLBAR) && (part == PART_THUMB_VERT) )
350 {
351 const int tw = widgetRect.width();
352 widgetRect.setWidth(kapp->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent));
353
354 QStyleOption option;
355 option.state = QStyle::State_Horizontal;
356
357 draw( QStyle::PE_IndicatorToolBarHandle, &option, m_image,
358 vclStateValue2StateFlag(nControlState, value) );
359
360 widgetRect.setWidth(tw);
361 }
362 else if (type == CTRL_EDITBOX)
363 {
364 QStyleOptionFrameV2 option;
365 draw( QStyle::PE_PanelLineEdit, &option, m_image,
366 vclStateValue2StateFlag(nControlState, value), 2 );
367
368 draw( QStyle::PE_FrameLineEdit, &option, m_image,
369 vclStateValue2StateFlag(nControlState, value), 0 );
370 }
371 else if (type == CTRL_COMBOBOX)
372 {
373 QStyleOptionComboBox option;
374 option.editable = true;
375
376 draw( QStyle::CC_ComboBox, &option, m_image,
377 vclStateValue2StateFlag(nControlState, value) );
378 }
379 else if (type == CTRL_LISTBOX)
380 {
381 if( part == PART_WINDOW )
382 {
383 lcl_drawFrame( QStyle::PE_Frame, m_image,
384 vclStateValue2StateFlag(nControlState, value) );
385 }
386 else
387 {
388 QStyleOptionComboBox option;
389 if (part == PART_SUB_EDIT)
390 {
391 draw( QStyle::CE_ComboBoxLabel, &option, m_image,
392 vclStateValue2StateFlag(nControlState, value) );
393 }
394 else
395 {
396 draw( QStyle::CC_ComboBox, &option, m_image,
397 vclStateValue2StateFlag(nControlState, value) );
398 }
399 }
400 }
401 else if (type == CTRL_LISTNODE)
402 {
403 QStyleOption option;
404 option.state = QStyle::State_Item | QStyle::State_Children;
405
406 if (nControlState & CTRL_STATE_PRESSED)
407 option.state |= QStyle::State_Open;
408
409 draw( QStyle::PE_IndicatorBranch, &option, m_image,
410 vclStateValue2StateFlag(nControlState, value) );
411 }
412 else if (type == CTRL_CHECKBOX)
413 {
414 QStyleOptionButton option;
415 draw( QStyle::CE_CheckBox, &option, m_image,
416 vclStateValue2StateFlag(nControlState, value) );
417 }
418 else if (type == CTRL_SCROLLBAR)
419 {
420 if ((part == PART_DRAW_BACKGROUND_VERT) || (part == PART_DRAW_BACKGROUND_HORZ))
421 {
422 QStyleOptionSlider option;
423 OSL_ASSERT( value.getType() == CTRL_SCROLLBAR );
424 const ScrollbarValue* sbVal = static_cast<const ScrollbarValue *>(&value);
425
426 //if the scroll bar is active (aka not degenrate...allow for hover events
427 if (sbVal->mnVisibleSize < sbVal->mnMax)
428 option.state = QStyle::State_MouseOver;
429
430 //horizontal or vertical
431 if (part == PART_DRAW_BACKGROUND_VERT)
432 option.orientation = Qt::Vertical;
433 else
434 option.state |= QStyle::State_Horizontal;
435
436 //setup parameters from the OO values
437 option.minimum = sbVal->mnMin;
438 option.maximum = sbVal->mnMax - sbVal->mnVisibleSize;
439 option.sliderValue = sbVal->mnCur;
440 option.sliderPosition = sbVal->mnCur;
441 option.pageStep = sbVal->mnVisibleSize;
442
443 //setup the active control...always the slider
444 if (sbVal->mnThumbState & CTRL_STATE_ROLLOVER)
445 option.activeSubControls = QStyle::SC_ScrollBarSlider;
446
447 draw( QStyle::CC_ScrollBar, &option, m_image,
448 vclStateValue2StateFlag(nControlState, value) );
449 }
450 else
451 {
452 returnVal = false;
453 }
454 }
455 else if (type == CTRL_SPINBOX)
456 {
457 QStyleOptionSpinBox option;
458
459 // determine active control
460 if( value.getType() == CTRL_SPINBUTTONS )
461 {
462 const SpinbuttonValue* pSpinVal = static_cast<const SpinbuttonValue *>(&value);
463 if( (pSpinVal->mnUpperState & CTRL_STATE_PRESSED) )
464 option.activeSubControls |= QStyle::SC_SpinBoxUp;
465 if( (pSpinVal->mnLowerState & CTRL_STATE_PRESSED) )
466 option.activeSubControls |= QStyle::SC_SpinBoxDown;
467 }
468
469 draw( QStyle::CC_SpinBox, &option, m_image,
470 vclStateValue2StateFlag(nControlState, value) );
471 }
472 else if (type == CTRL_GROUPBOX)
473 {
474 QStyleOptionGroupBox option;
475 draw( QStyle::CC_GroupBox, &option, m_image,
476 vclStateValue2StateFlag(nControlState, value) );
477 }
478 else if (type == CTRL_RADIOBUTTON)
479 {
480 QStyleOptionButton option;
481 draw( QStyle::CE_RadioButton, &option, m_image,
482 vclStateValue2StateFlag(nControlState, value) );
483 }
484 else if (type == CTRL_TOOLTIP)
485 {
486 QStyleOption option;
487 draw( QStyle::PE_PanelTipLabel, &option, m_image,
488 vclStateValue2StateFlag(nControlState, value) );
489 }
490 else if (type == CTRL_FRAME)
491 {
492 lcl_drawFrame( QStyle::PE_Frame, m_image,
493 vclStateValue2StateFlag(nControlState, value) );
494
495 // draw just the border, see http://qa.openoffice.org/issues/show_bug.cgi?id=107945
496 int nFrameWidth = getFrameWidth();
497 pTempClipRegion = XCreateRegion();
498 XRectangle xRect = { widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height() };
499 XUnionRectWithRegion( &xRect, pTempClipRegion, pTempClipRegion );
500 xRect.x += nFrameWidth;
501 xRect.y += nFrameWidth;
502
503 // do not crash for too small widgets, see http://qa.openoffice.org/issues/show_bug.cgi?id=112102
504 if( xRect.width > 2*nFrameWidth && xRect.height > 2*nFrameWidth )
505 {
506 xRect.width -= 2*nFrameWidth;
507 xRect.height -= 2*nFrameWidth;
508
509 XLIB_Region pSubtract = XCreateRegion();
510 XUnionRectWithRegion( &xRect, pSubtract, pSubtract );
511 XSubtractRegion( pTempClipRegion, pSubtract, pTempClipRegion );
512 XDestroyRegion( pSubtract );
513 }
514 }
515 else if (type == CTRL_FIXEDBORDER)
516 {
517 lcl_drawFrame( QStyle::PE_FrameWindow, m_image,
518 vclStateValue2StateFlag(nControlState, value) );
519 }
520 else if (type == CTRL_WINDOW_BACKGROUND)
521 {
522 m_image->fill(KApplication::palette().color(QPalette::Window).rgb());
523 }
524 else if (type == CTRL_FIXEDLINE)
525 {
526 QStyleOptionMenuItem option;
527 option.menuItemType = QStyleOptionMenuItem::Separator;
528 option.state |= QStyle::State_Item;
529
530 draw( QStyle::CE_MenuItem, &option, m_image,
531 vclStateValue2StateFlag(nControlState, value) );
532 }
533 else if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA))
534 {
535 OSL_ASSERT( value.getType() == CTRL_SLIDER );
536 const SliderValue* slVal = static_cast<const SliderValue *>(&value);
537 QStyleOptionSlider option;
538
539 option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height());
540 option.state = vclStateValue2StateFlag( nControlState, value );
541 option.maximum = slVal->mnMax;
542 option.minimum = slVal->mnMin;
543 option.sliderPosition = option.sliderValue = slVal->mnCur;
544 option.orientation = (part == PART_TRACK_HORZ_AREA) ? Qt::Horizontal : Qt::Vertical;
545
546 draw( QStyle::CC_Slider, &option, m_image, vclStateValue2StateFlag(nControlState, value) );
547 }
548 else
549 {
550 returnVal = false;
551 }
552
553 if (returnVal)
554 {
555 GC gc = GetFontGC();
556
557 if( gc )
558 {
559 if( pTempClipRegion )
560 {
561 if( mpClipRegion )
562 XIntersectRegion( pTempClipRegion, mpClipRegion, pTempClipRegion );
563 XSetRegion( GetXDisplay(), gc, pTempClipRegion );
564 }
565 QPixmap pixmap = QPixmap::fromImage(*m_image, Qt::ColorOnly | Qt::OrderedDither | Qt::OrderedAlphaDither);
566 X11SalGraphics::CopyScreenArea( GetXDisplay(),
567 pixmap.handle(), pixmap.x11Info().screen(), pixmap.x11Info().depth(),
568 GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
569 gc, 0, 0, widgetRect.width(), widgetRect.height(), widgetRect.left(), widgetRect.top());
570
571 if( pTempClipRegion )
572 {
573 if( mpClipRegion )
574 XSetRegion( GetXDisplay(), gc, mpClipRegion );
575 else
576 XSetClipMask( GetXDisplay(), gc, None );
577 }
578 }
579 else
580 returnVal = false;
581 }
582 if( pTempClipRegion )
583 XDestroyRegion( pTempClipRegion );
584
585 return returnVal;
586 }
587
getNativeControlRegion(ControlType type,ControlPart part,const Rectangle & controlRegion,ControlState controlState,const ImplControlValue & val,const OUString &,Rectangle & nativeBoundingRegion,Rectangle & nativeContentRegion)588 sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part,
589 const Rectangle& controlRegion, ControlState controlState,
590 const ImplControlValue& val,
591 const OUString&,
592 Rectangle &nativeBoundingRegion, Rectangle &nativeContentRegion )
593 {
594 bool retVal = false;
595
596 QRect boundingRect = region2QRect( controlRegion );
597 QRect contentRect = boundingRect;
598 QStyleOptionComplex styleOption;
599
600 switch ( type )
601 {
602 // Metrics of the push button
603 case CTRL_PUSHBUTTON:
604 if (part == PART_ENTIRE_CONTROL)
605 {
606 styleOption.state = vclStateValue2StateFlag(controlState, val);
607
608 if ( controlState & CTRL_STATE_DEFAULT )
609 {
610 int size = kapp->style()->pixelMetric(
611 QStyle::PM_ButtonDefaultIndicator, &styleOption );
612
613 boundingRect.adjust( -size, -size, size, size );
614
615 retVal = true;
616 }
617 }
618 break;
619 case CTRL_EDITBOX:
620 {
621 int nFontHeight = kapp->fontMetrics().height();
622 //int nFrameSize = kapp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
623 int nLayoutTop = kapp->style()->pixelMetric(QStyle::PM_LayoutTopMargin);
624 int nLayoutBottom = kapp->style()->pixelMetric(QStyle::PM_LayoutBottomMargin);
625 int nLayoutLeft = kapp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
626 int nLayoutRight = kapp->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
627
628 int nMinHeight = (nFontHeight + nLayoutTop + nLayoutBottom);
629 if( boundingRect.height() < nMinHeight )
630 {
631 int delta = nMinHeight - boundingRect.height();
632 boundingRect.adjust( 0, 0, 0, delta );
633 }
634 contentRect = boundingRect;
635 contentRect.adjust( -nLayoutLeft+1, -nLayoutTop+1, nLayoutRight-1, nLayoutBottom-1 );
636 retVal = true;
637
638 break;
639 }
640 case CTRL_CHECKBOX:
641 if (part == PART_ENTIRE_CONTROL)
642 {
643 styleOption.state = vclStateValue2StateFlag(controlState, val);
644
645 contentRect.setWidth(kapp->style()->pixelMetric(
646 QStyle::PM_IndicatorWidth, &styleOption));
647 contentRect.setHeight(kapp->style()->pixelMetric(
648 QStyle::PM_IndicatorHeight, &styleOption));
649
650 contentRect.adjust(0, 0,
651 2 * kapp->style()->pixelMetric(
652 QStyle::PM_FocusFrameHMargin, &styleOption),
653 2 * kapp->style()->pixelMetric(
654 QStyle::PM_FocusFrameVMargin, &styleOption)
655 );
656
657 boundingRect = contentRect;
658
659 retVal = true;
660
661 break;
662 }
663 case CTRL_COMBOBOX:
664 case CTRL_LISTBOX:
665 {
666 QStyleOptionComboBox cbo;
667
668 cbo.rect = QRect(0, 0, contentRect.width(), contentRect.height());
669 cbo.state = vclStateValue2StateFlag(controlState, val);
670
671 switch ( part )
672 {
673 case PART_ENTIRE_CONTROL:
674 {
675 int size = kapp->style()->pixelMetric(QStyle::PM_ComboBoxFrameWidth) - 2;
676
677 // find out the minimum size that should be used
678 // assume contents is a text ling
679 int nHeight = kapp->fontMetrics().height();
680 QSize aContentSize( contentRect.width(), nHeight );
681 QSize aMinSize = kapp->style()->
682 sizeFromContents( QStyle::CT_ComboBox, &cbo, aContentSize );
683 if( aMinSize.height() > contentRect.height() )
684 contentRect.adjust( 0, 0, 0, aMinSize.height() - contentRect.height() );
685 boundingRect = contentRect;
686 // FIXME: why this difference between comboboxes and listboxes ?
687 // because a combobox has a sub edit and that is positioned
688 // inside the outer bordered control ?
689 if( type == CTRL_COMBOBOX )
690 contentRect.adjust(-size,-size,size,size);
691 retVal = true;
692 break;
693 }
694 case PART_BUTTON_DOWN:
695 //the entire control can be used as the "down" button
696 retVal = true;
697 break;
698 case PART_SUB_EDIT:
699 contentRect = kapp->style()->subControlRect(
700 QStyle::CC_ComboBox, &cbo, QStyle::SC_ComboBoxEditField );
701
702 contentRect.translate( boundingRect.left(), boundingRect.top() );
703
704 retVal = true;
705 break;
706 case PART_WINDOW:
707 retVal = true;
708 break;
709 }
710 break;
711 }
712 case CTRL_SPINBOX:
713 {
714 QStyleOptionSpinBox sbo;
715
716 sbo.rect = QRect(0, 0, contentRect.width(), contentRect.height());
717 sbo.state = vclStateValue2StateFlag(controlState, val);
718
719 switch ( part )
720 {
721 case PART_BUTTON_UP:
722 contentRect = kapp->style()->subControlRect(
723 QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxUp );
724 contentRect.translate( boundingRect.left(), boundingRect.top() );
725 retVal = true;
726 boundingRect = QRect();
727 break;
728
729 case PART_BUTTON_DOWN:
730 contentRect = kapp->style()->subControlRect(
731 QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxDown );
732 retVal = true;
733 contentRect.translate( boundingRect.left(), boundingRect.top() );
734 boundingRect = QRect();
735 break;
736
737 case PART_SUB_EDIT:
738 contentRect = kapp->style()->subControlRect(
739 QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxEditField );
740 retVal = true;
741 contentRect.translate( boundingRect.left(), boundingRect.top() );
742 break;
743 default:
744 retVal = true;
745 }
746 break;
747 }
748 case CTRL_MENU_POPUP:
749 //just limit the widget of the menu items
750 //OO isn't very flexible in all reguards with the menu
751 //so we do the best we can
752 if (part == PART_MENU_ITEM_CHECK_MARK)
753 {
754 contentRect.setWidth(contentRect.height());
755 retVal = true;
756 }
757 else if (part == PART_MENU_ITEM_RADIO_MARK)
758 {
759 contentRect.setWidth(contentRect.height());
760 retVal = true;
761 }
762 break;
763 case CTRL_FRAME:
764 {
765 if( part == PART_BORDER )
766 {
767 int nFrameWidth = getFrameWidth();
768 sal_uInt16 nStyle = val.getNumericVal();
769 if( nStyle & FRAME_DRAW_NODRAW )
770 {
771 // in this case the question is: how thick would a frame be
772 // see brdwin.cxx, decoview.cxx
773 // most probably the behavior in decoview.cxx is wrong.
774 contentRect.adjust(nFrameWidth, nFrameWidth, -nFrameWidth, -nFrameWidth);
775 }
776 retVal = true;
777 }
778 break;
779 }
780 case CTRL_RADIOBUTTON:
781 {
782 const int h = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight);
783 const int w = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth);
784
785 contentRect = QRect(boundingRect.left(), boundingRect.top(), w, h);
786 contentRect.adjust(0, 0,
787 2 * kapp->style()->pixelMetric(
788 QStyle::PM_FocusFrameHMargin, &styleOption),
789 2 * kapp->style()->pixelMetric(
790 QStyle::PM_FocusFrameVMargin, &styleOption)
791 );
792 boundingRect = contentRect;
793
794 retVal = true;
795 break;
796 }
797 case CTRL_SLIDER:
798 {
799 const int w = kapp->style()->pixelMetric(QStyle::PM_SliderLength);
800 if( part == PART_THUMB_HORZ )
801 {
802 contentRect = QRect(boundingRect.left(), boundingRect.top(), w, boundingRect.height());
803 boundingRect = contentRect;
804 retVal = true;
805 }
806 else if( part == PART_THUMB_VERT )
807 {
808 contentRect = QRect(boundingRect.left(), boundingRect.top(), boundingRect.width(), w);
809 boundingRect = contentRect;
810 retVal = true;
811 }
812 break;
813 }
814 default:
815 break;
816 }
817 #if 0
818
819
820 // Metrics of the scroll bar
821 case CTRL_SCROLLBAR:
822 //pWidget = pWidgetPainter->scrollBar( rControlRegion,
823 //( part == PART_BUTTON_LEFT || part == PART_BUTTON_RIGHT ),
824 //ImplControlValue() );
825 //aStyleOption.initFrom( pWidget );
826
827 switch ( part )
828 {
829 case PART_BUTTON_LEFT:
830 case PART_BUTTON_UP:
831 qRect = kapp->style()->subControlRect(
832 QStyle::CC_ScrollBar, &aStyleOption, QStyle::SC_ScrollBarSubLine );
833
834 // Workaround for Platinum style scroll bars. It makes the
835 // left/up button invisible.
836 if ( part == PART_BUTTON_LEFT )
837 {
838 if ( qRect.left() > kapp->style()->subControlRect(
839 QStyle::CC_ScrollBar, &aStyleOption,
840 QStyle::SC_ScrollBarSubPage ).left() )
841 {
842 qRect.setLeft( 0 );
843 qRect.setRight( 0 );
844 }
845 }
846 else
847 {
848 if ( qRect.top() > kapp->style()->subControlRect(
849 QStyle::CC_ScrollBar, &aStyleOption,
850 QStyle::SC_ScrollBarSubPage ).top() )
851 {
852 qRect.setTop( 0 );
853 qRect.setBottom( 0 );
854 }
855 }
856
857 qRect.translate( qBoundingRect.left(), qBoundingRect.top() );
858
859 bReturn = TRUE;
860 break;
861
862 case PART_BUTTON_RIGHT:
863 case PART_BUTTON_DOWN:
864 qRect = kapp->style()->subControlRect(
865 QStyle::CC_ScrollBar, &aStyleOption, QStyle::SC_ScrollBarAddLine );
866
867 // Workaround for Platinum and 3 button style scroll bars.
868 // It makes the right/down button bigger.
869 if ( part == PART_BUTTON_RIGHT )
870 qRect.setLeft( kapp->style()->subControlRect(
871 QStyle::CC_ScrollBar, &aStyleOption,
872 QStyle::SC_ScrollBarAddPage ).right() + 1 );
873 else
874 qRect.setTop( kapp->style()->subControlRect(
875 QStyle::CC_ScrollBar, &aStyleOption,
876 QStyle::SC_ScrollBarAddPage ).bottom() + 1 );
877
878 qRect.translate( qBoundingRect.left(), qBoundingRect.top() );
879
880 bReturn = TRUE;
881 break;
882 }
883 break;
884 }
885 #endif
886
887 if (retVal)
888 {
889 // Bounding region
890 Point aBPoint( boundingRect.x(), boundingRect.y() );
891 Size aBSize( boundingRect.width(), boundingRect.height() );
892 nativeBoundingRegion = Rectangle( aBPoint, aBSize );
893
894 // Region of the content
895 Point aPoint( contentRect.x(), contentRect.y() );
896 Size aSize( contentRect.width(), contentRect.height() );
897 nativeContentRegion = Rectangle( aPoint, aSize );
898 }
899
900 return retVal;
901 }
902