Warning, file /libraries/libqaccessibilityclient/examples/accessibleapps/accessibleproperties.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2012 Sebastian Sauer <sebastian.sauer@kdab.com> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "accessibleproperties.h" 0008 0009 #include "qaccessibilityclient/registry.h" 0010 0011 using namespace QAccessibleClient; 0012 0013 ObjectProperties::ObjectProperties(QObject *parent) 0014 : QStandardItemModel(parent) 0015 { 0016 setColumnCount(2); 0017 setHorizontalHeaderLabels( QStringList() << QStringLiteral("Property") << QStringLiteral("Value") ); 0018 0019 connect(this, SIGNAL(itemChanged(QStandardItem *)), this, SLOT(slotDataChanged(QStandardItem *))); 0020 } 0021 0022 ObjectProperties::~ObjectProperties() 0023 { 0024 } 0025 0026 void ObjectProperties::slotDataChanged(QStandardItem *item) { 0027 if (item == m_textItem) { 0028 QString newText = item->data(Qt::EditRole).toString(); 0029 m_acc.setText(newText); 0030 } else if (item == m_valueItem) { 0031 bool couldConvert; 0032 double value = item->data(Qt::EditRole).toDouble(&couldConvert); 0033 if (couldConvert) { 0034 m_acc.setCurrentValue(value); 0035 } 0036 0037 m_valueItem = nullptr; //Prevent recursion 0038 item->setData(m_acc.currentValue(), Qt::DisplayRole); 0039 m_valueItem = item; 0040 } 0041 } 0042 0043 QVariant ObjectProperties::headerData(int section, Qt::Orientation orientation, int role) const 0044 { 0045 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { 0046 if (section == 0) { 0047 return QStringLiteral("Property"); 0048 } 0049 if (section == 1) { 0050 return QStringLiteral("Value"); 0051 } 0052 } 0053 return QVariant(); 0054 } 0055 0056 QHash<int,QByteArray> ObjectProperties::roleNames() const 0057 { 0058 QHash<int, QByteArray> roles; 0059 roles[NameRole] = "name"; 0060 roles[ValueRole] = "value"; 0061 return roles; 0062 } 0063 0064 void ObjectProperties::setAccessibleObject(const QAccessibleClient::AccessibleObject &acc) 0065 { 0066 beginResetModel(); 0067 m_acc = acc; 0068 m_textItem = nullptr; 0069 m_valueItem = nullptr; 0070 0071 clear(); 0072 0073 if (!acc.isValid()) { 0074 endResetModel(); 0075 return; 0076 } 0077 0078 QAccessibleClient::AccessibleObject::Interfaces interfaces = acc.supportedInterfaces(); 0079 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::AccessibleInterface)) { 0080 QStandardItem *item = append(QStringLiteral("Accessible")); 0081 append(QStringLiteral("Name"), acc.name(), item); 0082 append(QStringLiteral("Description"), acc.description(), item); 0083 append(QStringLiteral("Role"), acc.roleName(), item); 0084 append(QStringLiteral("LocalizedRole"), acc.localizedRoleName(), item); 0085 append(QStringLiteral("Visible"), acc.isVisible(), item); 0086 append(QStringLiteral("Default"), acc.isDefault(), item); 0087 append(QStringLiteral("State"), acc.stateString(), item); 0088 append(QStringLiteral("AccessibleId"), acc.accessibleId(), item); 0089 append(tr("Url"), acc.url(), item); 0090 AccessibleObject parent = acc.parent(); 0091 if (parent.isValid()) 0092 append(tr("Parent"), parent.url(), item); 0093 int childCount = acc.childCount(); 0094 QStandardItem *children = append(QStringLiteral("Children"), acc.childCount(), item); 0095 for (int i = 0; i < childCount; ++i) { 0096 AccessibleObject child = acc.child(i); 0097 if (!child.isValid()) { 0098 append(QLatin1String("Broken child"), QString::number(i), children); 0099 } else { 0100 append(child.name().isEmpty() ? tr("[%1]").arg(child.roleName()) : child.name(), child.url(), children); 0101 } 0102 } 0103 //GetAttributes 0104 } 0105 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::ComponentInterface)) { 0106 QStandardItem *item = append(QStringLiteral("Component")); 0107 append(QStringLiteral("BoundingRect"), acc.boundingRect(), item); 0108 append(QStringLiteral("Layer"), acc.layer(), item); 0109 append(QStringLiteral("MDIZOrder"), acc.mdiZOrder(), item); 0110 append(QStringLiteral("Alpha"), acc.alpha(), item); 0111 } 0112 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::CollectionInterface)) { 0113 QStandardItem *item = append(QStringLiteral("Collection")); 0114 Q_UNUSED(item); 0115 } 0116 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::ApplicationInterface)) { 0117 QStandardItem *item = append(QStringLiteral("Application")); 0118 append(QStringLiteral("ToolkitName"), acc.appToolkitName(), item); 0119 append(QStringLiteral("Version"), acc.appVersion(), item); 0120 append(QStringLiteral("Id"), acc.appId(), item); 0121 append(QStringLiteral("Locale"), acc.appLocale(), item); 0122 append(QStringLiteral("BusAddress"), acc.appBusAddress(), item); 0123 } 0124 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::DocumentInterface)) { 0125 QStandardItem *item = append(QStringLiteral("Document")); 0126 Q_UNUSED(item); 0127 //GetLocale 0128 //GetAttributeValue 0129 //GetAttributes 0130 } 0131 0132 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::EditableTextInterface)) { 0133 QStandardItem *item = append(QStringLiteral("EditableText")); 0134 Q_UNUSED(item); 0135 } 0136 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::HyperlinkInterface)) { 0137 QStandardItem *item = append(QStringLiteral("Hyperlink")); 0138 Q_UNUSED(item); 0139 /* 0140 <property name="NAnchors" type="n" access="read"/> 0141 <property name="StartIndex" type="i" access="read"/> 0142 <property name="EndIndex" type="i" access="read"/> 0143 <method name="GetObject"> 0144 <arg direction="in" name="i" type="i"/> 0145 <arg direction="out" type="(so)"/> 0146 <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QSpiObjectReference"/> 0147 </method> 0148 0<method name="GetURI"> 0149 <arg direction="in" name="i" type="i"/> 0150 <arg direction="out" type="s"/> 0151 </method> 0152 <method name="IsValid"> 0153 <arg direction="out" type="b"/> 0154 </method> 0155 */ 0156 } 0157 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::HypertextInterface)) { 0158 QStandardItem *item = append(QStringLiteral("Hypertext")); 0159 Q_UNUSED(item); 0160 /* 0161 <method name="GetNLinks"> 0162 <arg direction="out" type="i"/> 0163 </method> 0164 <method name="GetLink"> 0165 <arg direction="in" name="linkIndex" type="i"/> 0166 <arg direction="out" type="(so)"/> 0167 <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QSpiObjectReference"/> 0168 </method> 0169 <method name="GetLinkIndex"> 0170 <arg direction="in" name="characterIndex" type="i"/> 0171 <arg direction="out" type="i"/> 0172 </method> 0173 */ 0174 } 0175 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::ImageInterface)) { 0176 QStandardItem *item = append(QStringLiteral("Image")); 0177 append(QStringLiteral("Description"), acc.imageDescription(), item); 0178 append(QStringLiteral("Locale"), acc.imageLocale(), item); 0179 append(QStringLiteral("Rect"), acc.imageRect(), item); 0180 } 0181 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::SelectionInterface)) { 0182 QStandardItem *item = append(QStringLiteral("Selection")); 0183 for (const QAccessibleClient::AccessibleObject &s : acc.selection()) { 0184 append(s.name(), s.role(), item); 0185 } 0186 } 0187 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::TableInterface)) { 0188 QStandardItem *item = append(QStringLiteral("Table")); 0189 Q_UNUSED(item); 0190 /* 0191 <property name="NRows" type="i" access="read"/> 0192 <property name="NColumns" type="i" access="read"/> 0193 <property name="Caption" type="(so)" access="read"> 0194 <annotation name="com.trolltech.QtDBus.QtTypeName" value="QSpiObjectReference"/> 0195 </property> 0196 <property name="Summary" type="(so)" access="read"> 0197 <annotation name="com.trolltech.QtDBus.QtTypeName" value="QSpiObjectReference"/> 0198 </property> 0199 <property name="NSelectedRows" type="i" access="read"/> 0200 <property name="NSelectedColumns" type="i" access="read"/> 0201 <method name="GetRowDescription"> 0202 <arg direction="in" name="row" type="i"/> 0203 <arg direction="out" type="s"/> 0204 </method> 0205 <method name="GetColumnDescription"> 0206 <arg direction="in" name="column" type="i"/> 0207 <arg direction="out" type="s"/> 0208 </method> 0209 <method name="GetSelectedRows"> 0210 <arg direction="out" type="ai"/> 0211 <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QSpiIntList"/> 0212 </method> 0213 <method name="GetSelectedColumns"> 0214 <arg direction="out" type="ai"/> 0215 <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QSpiIntList"/> 0216 </method> 0217 */ 0218 } 0219 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::TextInterface)) { 0220 QStandardItem *item = append(QStringLiteral("Text")); 0221 int offset = acc.caretOffset(); 0222 append(QStringLiteral("CaretOffset"), offset, item); 0223 append(QStringLiteral("CharacterCount"), acc.characterCount(), item); 0224 append(QStringLiteral("CharacterRect"), acc.characterRect(offset), item); 0225 0226 QString text = acc.text(); 0227 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::EditableTextInterface)) { 0228 append(QStringLiteral("Text"), text, item, &m_textItem); 0229 } else { 0230 append(QStringLiteral("Text"), text, item); 0231 } 0232 0233 QList< QPair<int,int> > selections = acc.textSelections(); 0234 QStandardItem *selectionsItem = append(QStringLiteral("Selections"), selections.count(), item); 0235 for (int i = 0; i < selections.count(); ++i) { 0236 QPair<int,int> sel = selections[i]; 0237 int startOffset = sel.first; 0238 int endOffset = sel.second; 0239 Q_ASSERT(startOffset <= endOffset); 0240 append( QStringLiteral("%1:%2").arg(startOffset).arg(endOffset), 0241 text.mid(startOffset, endOffset - startOffset), 0242 selectionsItem ); 0243 } 0244 } 0245 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::ValueInterface)) { 0246 QStandardItem *item = append(QStringLiteral("Value")); 0247 append(QStringLiteral("Current"), acc.currentValue(), item, &m_valueItem); 0248 append(QStringLiteral("Minimum"), acc.minimumValue(), item); 0249 append(QStringLiteral("Maximum"), acc.maximumValue(), item); 0250 append(QStringLiteral("Increment"), acc.minimumValueIncrement(), item); 0251 } 0252 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::SocketInterface)) { 0253 QStandardItem *item = append(QStringLiteral("Socket")); 0254 Q_UNUSED(item); 0255 } 0256 0257 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::EventKeyboardInterface)) { 0258 QStandardItem *item = append(QStringLiteral("EventKeyboard")); 0259 Q_UNUSED(item); 0260 } 0261 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::EventMouseInterface)) { 0262 QStandardItem *item = append(QStringLiteral("EventMouse")); 0263 Q_UNUSED(item); 0264 } 0265 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::EventObjectInterface)) { 0266 QStandardItem *item = append(QStringLiteral("EventObject")); 0267 Q_UNUSED(item); 0268 } 0269 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::EventWindowInterface)) { 0270 QStandardItem *item = append(QStringLiteral("EventWindow")); 0271 Q_UNUSED(item); 0272 } 0273 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::EventFocusInterface)) { 0274 QStandardItem *item = append(QStringLiteral("EventFocus")); 0275 Q_UNUSED(item); 0276 } 0277 0278 if (interfaces.testFlag(QAccessibleClient::AccessibleObject::ActionInterface)) { 0279 QStandardItem *item = append(QStringLiteral("Action")); 0280 for (const QSharedPointer<QAction> &a : acc.actions()) { 0281 QStandardItem *nameItem = new QStandardItem(a->text()); 0282 QStandardItem *valueItem = new QStandardItem(a->whatsThis()); 0283 nameItem->setEditable(false); 0284 valueItem->setEditable(false); 0285 item->appendRow(QList<QStandardItem*>() << nameItem << valueItem); 0286 } 0287 } 0288 0289 endResetModel(); 0290 } 0291 0292 void ObjectProperties::doubleClicked(const QModelIndex &index) 0293 { 0294 if (!index.isValid() || !index.parent().isValid() || index.parent().data().toString() != QLatin1String("Action")) 0295 return; 0296 0297 const auto actions{m_acc.actions()}; 0298 for (const QSharedPointer<QAction> &action : actions) { 0299 if (action->text() == data(index).toString()) { 0300 action->trigger(); 0301 return; 0302 } 0303 } 0304 } 0305 0306 QStandardItem* ObjectProperties::append(const QString &name, const QVariant &value, QStandardItem *parentItem, QStandardItem **changeHandler) 0307 { 0308 if (!parentItem) 0309 parentItem = invisibleRootItem(); 0310 QStandardItem *nameItem = new QStandardItem(name); 0311 QString text; 0312 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0313 switch (value.metaType().id()) { 0314 #else 0315 switch (value.type()) { 0316 #endif 0317 case QMetaType::QPoint: { 0318 QPoint p = value.toPoint(); 0319 text = QStringLiteral("%1:%2").arg(p.x()).arg(p.y()); 0320 } break; 0321 case QMetaType::QPointF: { 0322 QPointF p = value.toPointF(); 0323 text = QStringLiteral("%1:%2").arg(p.x()).arg(p.y()); 0324 } break; 0325 case QMetaType::QRect: { 0326 QRect r = value.toRect(); 0327 text = QStringLiteral("%1:%2 %3x%4").arg(r.left()).arg(r.top()).arg(r.width()).arg(r.height()); 0328 } break; 0329 case QMetaType::QRectF: { 0330 QRectF r = value.toRectF(); 0331 text = QStringLiteral("%1:%2 %3x%4").arg(r.left()).arg(r.top()).arg(r.width()).arg(r.height()); 0332 } break; 0333 default: 0334 text = value.toString(); 0335 break; 0336 } 0337 QStandardItem *valueItem = new QStandardItem(text); 0338 parentItem->appendRow(QList<QStandardItem*>() << nameItem << valueItem); 0339 nameItem->setEditable(false); 0340 0341 if (changeHandler) { 0342 *changeHandler = valueItem; 0343 valueItem->setEditable(true); 0344 } else { 0345 valueItem->setEditable(false); 0346 } 0347 0348 return nameItem; 0349 } 0350 0351 #include "moc_accessibleproperties.cpp"