#ifndef adwaitastyle_h
#define adwaitastyle_h
/*************************************************************************
* Copyright (C) 2014 by Hugo Pereira Da Costa <hugo.pereira@free.fr> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
*************************************************************************/
#include "adwaita.h"
#include "config-adwaita.h"
#if ADWAITA_USE_KDE4
#include "kstylekde4compat.h"
#endif
#include <QAbstractItemView>
#include <QAbstractScrollArea>
#include <QCommonStyle>
#include <QDockWidget>
#include <QHash>
#include <QIcon>
#include <QMdiSubWindow>
#include <QStyleOption>
#include <QWidget>
#if QT_VERSION >= 0x050000
#include <QCommandLinkButton>
#endif
namespace AdwaitaPrivate
{
class TabBarData;
}
namespace Adwaita
{
class Animations;
class Helper;
class Mnemonics;
class SplitterFactory;
class WidgetExplorer;
class WindowManager;
//* convenience typedef for base class
#if ADWAITA_USE_KDE4
using ParentStyleClass = KStyleKDE4Compat;
#else
using ParentStyleClass = QCommonStyle;
#endif
//* base class for adwaita style
/** it is responsible to draw all the primitives to be displayed on screen, on request from Qt paint engine */
class Style: public ParentStyleClass
{
Q_OBJECT
/* this tells kde applications that custom style elements are supported, using the kstyle mechanism */
Q_CLASSINFO ("X-KDE-CustomElements", "true")
public:
//* constructor
explicit Style( bool dark );
//* destructor
virtual ~Style( void );
//* needed to avoid warnings at compilation time
using ParentStyleClass::polish;
using ParentStyleClass::unpolish;
//* widget polishing
virtual void polish( QWidget* );
//* widget unpolishing
virtual void unpolish( QWidget* );
//* palette polishing
virtual void polish( QPalette &palette );
//* polish scrollarea
void polishScrollArea( QAbstractScrollArea* );
//* pixel metrics
virtual int pixelMetric(PixelMetric, const QStyleOption* = nullptr, const QWidget* = nullptr) const;
//* style hints
virtual int styleHint(StyleHint, const QStyleOption* = nullptr, const QWidget* = nullptr, QStyleHintReturn* = nullptr) const;
//* returns rect corresponding to one widget's subelement
virtual QRect subElementRect( SubElement, const QStyleOption*, const QWidget* ) const;
//* returns rect corresponding to one widget's subcontrol
virtual QRect subControlRect( ComplexControl, const QStyleOptionComplex*, SubControl, const QWidget* ) const;
//* returns size matching contents
QSize sizeFromContents( ContentsType, const QStyleOption*, const QSize&, const QWidget* ) const;
//* returns which subcontrol given QPoint corresponds to
SubControl hitTestComplexControl( ComplexControl, const QStyleOptionComplex*, const QPoint&, const QWidget* ) const;
//* primitives
void drawPrimitive( PrimitiveElement, const QStyleOption*, QPainter*, const QWidget* ) const;
//* controls
void drawControl( ControlElement, const QStyleOption*, QPainter*, const QWidget* ) const;
//* complex controls
void drawComplexControl( ComplexControl, const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
//* generic text rendering
virtual void drawItemText(
QPainter*, const QRect&, int alignment, const QPalette&, bool enabled,
const QString&, QPalette::ColorRole = QPalette::NoRole) const;
//*@name event filters
//@{
virtual bool eventFilter(QObject *, QEvent *);
bool eventFilterScrollArea( QWidget*, QEvent* );
bool eventFilterComboBoxContainer( QWidget*, QEvent* );
bool eventFilterDockWidget( QDockWidget*, QEvent* );
bool eventFilterMdiSubWindow( QMdiSubWindow*, QEvent* );
#if QT_VERSION >= 0x050000
bool eventFilterCommandLinkButton( QCommandLinkButton*, QEvent* );
#endif
//* install event filter to object, in a unique way
void addEventFilter( QObject* object )
{
object->removeEventFilter( this );
object->installEventFilter( this );
}
//@}
protected Q_SLOTS:
//* update configuration
void configurationChanged( void );
//* standard icons
virtual QIcon standardIconImplementation( StandardPixmap, const QStyleOption*, const QWidget* ) const;
protected:
//* standard icons
virtual QIcon standardIcon( StandardPixmap pixmap, const QStyleOption* option = nullptr, const QWidget* widget = nullptr) const
{ return standardIconImplementation( pixmap, option, widget ); }
//* load configuration
void loadConfiguration();
//*@name subelementRect specialized functions
//@{
//* default implementation. Does not change anything
QRect defaultSubElementRect( const QStyleOption* option, const QWidget* ) const
{ return option->rect; }
QRect pushButtonContentsRect( const QStyleOption*, const QWidget* ) const;
QRect pushButtonFocusRect( const QStyleOption*, const QWidget* ) const;
QRect checkBoxContentsRect( const QStyleOption*, const QWidget* ) const;
QRect checkBoxIndicatorRect( const QStyleOption*, const QWidget* ) const;
QRect checkBoxFocusRect( const QStyleOption*, const QWidget* ) const;
QRect lineEditContentsRect( const QStyleOption*, const QWidget* ) const;
QRect progressBarGrooveRect( const QStyleOption*, const QWidget* ) const;
QRect progressBarContentsRect( const QStyleOption*, const QWidget* ) const;
QRect progressBarLabelRect( const QStyleOption*, const QWidget* ) const;
QRect headerArrowRect( const QStyleOption*, const QWidget* ) const;
QRect headerLabelRect( const QStyleOption*, const QWidget* ) const;
QRect sliderFocusRect( const QStyleOption*, const QWidget* ) const;
QRect tabBarTabLeftButtonRect( const QStyleOption*, const QWidget* ) const;
QRect tabBarTabRightButtonRect( const QStyleOption*, const QWidget* ) const;
QRect tabWidgetTabBarRect( const QStyleOption*, const QWidget* ) const;
QRect tabWidgetTabContentsRect( const QStyleOption*, const QWidget* ) const;
QRect tabWidgetTabPaneRect( const QStyleOption*, const QWidget* ) const;
QRect tabWidgetCornerRect( SubElement, const QStyleOption*, const QWidget* widget ) const;
QRect toolBoxTabContentsRect( const QStyleOption*, const QWidget* ) const;
QRect genericLayoutItemRect( const QStyleOption*, const QWidget* ) const;
//@}
//*@name subcontrol Rect specialized functions
//@{
QRect groupBoxSubControlRect( const QStyleOptionComplex*, SubControl, const QWidget* ) const;
QRect toolButtonSubControlRect( const QStyleOptionComplex*, SubControl, const QWidget* ) const;
QRect comboBoxSubControlRect( const QStyleOptionComplex*, SubControl, const QWidget* ) const;
QRect spinBoxSubControlRect( const QStyleOptionComplex*, SubControl, const QWidget* ) const;
QRect scrollBarInternalSubControlRect( const QStyleOptionComplex*, SubControl ) const;
QRect scrollBarSubControlRect( const QStyleOptionComplex*, SubControl, const QWidget* ) const;
QRect dialSubControlRect( const QStyleOptionComplex*, SubControl, const QWidget* ) const;
QRect sliderSubControlRect( const QStyleOptionComplex*, SubControl, const QWidget* ) const;
//@}
//*@name sizeFromContents
//@{
QSize defaultSizeFromContents( const QStyleOption*, const QSize& size, const QWidget* ) const
{ return size; }
QSize checkBoxSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize lineEditSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize comboBoxSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize spinBoxSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize sliderSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize pushButtonSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize toolButtonSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize menuBarItemSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize menuItemSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize progressBarSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize tabWidgetSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize tabBarTabSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize headerSectionSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
QSize itemViewItemSizeFromContents( const QStyleOption*, const QSize&, const QWidget* ) const;
//@}
//*@name primitives specialized functions
//@{
bool emptyPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const
{ return true; }
bool drawFramePrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawFrameLineEditPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawFrameFocusRectPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawFrameMenuPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawFrameGroupBoxPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawFrameTabWidgetPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawFrameTabBarBasePrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawFrameWindowPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorArrowUpPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
{ return drawIndicatorArrowPrimitive( ArrowUp, option, painter, widget ); }
bool drawIndicatorArrowDownPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
{ return drawIndicatorArrowPrimitive( ArrowDown, option, painter, widget ); }
bool drawIndicatorArrowLeftPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
{ return drawIndicatorArrowPrimitive( ArrowLeft, option, painter, widget ); }
bool drawIndicatorArrowRightPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const
{ return drawIndicatorArrowPrimitive( ArrowRight, option, painter, widget ); }
bool drawIndicatorArrowPrimitive( ArrowOrientation, const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorHeaderArrowPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawPanelButtonCommandPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawPanelButtonToolPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawTabBarPanelButtonToolPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawPanelScrollAreaCornerPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawPanelMenuPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawPanelTipLabelPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawPanelItemViewItemPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorCheckBoxPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorRadioButtonPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorButtonDropDownPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorTabClosePrimitive( const QStyleOption*, QPainter* painter, const QWidget* widget ) const;
bool drawIndicatorTabTearPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorToolBarHandlePrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorToolBarSeparatorPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
bool drawIndicatorBranchPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const;
//@}
//*@name controls specialized functions
//@{
bool emptyControl( const QStyleOption*, QPainter*, const QWidget* ) const
{ return true; }
virtual bool drawPushButtonLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawToolButtonLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawCheckBoxLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawComboBoxLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawMenuBarEmptyArea( const QStyleOption*, QPainter* , const QWidget*) const;
virtual bool drawMenuBarItemControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawMenuEmptyAreaControl( const QStyleOption*, QPainter* , const QWidget*) const;
virtual bool drawMenuItemControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawProgressBarControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawProgressBarContentsControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawProgressBarGrooveControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawProgressBarLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawScrollBarSliderControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawScrollBarAddLineControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawScrollBarSubLineControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawShapedFrameControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawRubberBandControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawHeaderSectionControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawHeaderLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawHeaderEmptyAreaControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawTabBarTabLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawTabBarTabShapeControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawToolBoxTabLabelControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawToolBoxTabShapeControl( const QStyleOption*, QPainter*, const QWidget* ) const;
virtual bool drawDockWidgetTitleControl( const QStyleOption*, QPainter*, const QWidget* ) const;
//*@}
//*@name complex ontrols specialized functions
//@{
bool drawGroupBoxComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
bool drawToolButtonComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
bool drawComboBoxComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
bool drawSpinBoxComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
bool drawSliderComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
bool drawDialComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
bool drawScrollBarComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
bool drawTitleBarComplexControl( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
//@}
//!*@name various utilty functions
//@{
//* spinbox arrows
void renderSpinBoxArrow( const SubControl&, const QStyleOptionSpinBox*, QPainter*, const QWidget*) const;
//* menu title
void renderMenuTitle( const QStyleOptionToolButton*, QPainter*, const QWidget* ) const;
//* return dial angle based on option and value
qreal dialAngle( const QStyleOptionSlider*, int ) const;
//* returns relevant scrollbar parent
/** needed to detect parent focus */
const QWidget* scrollBarParent( const QWidget* ) const;
//* returns true if given scrollbar arrow is animated
QColor scrollBarArrowColor( const QStyleOptionSlider*, const SubControl&, const QWidget* ) const;
//* scrollbar buttons
enum ScrollBarButtonType
{
NoButton,
SingleButton,
DoubleButton
};
//* returns height for scrollbar buttons depending of button types
int scrollBarButtonHeight( const ScrollBarButtonType& type ) const
{
switch( type )
{
case NoButton: return Metrics::ScrollBar_NoButtonHeight;
case SingleButton: return Metrics::ScrollBar_SingleButtonHeight;
case DoubleButton: return Metrics::ScrollBar_DoubleButtonHeight;
default: return 0;
}
}
//@}
//* translucent background
void setTranslucentBackground( QWidget* ) const;
/**
separator can have a title and an icon
in that case they are rendered as sunken flat toolbuttons
return toolbutton option that matches named separator menu items
*/
QStyleOptionToolButton separatorMenuItemOption( const QStyleOptionMenuItem*, const QWidget* ) const;
//* create toolbar extension icon
QIcon toolBarExtensionIcon( StandardPixmap, const QStyleOption*, const QWidget* ) const;
//* create title bar button icon
QIcon titleBarButtonIcon( StandardPixmap, const QStyleOption*, const QWidget* ) const;
//* returns item view parent if any
/** needed to have correct color on focused checkboxes and radiobuttons */
const QAbstractItemView* itemViewParent( const QWidget* ) const;
//* returns true if a given widget is a selected item in a focused list
/**
This is necessary to have the correct colors used for e.g. checkboxes and radiobuttons in lists
@param widget The widget to be checked
@param position Used to find the relevant QModelIndex
*/
bool isSelectedItem( const QWidget*, const QPoint& ) const;
//* return true if option corresponds to QtQuick control
bool isQtQuickControl( const QStyleOption*, const QWidget* ) const;
//@}
//* adjust rect based on provided margins
QRect insideMargin( const QRect& r, int margin ) const
{ return insideMargin( r, margin, margin ); }
//* adjust rect based on provided margins
QRect insideMargin( const QRect& r, int marginWidth, int marginHeight ) const
{ return r.adjusted( marginWidth, marginHeight, -marginWidth, -marginHeight ); }
//* expand size based on margins
QSize expandSize( const QSize& size, int margin ) const
{ return expandSize( size, margin, margin ); }
//* expand size based on margins
QSize expandSize( const QSize& size, int marginWidth, int marginHeight ) const
{ return size + 2*QSize( marginWidth, marginHeight ); }
//* returns true for vertical tabs
bool isVerticalTab( const QStyleOptionTab* option ) const
{ return isVerticalTab( option->shape ); }
bool isVerticalTab( const QTabBar::Shape& shape ) const
{
return shape == QTabBar::RoundedEast
|| shape == QTabBar::RoundedWest
|| shape == QTabBar::TriangularEast
|| shape == QTabBar::TriangularWest;
}
//* right to left alignment handling
using ParentStyleClass::visualRect;
QRect visualRect(const QStyleOption* opt, const QRect& subRect) const
{ return ParentStyleClass::visualRect(opt->direction, opt->rect, subRect); }
//* centering
QRect centerRect(const QRect &rect, const QSize& size ) const
{ return centerRect( rect, size.width(), size.height() ); }
QRect centerRect(const QRect &rect, int width, int height) const
{ return QRect(rect.left() + (rect.width() - width)/2, rect.top() + (rect.height() - height)/2, width, height); }
/*
Checks whether the point is before the bound rect for bound of given orientation.
This is needed to implement custom number of buttons in scrollbars,
as well as proper mouse-hover
*/
inline bool preceeds( const QPoint&, const QRect&, const QStyleOption* ) const;
//* return which arrow button is hit by point for scrollbar double buttons
inline QStyle::SubControl scrollBarHitTest( const QRect&, const QPoint&, const QStyleOption* ) const;
//! return true if one of the widget's parent inherits requested type
inline bool hasParent( const QWidget*, const char* ) const;
//* return true if one of the widget's parent inherits requested type
template<typename T> bool hasParent( const QWidget* ) const;
//* return true if icons should be shown in menus
bool showIconsInMenuItems( void ) const;
//* return true if icons should be shown on buttons
bool showIconsOnPushButtons( void ) const;
//* return true if passed widget is a menu title (KMenu::addTitle)
bool isMenuTitle( const QWidget* ) const;
//* return true if passed widget is a menu title (KMenu::addTitle)
bool hasAlteredBackground( const QWidget* ) const;
private:
//*@name scrollbar button types (for addLine and subLine )
//@{
ScrollBarButtonType _addLineButtons;
ScrollBarButtonType _subLineButtons;
//@}
//* helper
Helper* _helper;
//* animations
Animations* _animations;
//* keyboard accelerators
Mnemonics* _mnemonics;
//* window manager
WindowManager* _windowManager;
//* splitter Factory, to extend splitters hit area
SplitterFactory* _splitterFactory;
//* widget explorer
WidgetExplorer* _widgetExplorer;
//* tabbar data
AdwaitaPrivate::TabBarData* _tabBarData;
//* icon hash
using IconCache = QHash<StandardPixmap, QIcon>;
IconCache _iconCache;
//* pointer to primitive specialized function
using StylePrimitive = bool(Style::*)(const QStyleOption*, QPainter*, const QWidget* ) const;
StylePrimitive _frameFocusPrimitive = nullptr;
//* pointer to control specialized function
using StyleControl = bool (Style::*)( const QStyleOption*, QPainter*, const QWidget* ) const;
//* pointer to control specialized function
using StyleComplexControl = bool (Style::*)( const QStyleOptionComplex*, QPainter*, const QWidget* ) const;
//*@name custom elements
//@{
//* use Argb Drag and Drop Window
QStyle::StyleHint SH_ArgbDndWindow;
//! styled painting for KCapacityBar
QStyle::ControlElement CE_CapacityBar;
bool _dark { false };
bool _isGNOME { false };
bool _isKDE { false };
//@}
};
//_________________________________________________________________________
bool Style::preceeds( const QPoint& point, const QRect& bound, const QStyleOption* option ) const
{
if( option->state&QStyle::State_Horizontal)
{
if( option->direction == Qt::LeftToRight) return point.x() < bound.right();
else return point.x() > bound.x();
} else return point.y() < bound.y();
}
//_________________________________________________________________________
QStyle::SubControl Style::scrollBarHitTest( const QRect& rect, const QPoint& point, const QStyleOption* option ) const
{
if( option->state & QStyle::State_Horizontal)
{
if( option->direction == Qt::LeftToRight ) return point.x() < rect.center().x() ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine;
else return point.x() > rect.center().x() ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine;
} else return point.y() < rect.center().y() ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine;
}
//_________________________________________________________________________
bool Style::hasParent( const QWidget* widget, const char* className ) const
{
if( !widget ) return false;
while( (widget = widget->parentWidget()) )
{ if( widget->inherits( className ) ) return true; }
return false;
}
//_________________________________________________________________________
template< typename T > bool Style::hasParent( const QWidget* widget ) const
{
if( !widget ) return false;
while( (widget = widget->parentWidget()) )
{ if( qobject_cast<const T*>( widget ) ) return true; }
return false;
}
}
#endif