blob: cb7fee823fd0f8954e43269dc05d6e849a68c5e7 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#define _SV_SALNATIVEWIDGETS_KDE_CXX
#define Region QtXRegion
#include <QStyle>
#include <QStyleOption>
#include <QPainter>
#include <QFrame>
#include <QLabel>
#include <kapplication.h>
#undef Region
#include "KDESalGraphics.hxx"
#include "vcl/settings.hxx"
#include "vcl/decoview.hxx"
#include "rtl/ustrbuf.hxx"
using namespace ::rtl;
/**
Conversion function between VCL ControlState together with
ImplControlValue and Qt state flags.
@param nControlState State of the widget (default, focused, ...) in Native Widget Framework.
@param aValue Value held by the widget (on, off, ...)
*/
QStyle::State vclStateValue2StateFlag( ControlState nControlState,
const ImplControlValue& aValue )
{
QStyle::State nState =
( (nControlState & CTRL_STATE_DEFAULT)? QStyle::State_None: QStyle::State_None ) |
( (nControlState & CTRL_STATE_ENABLED)? QStyle::State_Enabled: QStyle::State_None ) |
( (nControlState & CTRL_STATE_FOCUSED)? QStyle::State_HasFocus: QStyle::State_None ) |
( (nControlState & CTRL_STATE_PRESSED)? QStyle::State_Sunken: QStyle::State_None ) |
( (nControlState & CTRL_STATE_SELECTED)? QStyle::State_Selected : QStyle::State_None ) |
( (nControlState & CTRL_STATE_ROLLOVER)? QStyle::State_MouseOver: QStyle::State_None );
//TODO ( (nControlState & CTRL_STATE_HIDDEN)? QStyle::State_: QStyle::State_None ) |
switch ( aValue.getTristateVal() )
{
case BUTTONVALUE_ON: nState |= QStyle::State_On; break;
case BUTTONVALUE_OFF: nState |= QStyle::State_Off; break;
case BUTTONVALUE_MIXED: nState |= QStyle::State_NoChange; break;
default: break;
}
return nState;
}
/**
Convert VCL Rectangle to QRect.
@param rControlRegion The Rectangle to convert.
@return The matching QRect
*/
QRect region2QRect( const Rectangle& rControlRegion )
{
return QRect(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.GetWidth(), rControlRegion.GetHeight());
}
KDESalGraphics::KDESalGraphics() :
m_image(0)
{
}
KDESalGraphics::~KDESalGraphics()
{
if (m_image)
delete m_image;
}
sal_Bool KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart part )
{
if (type == CTRL_PUSHBUTTON) return true;
if (type == CTRL_MENUBAR) return true;
if (type == CTRL_MENU_POPUP) return true;
if (type == CTRL_EDITBOX) return true;
if (type == CTRL_COMBOBOX) return true;
if (type == CTRL_TOOLBAR) return true;
if (type == CTRL_CHECKBOX) return true;
if (type == CTRL_LISTBOX) return true;
if (type == CTRL_LISTNODE) return true;
if (type == CTRL_FRAME) return true;
if (type == CTRL_SCROLLBAR) return true;
if (type == CTRL_WINDOW_BACKGROUND) return true;
if (type == CTRL_SPINBOX && (part == PART_ENTIRE_CONTROL || part == HAS_BACKGROUND_TEXTURE) ) return true;
// no spinbuttons for KDE, paint spinbox complete
//if (type == CTRL_SPINBUTTONS) return true;
if (type == CTRL_GROUPBOX) return true;
if (type == CTRL_FIXEDLINE) return true;
if (type == CTRL_FIXEDBORDER) return true;
if (type == CTRL_TOOLTIP) return true;
if (type == CTRL_RADIOBUTTON) return true;
if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA) )
return true;
return false;
if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true;
if ( (type == CTRL_TAB_PANE) && (part == PART_ENTIRE_CONTROL) ) return true;
// no CTRL_TAB_BODY for KDE
if ( (type == CTRL_PROGRESS) && (part == PART_ENTIRE_CONTROL) ) return true;
return false;
}
sal_Bool KDESalGraphics::hitTestNativeControl( ControlType, ControlPart,
const Rectangle&, const Point&,
sal_Bool& )
{
return FALSE;
}
/// helper drawing methods
namespace
{
void draw( QStyle::ControlElement element, QStyleOption* option, QImage* image, QStyle::State state )
{
option->state |= state;
option->rect = image->rect();
QPainter painter(image);
kapp->style()->drawControl(element, option, &painter);
}
void draw( QStyle::PrimitiveElement element, QStyleOption* option, QImage* image, QStyle::State state, int nAdjust = 0 )
{
option->state |= state;
option->rect = image->rect();
if( nAdjust )
option->rect.adjust( nAdjust, nAdjust, -nAdjust, -nAdjust );
QPainter painter(image);
kapp->style()->drawPrimitive(element, option, &painter);
}
void draw( QStyle::ComplexControl element, QStyleOptionComplex* option, QImage* image, QStyle::State state )
{
option->state |= state;
option->rect = image->rect();
QPainter painter(image);
kapp->style()->drawComplexControl(element, option, &painter);
}
int getFrameWidth()
{
static int s_nFrameWidth = -1;
if( s_nFrameWidth < 0 )
{
// fill in a default
s_nFrameWidth = 2;
QFrame aFrame( NULL );
aFrame.setFrameRect( QRect(0, 0, 100, 30) );
aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
aFrame.ensurePolished();
s_nFrameWidth = aFrame.frameWidth();
}
return s_nFrameWidth;
}
void lcl_drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State state)
{
#if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) )
QStyleOptionFrameV3 option;
option.frameShape = QFrame::StyledPanel;
option.state = QStyle::State_Sunken;
#else
QStyleOptionFrame option;
QFrame aFrame( NULL );
aFrame.setFrameRect( QRect(0, 0, image->width(), image->height()) );
aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
aFrame.ensurePolished();
option.initFrom( &aFrame );
option.lineWidth = aFrame.lineWidth();
option.midLineWidth = aFrame.midLineWidth();
#endif
draw(element, &option, image, state);
}
}
sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
const Rectangle& rControlRegion, ControlState nControlState,
const ImplControlValue& value,
const OUString& )
{
// put not implemented types here
if (type == CTRL_SPINBUTTONS)
{
return false;
}
sal_Bool returnVal = true;
QRect widgetRect = region2QRect(rControlRegion);
if( type == CTRL_SPINBOX && part == PART_ALL_BUTTONS )
type = CTRL_SPINBUTTONS;
if( type == CTRL_SPINBUTTONS )
{
OSL_ASSERT( value.getType() != CTRL_SPINBUTTONS );
const SpinbuttonValue* pSpinVal = static_cast<const SpinbuttonValue *>(&value);
Rectangle aButtonRect( pSpinVal->maUpperRect);
aButtonRect.Union( pSpinVal->maLowerRect );;
widgetRect = QRect( aButtonRect.Left(), aButtonRect.Top(),
aButtonRect.Right(), aButtonRect.Bottom() );
}
//if no image, or resized, make a new image
if (!m_image || m_image->size() != widgetRect.size())
{
if (m_image)
delete m_image;
m_image = new QImage( widgetRect.width(),
widgetRect.height(),
QImage::Format_ARGB32 );
}
m_image->fill(KApplication::palette().color(QPalette::Window).rgb());
XLIB_Region pTempClipRegion = 0;
if (type == CTRL_PUSHBUTTON)
{
QStyleOptionButton option;
draw( QStyle::CE_PushButton, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if ( (type == CTRL_MENUBAR))
{
if (part == PART_MENU_ITEM)
{
QStyleOptionMenuItem option;
draw( QStyle::CE_MenuBarItem, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (part == PART_ENTIRE_CONTROL)
{
}
else
{
returnVal = false;
}
}
else if (type == CTRL_MENU_POPUP)
{
if (part == PART_MENU_ITEM)
{
QStyleOptionMenuItem option;
draw( QStyle::CE_MenuItem, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (part == PART_MENU_ITEM_CHECK_MARK && (nControlState & CTRL_STATE_PRESSED) )
{
QStyleOptionButton option;
draw( QStyle::PE_IndicatorMenuCheckMark, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (part == PART_MENU_ITEM_RADIO_MARK && (nControlState & CTRL_STATE_PRESSED) )
{
QStyleOptionButton option;
draw( QStyle::PE_IndicatorRadioButton, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else
{
#if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) )
QStyleOptionFrameV3 option;
option.frameShape = QFrame::StyledPanel;
#else
QStyleOptionFrameV2 option;
#endif
draw( QStyle::PE_FrameMenu, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
}
else if ( (type == CTRL_TOOLBAR) && (part == PART_BUTTON) )
{
QStyleOptionToolButton option;
option.arrowType = Qt::NoArrow;
option.subControls = QStyle::SC_ToolButton;
option.state = vclStateValue2StateFlag( nControlState, value );
option.state |= QStyle::State_Raised | QStyle::State_Enabled | QStyle::State_AutoRaise;
draw( QStyle::CC_ToolButton, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if ( (type == CTRL_TOOLBAR) && (part == PART_ENTIRE_CONTROL) )
{
QStyleOptionToolBar option;
option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height());
option.state = vclStateValue2StateFlag( nControlState, value );
draw( QStyle::CE_ToolBar, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if ( (type == CTRL_TOOLBAR) && (part == PART_THUMB_VERT) )
{
const int tw = widgetRect.width();
widgetRect.setWidth(kapp->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent));
QStyleOption option;
option.state = QStyle::State_Horizontal;
draw( QStyle::PE_IndicatorToolBarHandle, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
widgetRect.setWidth(tw);
}
else if (type == CTRL_EDITBOX)
{
QStyleOptionFrameV2 option;
draw( QStyle::PE_PanelLineEdit, &option, m_image,
vclStateValue2StateFlag(nControlState, value), 2 );
draw( QStyle::PE_FrameLineEdit, &option, m_image,
vclStateValue2StateFlag(nControlState, value), 0 );
}
else if (type == CTRL_COMBOBOX)
{
QStyleOptionComboBox option;
option.editable = true;
draw( QStyle::CC_ComboBox, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_LISTBOX)
{
if( part == PART_WINDOW )
{
lcl_drawFrame( QStyle::PE_Frame, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else
{
QStyleOptionComboBox option;
if (part == PART_SUB_EDIT)
{
draw( QStyle::CE_ComboBoxLabel, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else
{
draw( QStyle::CC_ComboBox, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
}
}
else if (type == CTRL_LISTNODE)
{
QStyleOption option;
option.state = QStyle::State_Item | QStyle::State_Children;
if (nControlState & CTRL_STATE_PRESSED)
option.state |= QStyle::State_Open;
draw( QStyle::PE_IndicatorBranch, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_CHECKBOX)
{
QStyleOptionButton option;
draw( QStyle::CE_CheckBox, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_SCROLLBAR)
{
if ((part == PART_DRAW_BACKGROUND_VERT) || (part == PART_DRAW_BACKGROUND_HORZ))
{
QStyleOptionSlider option;
OSL_ASSERT( value.getType() == CTRL_SCROLLBAR );
const ScrollbarValue* sbVal = static_cast<const ScrollbarValue *>(&value);
//if the scroll bar is active (aka not degenrate...allow for hover events
if (sbVal->mnVisibleSize < sbVal->mnMax)
option.state = QStyle::State_MouseOver;
//horizontal or vertical
if (part == PART_DRAW_BACKGROUND_VERT)
option.orientation = Qt::Vertical;
else
option.state |= QStyle::State_Horizontal;
//setup parameters from the OO values
option.minimum = sbVal->mnMin;
option.maximum = sbVal->mnMax - sbVal->mnVisibleSize;
option.sliderValue = sbVal->mnCur;
option.sliderPosition = sbVal->mnCur;
option.pageStep = sbVal->mnVisibleSize;
//setup the active control...always the slider
if (sbVal->mnThumbState & CTRL_STATE_ROLLOVER)
option.activeSubControls = QStyle::SC_ScrollBarSlider;
draw( QStyle::CC_ScrollBar, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else
{
returnVal = false;
}
}
else if (type == CTRL_SPINBOX)
{
QStyleOptionSpinBox option;
// determine active control
if( value.getType() == CTRL_SPINBUTTONS )
{
const SpinbuttonValue* pSpinVal = static_cast<const SpinbuttonValue *>(&value);
if( (pSpinVal->mnUpperState & CTRL_STATE_PRESSED) )
option.activeSubControls |= QStyle::SC_SpinBoxUp;
if( (pSpinVal->mnLowerState & CTRL_STATE_PRESSED) )
option.activeSubControls |= QStyle::SC_SpinBoxDown;
}
draw( QStyle::CC_SpinBox, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_GROUPBOX)
{
QStyleOptionGroupBox option;
draw( QStyle::CC_GroupBox, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_RADIOBUTTON)
{
QStyleOptionButton option;
draw( QStyle::CE_RadioButton, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_TOOLTIP)
{
QStyleOption option;
draw( QStyle::PE_PanelTipLabel, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_FRAME)
{
lcl_drawFrame( QStyle::PE_Frame, m_image,
vclStateValue2StateFlag(nControlState, value) );
// draw just the border, see http://qa.openoffice.org/issues/show_bug.cgi?id=107945
int nFrameWidth = getFrameWidth();
pTempClipRegion = XCreateRegion();
XRectangle xRect = { widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height() };
XUnionRectWithRegion( &xRect, pTempClipRegion, pTempClipRegion );
xRect.x += nFrameWidth;
xRect.y += nFrameWidth;
// do not crash for too small widgets, see http://qa.openoffice.org/issues/show_bug.cgi?id=112102
if( xRect.width > 2*nFrameWidth && xRect.height > 2*nFrameWidth )
{
xRect.width -= 2*nFrameWidth;
xRect.height -= 2*nFrameWidth;
XLIB_Region pSubtract = XCreateRegion();
XUnionRectWithRegion( &xRect, pSubtract, pSubtract );
XSubtractRegion( pTempClipRegion, pSubtract, pTempClipRegion );
XDestroyRegion( pSubtract );
}
}
else if (type == CTRL_FIXEDBORDER)
{
lcl_drawFrame( QStyle::PE_FrameWindow, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_WINDOW_BACKGROUND)
{
m_image->fill(KApplication::palette().color(QPalette::Window).rgb());
}
else if (type == CTRL_FIXEDLINE)
{
QStyleOptionMenuItem option;
option.menuItemType = QStyleOptionMenuItem::Separator;
option.state |= QStyle::State_Item;
draw( QStyle::CE_MenuItem, &option, m_image,
vclStateValue2StateFlag(nControlState, value) );
}
else if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA))
{
OSL_ASSERT( value.getType() == CTRL_SLIDER );
const SliderValue* slVal = static_cast<const SliderValue *>(&value);
QStyleOptionSlider option;
option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height());
option.state = vclStateValue2StateFlag( nControlState, value );
option.maximum = slVal->mnMax;
option.minimum = slVal->mnMin;
option.sliderPosition = option.sliderValue = slVal->mnCur;
option.orientation = (part == PART_TRACK_HORZ_AREA) ? Qt::Horizontal : Qt::Vertical;
draw( QStyle::CC_Slider, &option, m_image, vclStateValue2StateFlag(nControlState, value) );
}
else
{
returnVal = false;
}
if (returnVal)
{
GC gc = GetFontGC();
if( gc )
{
if( pTempClipRegion )
{
if( mpClipRegion )
XIntersectRegion( pTempClipRegion, mpClipRegion, pTempClipRegion );
XSetRegion( GetXDisplay(), gc, pTempClipRegion );
}
QPixmap pixmap = QPixmap::fromImage(*m_image, Qt::ColorOnly | Qt::OrderedDither | Qt::OrderedAlphaDither);
X11SalGraphics::CopyScreenArea( GetXDisplay(),
pixmap.handle(), pixmap.x11Info().screen(), pixmap.x11Info().depth(),
GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
gc, 0, 0, widgetRect.width(), widgetRect.height(), widgetRect.left(), widgetRect.top());
if( pTempClipRegion )
{
if( mpClipRegion )
XSetRegion( GetXDisplay(), gc, mpClipRegion );
else
XSetClipMask( GetXDisplay(), gc, None );
}
}
else
returnVal = false;
}
if( pTempClipRegion )
XDestroyRegion( pTempClipRegion );
return returnVal;
}
sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part,
const Rectangle& controlRegion, ControlState controlState,
const ImplControlValue& val,
const OUString&,
Rectangle &nativeBoundingRegion, Rectangle &nativeContentRegion )
{
bool retVal = false;
QRect boundingRect = region2QRect( controlRegion );
QRect contentRect = boundingRect;
QStyleOptionComplex styleOption;
switch ( type )
{
// Metrics of the push button
case CTRL_PUSHBUTTON:
if (part == PART_ENTIRE_CONTROL)
{
styleOption.state = vclStateValue2StateFlag(controlState, val);
if ( controlState & CTRL_STATE_DEFAULT )
{
int size = kapp->style()->pixelMetric(
QStyle::PM_ButtonDefaultIndicator, &styleOption );
boundingRect.adjust( -size, -size, size, size );
retVal = true;
}
}
break;
case CTRL_EDITBOX:
{
int nFontHeight = kapp->fontMetrics().height();
//int nFrameSize = kapp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
int nLayoutTop = kapp->style()->pixelMetric(QStyle::PM_LayoutTopMargin);
int nLayoutBottom = kapp->style()->pixelMetric(QStyle::PM_LayoutBottomMargin);
int nLayoutLeft = kapp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
int nLayoutRight = kapp->style()->pixelMetric(QStyle::PM_LayoutRightMargin);
int nMinHeight = (nFontHeight + nLayoutTop + nLayoutBottom);
if( boundingRect.height() < nMinHeight )
{
int delta = nMinHeight - boundingRect.height();
boundingRect.adjust( 0, 0, 0, delta );
}
contentRect = boundingRect;
contentRect.adjust( -nLayoutLeft+1, -nLayoutTop+1, nLayoutRight-1, nLayoutBottom-1 );
retVal = true;
break;
}
case CTRL_CHECKBOX:
if (part == PART_ENTIRE_CONTROL)
{
styleOption.state = vclStateValue2StateFlag(controlState, val);
contentRect.setWidth(kapp->style()->pixelMetric(
QStyle::PM_IndicatorWidth, &styleOption));
contentRect.setHeight(kapp->style()->pixelMetric(
QStyle::PM_IndicatorHeight, &styleOption));
contentRect.adjust(0, 0,
2 * kapp->style()->pixelMetric(
QStyle::PM_FocusFrameHMargin, &styleOption),
2 * kapp->style()->pixelMetric(
QStyle::PM_FocusFrameVMargin, &styleOption)
);
boundingRect = contentRect;
retVal = true;
break;
}
case CTRL_COMBOBOX:
case CTRL_LISTBOX:
{
QStyleOptionComboBox cbo;
cbo.rect = QRect(0, 0, contentRect.width(), contentRect.height());
cbo.state = vclStateValue2StateFlag(controlState, val);
switch ( part )
{
case PART_ENTIRE_CONTROL:
{
int size = kapp->style()->pixelMetric(QStyle::PM_ComboBoxFrameWidth) - 2;
// find out the minimum size that should be used
// assume contents is a text ling
int nHeight = kapp->fontMetrics().height();
QSize aContentSize( contentRect.width(), nHeight );
QSize aMinSize = kapp->style()->
sizeFromContents( QStyle::CT_ComboBox, &cbo, aContentSize );
if( aMinSize.height() > contentRect.height() )
contentRect.adjust( 0, 0, 0, aMinSize.height() - contentRect.height() );
boundingRect = contentRect;
// FIXME: why this difference between comboboxes and listboxes ?
// because a combobox has a sub edit and that is positioned
// inside the outer bordered control ?
if( type == CTRL_COMBOBOX )
contentRect.adjust(-size,-size,size,size);
retVal = true;
break;
}
case PART_BUTTON_DOWN:
//the entire control can be used as the "down" button
retVal = true;
break;
case PART_SUB_EDIT:
contentRect = kapp->style()->subControlRect(
QStyle::CC_ComboBox, &cbo, QStyle::SC_ComboBoxEditField );
contentRect.translate( boundingRect.left(), boundingRect.top() );
retVal = true;
break;
case PART_WINDOW:
retVal = true;
break;
}
break;
}
case CTRL_SPINBOX:
{
QStyleOptionSpinBox sbo;
sbo.rect = QRect(0, 0, contentRect.width(), contentRect.height());
sbo.state = vclStateValue2StateFlag(controlState, val);
switch ( part )
{
case PART_BUTTON_UP:
contentRect = kapp->style()->subControlRect(
QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxUp );
contentRect.translate( boundingRect.left(), boundingRect.top() );
retVal = true;
boundingRect = QRect();
break;
case PART_BUTTON_DOWN:
contentRect = kapp->style()->subControlRect(
QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxDown );
retVal = true;
contentRect.translate( boundingRect.left(), boundingRect.top() );
boundingRect = QRect();
break;
case PART_SUB_EDIT:
contentRect = kapp->style()->subControlRect(
QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxEditField );
retVal = true;
contentRect.translate( boundingRect.left(), boundingRect.top() );
break;
default:
retVal = true;
}
break;
}
case CTRL_MENU_POPUP:
//just limit the widget of the menu items
//OO isn't very flexible in all reguards with the menu
//so we do the best we can
if (part == PART_MENU_ITEM_CHECK_MARK)
{
contentRect.setWidth(contentRect.height());
retVal = true;
}
else if (part == PART_MENU_ITEM_RADIO_MARK)
{
contentRect.setWidth(contentRect.height());
retVal = true;
}
break;
case CTRL_FRAME:
{
if( part == PART_BORDER )
{
int nFrameWidth = getFrameWidth();
sal_uInt16 nStyle = val.getNumericVal();
if( nStyle & FRAME_DRAW_NODRAW )
{
// in this case the question is: how thick would a frame be
// see brdwin.cxx, decoview.cxx
// most probably the behavior in decoview.cxx is wrong.
contentRect.adjust(nFrameWidth, nFrameWidth, -nFrameWidth, -nFrameWidth);
}
retVal = true;
}
break;
}
case CTRL_RADIOBUTTON:
{
const int h = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight);
const int w = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth);
contentRect = QRect(boundingRect.left(), boundingRect.top(), w, h);
contentRect.adjust(0, 0,
2 * kapp->style()->pixelMetric(
QStyle::PM_FocusFrameHMargin, &styleOption),
2 * kapp->style()->pixelMetric(
QStyle::PM_FocusFrameVMargin, &styleOption)
);
boundingRect = contentRect;
retVal = true;
break;
}
case CTRL_SLIDER:
{
const int w = kapp->style()->pixelMetric(QStyle::PM_SliderLength);
if( part == PART_THUMB_HORZ )
{
contentRect = QRect(boundingRect.left(), boundingRect.top(), w, boundingRect.height());
boundingRect = contentRect;
retVal = true;
}
else if( part == PART_THUMB_VERT )
{
contentRect = QRect(boundingRect.left(), boundingRect.top(), boundingRect.width(), w);
boundingRect = contentRect;
retVal = true;
}
break;
}
default:
break;
}
#if 0
// Metrics of the scroll bar
case CTRL_SCROLLBAR:
//pWidget = pWidgetPainter->scrollBar( rControlRegion,
//( part == PART_BUTTON_LEFT || part == PART_BUTTON_RIGHT ),
//ImplControlValue() );
//aStyleOption.initFrom( pWidget );
switch ( part )
{
case PART_BUTTON_LEFT:
case PART_BUTTON_UP:
qRect = kapp->style()->subControlRect(
QStyle::CC_ScrollBar, &aStyleOption, QStyle::SC_ScrollBarSubLine );
// Workaround for Platinum style scroll bars. It makes the
// left/up button invisible.
if ( part == PART_BUTTON_LEFT )
{
if ( qRect.left() > kapp->style()->subControlRect(
QStyle::CC_ScrollBar, &aStyleOption,
QStyle::SC_ScrollBarSubPage ).left() )
{
qRect.setLeft( 0 );
qRect.setRight( 0 );
}
}
else
{
if ( qRect.top() > kapp->style()->subControlRect(
QStyle::CC_ScrollBar, &aStyleOption,
QStyle::SC_ScrollBarSubPage ).top() )
{
qRect.setTop( 0 );
qRect.setBottom( 0 );
}
}
qRect.translate( qBoundingRect.left(), qBoundingRect.top() );
bReturn = TRUE;
break;
case PART_BUTTON_RIGHT:
case PART_BUTTON_DOWN:
qRect = kapp->style()->subControlRect(
QStyle::CC_ScrollBar, &aStyleOption, QStyle::SC_ScrollBarAddLine );
// Workaround for Platinum and 3 button style scroll bars.
// It makes the right/down button bigger.
if ( part == PART_BUTTON_RIGHT )
qRect.setLeft( kapp->style()->subControlRect(
QStyle::CC_ScrollBar, &aStyleOption,
QStyle::SC_ScrollBarAddPage ).right() + 1 );
else
qRect.setTop( kapp->style()->subControlRect(
QStyle::CC_ScrollBar, &aStyleOption,
QStyle::SC_ScrollBarAddPage ).bottom() + 1 );
qRect.translate( qBoundingRect.left(), qBoundingRect.top() );
bReturn = TRUE;
break;
}
break;
}
#endif
if (retVal)
{
// Bounding region
Point aBPoint( boundingRect.x(), boundingRect.y() );
Size aBSize( boundingRect.width(), boundingRect.height() );
nativeBoundingRegion = Rectangle( aBPoint, aBSize );
// Region of the content
Point aPoint( contentRect.x(), contentRect.y() );
Size aSize( contentRect.width(), contentRect.height() );
nativeContentRegion = Rectangle( aPoint, aSize );
}
return retVal;
}