css::uno::Reference< css::accessibility::XAccessible > Window::GetAccessible( bool bCreate )
{ // do not optimize hierarchy for the top level border win (ie, when there is no parent) /* // do not optimize accessible hierarchy at all to better reflect real VCL hierarchy if(GetParent()&&(GetType()==WindowType::BORDERWINDOW)&&(GetChildCount()==1)) //if( !ImplIsAccessibleCandidate() ) { vcl::Window*pChild=GetAccessibleChildWindow(0); if(pChild) returnpChild->GetAccessible(); }
*/ if ( !mpWindowImpl ) return css::uno::Reference< css::accessibility::XAccessible >(); if (!mpWindowImpl->mxAccessible.is() && !mpWindowImpl->mbInDispose && bCreate)
mpWindowImpl->mxAccessible = CreateAccessible();
void Window::SetAccessible( const css::uno::Reference< css::accessibility::XAccessible >& x )
{ if (!mpWindowImpl) return;
mpWindowImpl->mxAccessible = x;
}
// skip all border windows that are not top level frames bool Window::ImplIsAccessibleCandidate() const
{ if( !mpWindowImpl->mbBorderWin ) returntrue;
return IsNativeFrame();
}
vcl::Window* Window::GetAccessibleParentWindow() const
{ if (!mpWindowImpl || IsNativeFrame()) return nullptr;
if (IsTopWindow())
{ // if "top-level" has native border window parent, report it; // but don't report parent otherwise (which could e.g. be // a dialog's parent window that's otherwise a separate window and // doesn't consider the top level its a11y child either) if (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->IsNativeFrame()) return mpWindowImpl->mpBorderWindow; return nullptr;
}
vcl::Window* pParent = mpWindowImpl->mpParent; if( GetType() == WindowType::MENUBARWINDOW )
{ // report the menubar as a child of THE workwindow
vcl::Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild; while( pWorkWin && (pWorkWin == this) )
pWorkWin = pWorkWin->mpWindowImpl->mpNext;
pParent = pWorkWin;
} // If this is a floating window which has a native border window, then that border should be reported as // the accessible parent elseif( GetType() == WindowType::FLOATINGWINDOW &&
mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame )
{
pParent = mpWindowImpl->mpBorderWindow;
} elseif( pParent && !pParent->ImplIsAccessibleCandidate() )
{
pParent = pParent->mpWindowImpl->mpParent;
} return pParent;
}
sal_uInt16 Window::GetAccessibleChildWindowCount()
{ if (!mpWindowImpl) return0;
sal_uInt16 Window::getDefaultAccessibleRole() const
{
sal_uInt16 nRole = accessibility::AccessibleRole::UNKNOWN; switch (GetType())
{ case WindowType::MESSBOX: case WindowType::INFOBOX: case WindowType::WARNINGBOX: case WindowType::ERRORBOX: case WindowType::QUERYBOX:
nRole = accessibility::AccessibleRole::ALERT; break;
case WindowType::MODELESSDIALOG: case WindowType::TABDIALOG: case WindowType::BUTTONDIALOG: case WindowType::DIALOG:
nRole = accessibility::AccessibleRole::DIALOG; break;
case WindowType::PUSHBUTTON: case WindowType::OKBUTTON: case WindowType::CANCELBUTTON: case WindowType::HELPBUTTON: case WindowType::IMAGEBUTTON: case WindowType::MOREBUTTON:
nRole = accessibility::AccessibleRole::PUSH_BUTTON; break; case WindowType::MENUBUTTON:
nRole = accessibility::AccessibleRole::BUTTON_MENU; break;
case WindowType::RADIOBUTTON:
nRole = accessibility::AccessibleRole::RADIO_BUTTON; break; case WindowType::TRISTATEBOX: case WindowType::CHECKBOX:
nRole = accessibility::AccessibleRole::CHECK_BOX; break;
case WindowType::MULTILINEEDIT:
nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
case WindowType::PATTERNFIELD: case WindowType::EDIT:
nRole = static_cast<Edit const*>(this)->IsPassword()
? accessibility::AccessibleRole::PASSWORD_TEXT
: accessibility::AccessibleRole::TEXT; break;
case WindowType::PATTERNBOX: case WindowType::NUMERICBOX: case WindowType::METRICBOX: case WindowType::CURRENCYBOX: case WindowType::LONGCURRENCYBOX: case WindowType::COMBOBOX:
nRole = accessibility::AccessibleRole::COMBO_BOX; break;
case WindowType::LISTBOX: case WindowType::MULTILISTBOX:
nRole = accessibility::AccessibleRole::LIST; break;
case WindowType::TREELISTBOX:
nRole = accessibility::AccessibleRole::TREE; break;
case WindowType::FIXEDTEXT:
nRole = accessibility::AccessibleRole::LABEL; break; case WindowType::FIXEDLINE: if (!GetText().isEmpty())
nRole = accessibility::AccessibleRole::LABEL; else
nRole = accessibility::AccessibleRole::SEPARATOR; break;
case WindowType::FIXEDBITMAP: case WindowType::FIXEDIMAGE:
nRole = accessibility::AccessibleRole::ICON; break; case WindowType::GROUPBOX:
nRole = accessibility::AccessibleRole::GROUP_BOX; break; case WindowType::SCROLLBAR:
nRole = accessibility::AccessibleRole::SCROLL_BAR; break;
case WindowType::SLIDER: case WindowType::SPLITTER: case WindowType::SPLITWINDOW:
nRole = accessibility::AccessibleRole::SPLIT_PANE; break;
case WindowType::DATEBOX: case WindowType::TIMEBOX: case WindowType::DATEFIELD: case WindowType::TIMEFIELD:
nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
case WindowType::METRICFIELD: case WindowType::CURRENCYFIELD: case WindowType::SPINBUTTON: case WindowType::SPINFIELD: case WindowType::FORMATTEDFIELD:
nRole = accessibility::AccessibleRole::SPIN_BOX; break;
case WindowType::TOOLBOX:
nRole = accessibility::AccessibleRole::TOOL_BAR; break; case WindowType::STATUSBAR:
nRole = accessibility::AccessibleRole::STATUS_BAR; break;
case WindowType::TABPAGE:
nRole = accessibility::AccessibleRole::PANEL; break; case WindowType::TABCONTROL:
nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break;
case WindowType::DOCKINGWINDOW:
nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME
: accessibility::AccessibleRole::PANEL; break;
case WindowType::WORKWINDOW:
nRole = accessibility::AccessibleRole::ROOT_PANE; break;
case WindowType::SCROLLBARBOX:
nRole = accessibility::AccessibleRole::FILLER; break;
case WindowType::HELPTEXTWINDOW:
nRole = accessibility::AccessibleRole::TOOL_TIP; break;
case WindowType::PROGRESSBAR:
nRole = accessibility::AccessibleRole::PROGRESS_BAR; break;
case WindowType::RULER:
nRole = accessibility::AccessibleRole::RULER; break;
case WindowType::SCROLLWINDOW:
nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
case WindowType::WINDOW: case WindowType::CONTROL: case WindowType::BORDERWINDOW: case WindowType::SYSTEMCHILDWINDOW: default: if (IsNativeFrame())
nRole = accessibility::AccessibleRole::FRAME; elseif (IsScrollable())
nRole = accessibility::AccessibleRole::SCROLL_PANE; elseif (this->ImplGetWindow()->IsMenuFloatingWindow()) // #106002#, contextmenus are windows (i.e. toplevel)
nRole = accessibility::AccessibleRole::WINDOW; else // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead // a WINDOW is interpreted as a top-level window, which is typically not the case //nRole = accessibility::AccessibleRole::WINDOW;
nRole = accessibility::AccessibleRole::PANEL;
} return nRole;
}
sal_uInt16 Window::GetAccessibleRole() const
{ if (!mpWindowImpl) return accessibility::AccessibleRole::UNKNOWN;
OUString Window::GetAccessibleName() const
{ if (!mpWindowImpl) return OUString();
if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName) return *mpWindowImpl->mpAccessibleInfos->pAccessibleName; return getDefaultAccessibleName();
}
OUString Window::getDefaultAccessibleName() const
{
OUString aAccessibleName; switch ( GetType() )
{ case WindowType::MULTILINEEDIT: case WindowType::PATTERNFIELD: case WindowType::METRICFIELD: case WindowType::CURRENCYFIELD: case WindowType::EDIT:
case WindowType::DATEBOX: case WindowType::TIMEBOX: case WindowType::CURRENCYBOX: case WindowType::LONGCURRENCYBOX: case WindowType::DATEFIELD: case WindowType::TIMEFIELD: case WindowType::SPINFIELD: case WindowType::FORMATTEDFIELD:
case WindowType::COMBOBOX: case WindowType::LISTBOX: case WindowType::MULTILISTBOX: case WindowType::TREELISTBOX: case WindowType::METRICBOX:
{
vcl::Window *pLabel = GetAccessibleRelationLabeledBy(); if ( pLabel && pLabel != this )
aAccessibleName = pLabel->GetText(); if (aAccessibleName.isEmpty())
aAccessibleName = GetQuickHelpText(); if (aAccessibleName.isEmpty())
aAccessibleName = GetText();
} break;
case WindowType::IMAGEBUTTON: case WindowType::PUSHBUTTON:
aAccessibleName = GetText(); if (aAccessibleName.isEmpty())
{
aAccessibleName = GetQuickHelpText(); if (aAccessibleName.isEmpty())
aAccessibleName = GetHelpText();
} break;
case WindowType::TOOLBOX:
aAccessibleName = GetText(); break;
case WindowType::MOREBUTTON:
aAccessibleName = mpWindowImpl->maText; break;
OUString Window::GetAccessibleDescription() const
{ if (!mpWindowImpl) return OUString();
OUString aAccessibleDescription; if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription )
{
aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
} else
{ // Special code for help text windows. ZT asks the border window for the // description so we have to forward this request to our inner window. const vcl::Window* pWin = this->ImplGetWindow(); if ( pWin->GetType() == WindowType::HELPTEXTWINDOW )
aAccessibleDescription = pWin->GetHelpText(); else
aAccessibleDescription = GetHelpText();
}
return aAccessibleDescription;
}
void Window::SetAccessibleRelationLabeledBy( vcl::Window* pLabeledBy )
{ if ( !mpWindowImpl->mpAccessibleInfos )
mpWindowImpl->mpAccessibleInfos.reset( new ImplAccessibleInfos );
mpWindowImpl->mpAccessibleInfos->pLabeledByWindow = pLabeledBy;
}
void Window::SetAccessibleRelationLabelFor( vcl::Window* pLabelFor )
{ if ( !mpWindowImpl->mpAccessibleInfos )
mpWindowImpl->mpAccessibleInfos.reset( new ImplAccessibleInfos );
mpWindowImpl->mpAccessibleInfos->pLabelForWindow = pLabelFor;
}
vcl::Window* Window::GetAccessibleRelationMemberOf() const
{ if (!isContainerWindow(this) && !isContainerWindow(GetParent())) return getLegacyNonLayoutAccessibleRelationMemberOf();
return nullptr;
}
vcl::Window* Window::getAccessibleRelationLabelFor() const
{ if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow) return mpWindowImpl->mpAccessibleInfos->pLabelForWindow;
// Avoid searching when using LOKit (jsdialog) - it can slow down dumping to json when we have a huge hierarchy if (!comphelper::LibreOfficeKit::isActive() && !isContainerWindow(this) && !isContainerWindow(GetParent())) return getLegacyNonLayoutAccessibleRelationLabelFor();
return nullptr;
}
vcl::Window* Window::GetAccessibleRelationLabeledBy() const
{ if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow) return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow;
autoconst& aMnemonicLabels = list_mnemonic_labels(); if (!aMnemonicLabels.empty())
{ //if we have multiple labels, then prefer the first that is visible for (autoconst & rCandidate : aMnemonicLabels)
{ if (rCandidate->IsVisible()) return rCandidate;
} return aMnemonicLabels[0];
}
// Avoid searching when using LOKit (jsdialog) - it can slow down dumping to json when we have a huge hierarchy if (!comphelper::LibreOfficeKit::isActive() && !isContainerWindow(this) && !isContainerWindow(GetParent())) return getLegacyNonLayoutAccessibleRelationLabeledBy();
return nullptr;
}
bool Window::IsAccessibilityEventsSuppressed()
{
vcl::Window *pParent = this; while (pParent && pParent->mpWindowImpl)
{ if (pParent->mpWindowImpl->mbSuppressAccessibilityEvents) returntrue; else
pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames
} returnfalse;
}
} /* namespace vcl */
uno::Reference<accessibility::XAccessibleEditableText>
FindFocusedEditableText(uno::Reference<accessibility::XAccessibleContext> const& xContext)
{ if (!xContext.is()) return uno::Reference<accessibility::XAccessibleEditableText>();
sal_Int64 nState = xContext->getAccessibleStateSet(); if (nState & accessibility::AccessibleStateType::FOCUSED)
{
uno::Reference<accessibility::XAccessibleEditableText> xText(xContext, uno::UNO_QUERY); if (xText.is()) return xText; if (nState & accessibility::AccessibleStateType::MANAGES_DESCENDANTS) return uno::Reference<accessibility::XAccessibleEditableText>();
}
bool bSafeToIterate = true;
sal_Int64 nCount = xContext->getAccessibleChildCount(); if (nCount < 0 || nCount > SAL_MAX_UINT16 /* slow enough for anyone */)
bSafeToIterate = false; if (!bSafeToIterate) return uno::Reference<accessibility::XAccessibleEditableText>();
for (sal_Int64 i = 0; i < xContext->getAccessibleChildCount(); ++i)
{
uno::Reference<accessibility::XAccessible> xChild = xContext->getAccessibleChild(i); if (!xChild.is()) continue;
uno::Reference<accessibility::XAccessibleContext> xChildContext
= xChild->getAccessibleContext(); if (!xChildContext.is()) continue;
uno::Reference<accessibility::XAccessibleEditableText> xText
= FindFocusedEditableText(xChildContext); if (xText.is()) return xText;
} return uno::Reference<accessibility::XAccessibleEditableText>();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.