1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of Qt for Python.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** BSD License Usage
18 ** Alternatively, you may use this file under the terms of the BSD license
19 ** as follows:
20 **
21 ** "Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions are
23 ** met:
24 **   * Redistributions of source code must retain the above copyright
25 **     notice, this list of conditions and the following disclaimer.
26 **   * Redistributions in binary form must reproduce the above copyright
27 **     notice, this list of conditions and the following disclaimer in
28 **     the documentation and/or other materials provided with the
29 **     distribution.
30 **   * Neither the name of The Qt Company Ltd nor the names of its
31 **     contributors may be used to endorse or promote products derived
32 **     from this software without specific prior written permission.
33 **
34 **
35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46 **
47 ** $QT_END_LICENSE$
48 **
49 ****************************************************************************/
50 
51 
52 //! [0]
QAccessibleSlider(QWidget * w)53 QAccessibleSlider::QAccessibleSlider(QWidget *w)
54 : QAccessibleAbstractSlider(w)
55 {
56     Q_ASSERT(slider());
57     addControllingSignal(QLatin1String("valueChanged(int)"));
58 }
59 //! [0]
60 
slider() const61 QSlider *QAccessibleSlider::slider() const
62 {
63     return qobject_cast<QSlider*>(object());
64 }
65 
66 //! [1]
rect(int child) const67 QRect QAccessibleSlider::rect(int child) const
68 {
69 //! [1]
70     QRect rect;
71     if (!slider()->isVisible())
72         return rect;
73     const QStyleOptionSlider option = qt_qsliderStyleOption(slider());
74     QRect srect = slider()->style()->subControlRect(QStyle::CC_Slider, &option,
75                                                     QStyle::SC_SliderHandle, slider());
76 
77 //! [2]
78     switch (child) {
79     case PageLeft:
80         if (slider()->orientation() == Qt::Vertical)
81             rect = QRect(0, 0, slider()->width(), srect.y());
82         else
83             rect = QRect(0, 0, srect.x(), slider()->height());
84         break;
85     case Position:
86         rect = srect;
87         break;
88     case PageRight:
89         if (slider()->orientation() == Qt::Vertical)
90             rect = QRect(0, srect.y() + srect.height(), slider()->width(), slider()->height()- srect.y() - srect.height());
91         else
92             rect = QRect(srect.x() + srect.width(), 0, slider()->width() - srect.x() - srect.width(), slider()->height());
93         break;
94     default:
95         return QAccessibleAbstractSlider::rect(child);
96     }
97 //! [2] //! [3]
98 
99     QPoint tp = slider()->mapToGlobal(QPoint(0,0));
100     return QRect(tp.x() + rect.x(), tp.y() + rect.y(), rect.width(), rect.height());
101 }
102 //! [3]
103 
childCount() const104 int QAccessibleSlider::childCount() const
105 {
106     if (!slider()->isVisible())
107         return 0;
108     return PageRight;
109 }
110 
111 //! [4]
text(Text t,int child) const112 QString QAccessibleSlider::text(Text t, int child) const
113 {
114     if (!slider()->isVisible())
115         return QString();
116     switch (t) {
117     case Value:
118         if (!child || child == 2)
119             return QString::number(slider()->value());
120         return QString();
121     case Name:
122         switch (child) {
123         case PageLeft:
124             return slider()->orientation() == Qt::Horizontal ?
125                 QSlider::tr("Page left") : QSlider::tr("Page up");
126         case Position:
127             return QSlider::tr("Position");
128         case PageRight:
129             return slider()->orientation() == Qt::Horizontal ?
130                 QSlider::tr("Page right") : QSlider::tr("Page down");
131         }
132         break;
133     default:
134         break;
135     }
136     return QAccessibleAbstractSlider::text(t, child);
137 }
138 //! [4]
139 
140 //! [5]
role(int child) const141 QAccessible::Role QAccessibleSlider::role(int child) const
142 {
143     switch (child) {
144     case PageLeft:
145     case PageRight:
146         return PushButton;
147     case Position:
148         return Indicator;
149     default:
150         return Slider;
151     }
152 }
153 //! [5]
154 
155 //! [6]
state(int child) const156 QAccessible::State QAccessibleSlider::state(int child) const
157 {
158     const State parentState = QAccessibleAbstractSlider::state(0);
159 //! [6]
160 
161     if (child == 0)
162         return parentState;
163 
164     // Inherit the Invisible state from parent.
165     State state = parentState & QAccessible::Invisible;
166 
167     // Disable left/right if we are at the minimum/maximum.
168     const QSlider * const slider = QAccessibleSlider::slider();
169 //! [7]
170     switch (child) {
171     case PageLeft:
172         if (slider->value() <= slider->minimum())
173             state |= Unavailable;
174         break;
175     case PageRight:
176         if (slider->value() >= slider->maximum())
177             state |= Unavailable;
178         break;
179     case Position:
180     default:
181         break;
182     }
183 
184     return state;
185 }
186 //! [7]
187 
defaultAction(int child) const188 int QAccessibleSlider::defaultAction(int child) const
189 {
190     switch (child) {
191         case SliderSelf:
192             return SetFocus;
193         case PageLeft:
194             return Press;
195         case PageRight:
196             return Press;
197     }
198 
199     return 0;
200 }
201 
202 // Name, Description, Value, Help, Accelerator
203 static const char * const actionTexts[][5] =
204 {
205     {"Press", "Decreases the value of the slider", "", "", "Ctrl+L"},
206     {"Press", "Increaces the value of the slider", "", "", "Ctrl+R"}
207 };
208 
actionText(int action,Text text,int child) const209 QString QAccessibleSlider::actionText(int action, Text text, int child) const
210 {
211     if (action != Press || child < 1 || child > 2)
212         return QAccessibleAbstractSlider::actionText(action, text, child);
213 
214     return actionTexts[child - 1][t];
215 }
216 
doAction(int action,int child)217 bool QAccessibleSlider::doAction(int action, int child)
218 {
219     if (action != Press || child < 1 || child > 2)
220         return false;
221 
222     if (child == PageLeft)
223         slider()->setValue(slider()->value() - slider()->pageStep());
224     else
225         slider()->setValue(slider()->value() + slider()->pageStep());
226 }
227 
QAccessibleAbstractSlider(QWidget * w,Role r)228 QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, Role r)
229     : QAccessibleWidgetEx(w, r)
230 {
231     Q_ASSERT(qobject_cast<QAbstractSlider *>(w));
232 }
233 
invokeMethodEx(Method method,int child,const QVariantList & params)234 QVariant QAccessibleAbstractSlider::invokeMethodEx(Method method, int child, const QVariantList &params)
235 {
236     switch (method) {
237     case ListSupportedMethods: {
238         QSet<QAccessible::Method> set;
239         set << ListSupportedMethods;
240         return qVariantFromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
241                     QAccessibleWidgetEx::invokeMethodEx(method, child, params)));
242     }
243     default:
244         return QAccessibleWidgetEx::invokeMethodEx(method, child, params);
245     }
246 }
247 
currentValue()248 QVariant QAccessibleAbstractSlider::currentValue()
249 {
250     return abstractSlider()->value();
251 }
252 
setCurrentValue(const QVariant & value)253 void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value)
254 {
255     abstractSlider()->setValue(value.toInt());
256 }
257 
maximumValue()258 QVariant QAccessibleAbstractSlider::maximumValue()
259 {
260     return abstractSlider()->maximum();
261 }
262 
minimumValue()263 QVariant QAccessibleAbstractSlider::minimumValue()
264 {
265     return abstractSlider()->minimum();
266 }
267 
abstractSlider() const268 QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const
269 {
270     return static_cast<QAbstractSlider *>(object());
271 }
272