feat:set control accessible

This commit is contained in:
fanpengcheng_cm 2020-03-13 12:59:02 +08:00
parent 0889159f74
commit 684ed7cf0b
38 changed files with 825 additions and 56 deletions

View File

@ -33,6 +33,7 @@ target_include_directories(${BIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
${DtkGUI_INCLUDE_DIRS}
${Qt5Svg_INCLUDE_DIRS}
../interfaces)
target_link_libraries(${BIN_NAME} PRIVATE
${XCB_EWMH_LIBRARIES}
${DFrameworkDBus_LIBRARIES}

View File

@ -279,7 +279,10 @@ void DockItemManager::pluginItemInserted(PluginsItem *item)
m_itemList.insert(insertIndex, item);
if(pluginType == DockItem::FixedPlugin)
{
insertIndex ++;
item->setAccessibleName("plugins");
}
emit itemInserted(insertIndex - firstPluginPosition, item);
}

View File

@ -181,6 +181,11 @@ void AppItem::setDockInfo(Dock::Position dockPosition, const QRect &dockGeometry
}
}
QString AppItem::accessibleName()
{
return m_itemEntryInter->name();
}
void AppItem::moveEvent(QMoveEvent *e)
{
DockItem::moveEvent(e);
@ -342,8 +347,8 @@ void AppItem::mouseMoveEvent(QMouseEvent *e)
e->accept();
// handle preview
// if (e->buttons() == Qt::NoButton)
// return showPreview();
// if (e->buttons() == Qt::NoButton)
// return showPreview();
// handle drag
if (e->buttons() != Qt::LeftButton)
@ -641,7 +646,7 @@ void AppItem::playSwingEffect()
stopSwingEffect();
QPair<QGraphicsView *, QGraphicsItemAnimation *> pair = SwingEffect(
this, m_appIcon, rect(), devicePixelRatioF());
this, m_appIcon, rect(), devicePixelRatioF());
m_swingEffectView = pair.first;
m_itemAnimation = pair.second;
@ -688,8 +693,8 @@ void AppItem::onGSettingsChanged(const QString &key)
}
QGSettings *setting = m_itemEntryInter->isDocked()
? GSettingsByDockApp()
: GSettingsByActiveApp();
? GSettingsByDockApp()
: GSettingsByActiveApp();
if (setting->keys().contains("enable")) {
const bool isEnable = GSettingsByApp()->keys().contains("enable") && GSettingsByApp()->get("enable").toBool();
@ -700,11 +705,11 @@ void AppItem::onGSettingsChanged(const QString &key)
bool AppItem::checkGSettingsControl() const
{
QGSettings *setting = m_itemEntryInter->isDocked()
? GSettingsByDockApp()
: GSettingsByActiveApp();
? GSettingsByDockApp()
: GSettingsByActiveApp();
return (setting->keys().contains("control") && setting->get("control").toBool()) ||
(GSettingsByApp()->keys().contains("control") && GSettingsByApp()->get("control").toBool());
(GSettingsByApp()->keys().contains("control") && GSettingsByApp()->get("control").toBool());
}
void AppItem::onThemeTypeChanged(DGuiApplicationHelper::ColorType themeType)

View File

@ -55,6 +55,7 @@ public:
inline ItemType itemType() const Q_DECL_OVERRIDE { return App; }
QPixmap appIcon(){ return m_appIcon; }
virtual QString accessibleName();
signals:
void requestActivateWindow(const WId wid) const;
@ -80,7 +81,6 @@ private:
void invokedMenuItem(const QString &itemId, const bool checked) Q_DECL_OVERRIDE;
const QString contextMenu() const Q_DECL_OVERRIDE;
QWidget *popupTips() Q_DECL_OVERRIDE;
void startDrag();
bool hasAttention() const;

View File

@ -60,11 +60,13 @@ AppSnapshot::AppSnapshot(const WId wid, QWidget *parent)
, m_wmHelper(DWindowManagerHelper::instance())
{
m_closeBtn2D->setFixedSize(24, 24);
m_closeBtn2D->setAccessibleName("closebutton-2d");
m_closeBtn2D->setNormalPic(":/icons/resources/close_round_normal.svg");
m_closeBtn2D->setHoverPic(":/icons/resources/close_round_hover.svg");
m_closeBtn2D->setPressPic(":/icons/resources/close_round_press.svg");
m_closeBtn2D->setVisible(false);
m_title->setObjectName("AppSnapshotTitle");
m_title->setAccessibleName("AppSnapshotTitle");
QHBoxLayout *centralLayout = new QHBoxLayout;
centralLayout->addWidget(m_title);

View File

@ -38,6 +38,7 @@ FloatingPreview::FloatingPreview(QWidget *parent)
, m_closeBtn3D(new DImageButton)
, m_titleBtn(new DPushButton)
{
m_closeBtn3D->setAccessibleName("closebutton-3d");
m_closeBtn3D->setFixedSize(24, 24);
m_closeBtn3D->setNormalPic(":/icons/resources/close_round_normal.svg");
m_closeBtn3D->setHoverPic(":/icons/resources/close_round_hover.svg");

View File

@ -79,6 +79,11 @@ QSize DockItem::sizeHint() const
return QSize(size, size);
}
QString DockItem::accessibleName()
{
return QString();
}
DockItem::~DockItem()
{
if (m_popupShown)

View File

@ -59,6 +59,7 @@ public:
inline virtual ItemType itemType() const {Q_UNREACHABLE(); return App;}
QSize sizeHint() const override;
virtual QString accessibleName();
public slots:
virtual void refershIcon() {}

View File

@ -40,9 +40,9 @@ LauncherItem::LauncherItem(QWidget *parent)
{
m_launcherInter->setSync(true, false);
setAccessibleName("Launcher");
m_tips->setVisible(false);
m_tips->setObjectName("launcher");
m_tips->setAccessibleName("launchertips");
connect(m_gsettings, &QGSettings::changed, this, &LauncherItem::onGSettingsChanged);
}

View File

@ -48,6 +48,7 @@ PluginsItem::PluginsItem(PluginsItemInterface *const pluginInter, const QString
m_centralWidget->setParent(this);
m_centralWidget->setVisible(true);
m_centralWidget->setAccessibleName("centralwidget");
m_centralWidget->installEventFilter(this);
QBoxLayout *hLayout = new QHBoxLayout;

View File

@ -20,8 +20,11 @@
*/
#include "window/mainwindow.h"
#include "window/accessible.h"
#include "util/themeappicon.h"
#include <QAccessible>
#include <DApplication>
#include <DLog>
#include <DDBusSender>
@ -49,17 +52,59 @@ void RegisterDdeSession()
if (!cookie.isEmpty()) {
QDBusPendingReply<bool> r = DDBusSender()
.interface("com.deepin.SessionManager")
.path("/com/deepin/SessionManager")
.service("com.deepin.SessionManager")
.method("Register")
.arg(QString(cookie))
.call();
.interface("com.deepin.SessionManager")
.path("/com/deepin/SessionManager")
.service("com.deepin.SessionManager")
.method("Register")
.arg(QString(cookie))
.call();
qDebug() << Q_FUNC_INFO << r.value();
}
}
QAccessibleInterface *accessibleFactory(const QString &classname, QObject *object)
{
QAccessibleInterface *interface = nullptr;
USE_ACCESSIBLE(classname,MainPanelControl);
USE_ACCESSIBLE(classname,LauncherItem);
USE_ACCESSIBLE(classname,AppItem);
USE_ACCESSIBLE(classname,PreviewContainer);
USE_ACCESSIBLE(classname,PluginsItem);
USE_ACCESSIBLE(classname,TrayPluginItem);
USE_ACCESSIBLE(classname,PlaceholderItem);
USE_ACCESSIBLE(classname,AppDragWidget);
USE_ACCESSIBLE(classname,AppSnapshot);
USE_ACCESSIBLE(classname,FloatingPreview);
USE_ACCESSIBLE(classname,SNITrayWidget);
USE_ACCESSIBLE(classname,SystemTrayItem);
USE_ACCESSIBLE(classname,FashionTrayItem);
USE_ACCESSIBLE(classname,FashionTrayWidgetWrapper);
USE_ACCESSIBLE(classname,FashionTrayControlWidget);
USE_ACCESSIBLE(classname,AttentionContainer);
USE_ACCESSIBLE(classname,HoldContainer);
USE_ACCESSIBLE(classname,NormalContainer);
USE_ACCESSIBLE(classname,SpliterAnimated);
USE_ACCESSIBLE(classname,IndicatorTrayWidget);
USE_ACCESSIBLE(classname,XEmbedTrayWidget);
USE_ACCESSIBLE(classname,ShowDesktopWidget);
USE_ACCESSIBLE(classname,SoundItem);
USE_ACCESSIBLE(classname,SoundApplet);
USE_ACCESSIBLE(classname,SinkInputWidget);
USE_ACCESSIBLE(classname,VolumeSlider);
USE_ACCESSIBLE(classname,HorizontalSeparator);
USE_ACCESSIBLE(classname,TipsWidget);
USE_ACCESSIBLE(classname,DatetimeWidget);
USE_ACCESSIBLE(classname,OnboardItem);
USE_ACCESSIBLE(classname,TrashWidget);
USE_ACCESSIBLE(classname,PopupControlWidget);
USE_ACCESSIBLE(classname,ShutdownWidget);
USE_ACCESSIBLE(classname,MultitaskingWidget);
// USE_ACCESSIBLE(classname,OverlayWarningWidget);
return interface;
}
int main(int argc, char *argv[])
{
DGuiApplicationHelper::setUseInactiveColorGroup(false);
@ -74,6 +119,8 @@ int main(int argc, char *argv[])
app.setAttribute(Qt::AA_EnableHighDpiScaling, true);
app.setAttribute(Qt::AA_UseHighDpiPixmaps, false);
QAccessible::installFactory(accessibleFactory);
// load dde-network-utils translator
QTranslator translator;
translator.load("/usr/share/dde-network-utils/translations/dde-network-utils_" + QLocale::system().name());

View File

@ -96,6 +96,10 @@ MainPanelControl::~MainPanelControl()
void MainPanelControl::init()
{
// 主窗口
m_fixedSpliter->setAccessibleName("spliter_fix");
m_appSpliter->setAccessibleName("spliter_app");
m_traySpliter->setAccessibleName("spliter_tray");
m_mainPanelLayout->addWidget(m_fixedAreaWidget);
m_mainPanelLayout->addWidget(m_fixedSpliter);
m_mainPanelLayout->addWidget(m_appAreaWidget);
@ -113,24 +117,28 @@ void MainPanelControl::init()
// 固定区域
m_fixedAreaWidget->setLayout(m_fixedAreaLayout);
m_fixedAreaWidget->setAccessibleName("fixedarea");
m_fixedAreaLayout->setMargin(0);
m_fixedAreaLayout->setContentsMargins(0, 0, 0, 0);
m_fixedAreaLayout->setSpacing(0);
// 应用程序
m_appAreaSonWidget->setLayout(m_appAreaSonLayout);
m_appAreaSonWidget->setAccessibleName("apparea");
m_appAreaSonLayout->setMargin(0);
m_appAreaSonLayout->setContentsMargins(0, 0, 0, 0);
m_appAreaSonLayout->setSpacing(0);
// 托盘
m_trayAreaWidget->setLayout(m_trayAreaLayout);
m_trayAreaWidget->setAccessibleName("trayarea");
m_trayAreaLayout->setMargin(0);
m_trayAreaLayout->setContentsMargins(0, 10, 0, 10);
m_trayAreaLayout->setSpacing(0);
// 插件
m_pluginAreaWidget->setLayout(m_pluginLayout);
m_pluginAreaWidget->setAccessibleName("pluginarea");
m_pluginLayout->setMargin(0);
m_pluginLayout->setSpacing(10);

View File

@ -97,7 +97,7 @@ public slots:
void removeItem(DockItem *item);
void itemUpdated(DockItem *item);
// void
// void
void onGSettingsChanged(const QString &key);
protected:
@ -114,7 +114,7 @@ private:
QBoxLayout *m_pluginLayout;
QWidget *m_appAreaSonWidget;
QBoxLayout *m_appAreaSonLayout;
QBoxLayout *m_appAreaLayout;
// QBoxLayout *m_appAreaLayout;
Position m_position;
QPointer<PlaceholderItem> m_placeholderItem;
MainPanelDelegate *m_delegate;

View File

@ -24,6 +24,8 @@
#include <QScreen>
#include <QApplication>
#include <QDesktopWidget>
#include <QAccessible>
#include <QAccessibleEvent>
DWIDGET_USE_NAMESPACE
@ -38,6 +40,8 @@ DockPopupWindow::DockPopupWindow(QWidget *parent)
m_acceptDelayTimer->setSingleShot(true);
m_acceptDelayTimer->setInterval(100);
setAccessibleName("popup");
m_wmHelper = DWindowManagerHelper::instance();
compositeChanged();
@ -66,6 +70,9 @@ void DockPopupWindow::setContent(QWidget *content)
lastWidget->removeEventFilter(this);
content->installEventFilter(this);
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
setAccessibleName(content->objectName() + "-popup");
DArrowRectangle::setContent(content);

View File

@ -73,6 +73,7 @@ DockSettings::DockSettings(QWidget *parent)
, m_itemManager(DockItemManager::instance(this))
, m_trashPluginShow(true)
{
m_settingsMenu.setAccessibleName("dock-settingsmenu");
checkService();
m_primaryRawRect = m_displayInter->primaryRawRect();
@ -98,12 +99,14 @@ DockSettings::DockSettings(QWidget *parent)
m_smartHideAct.setCheckable(true);
QMenu *modeSubMenu = new QMenu(&m_settingsMenu);
modeSubMenu->setAccessibleName("modesubmenu");
modeSubMenu->addAction(&m_fashionModeAct);
modeSubMenu->addAction(&m_efficientModeAct);
QAction *modeSubMenuAct = new QAction(tr("Mode"), this);
modeSubMenuAct->setMenu(modeSubMenu);
QMenu *locationSubMenu = new QMenu(&m_settingsMenu);
locationSubMenu->setAccessibleName("locationsubmenu");
locationSubMenu->addAction(&m_topPosAct);
locationSubMenu->addAction(&m_bottomPosAct);
locationSubMenu->addAction(&m_leftPosAct);
@ -112,6 +115,7 @@ DockSettings::DockSettings(QWidget *parent)
locationSubMenuAct->setMenu(locationSubMenu);
QMenu *statusSubMenu = new QMenu(&m_settingsMenu);
statusSubMenu->setAccessibleName("statussubmenu");
statusSubMenu->addAction(&m_keepShownAct);
statusSubMenu->addAction(&m_keepHiddenAct);
statusSubMenu->addAction(&m_smartHideAct);
@ -119,6 +123,7 @@ DockSettings::DockSettings(QWidget *parent)
statusSubMenuAct->setMenu(statusSubMenu);
m_hideSubMenu = new QMenu(&m_settingsMenu);
m_hideSubMenu->setAccessibleName("pluginsmenu");
QAction *hideSubMenuAct = new QAction(tr("Plugins"), this);
hideSubMenuAct->setMenu(m_hideSubMenu);

427
frame/window/accessible.cpp Normal file
View File

@ -0,0 +1,427 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: fpc_diesel <fanpengcheng@uniontech.com>
*
* Maintainer: fpc_diesel <fanpengcheng@uniontech.com>
*
* 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 3 of the License, or
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "accessible.h"
QString getAccesibleName(QWidget *w,QString fallback)
{
return w->accessibleName().isEmpty()?fallback:w->accessibleName();
}
QString AccessibleMainPanelControl::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"mainpanelcontrol");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleLauncherItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"launcheritem");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleAppItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->accessibleName());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessiblePreviewContainer::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"previewcontainer");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessiblePluginsItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->pluginName());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleTrayPluginItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->pluginName());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessiblePlaceholderItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"placeholderitem");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleAppDragWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"appdragwidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleAppSnapshot::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"appsnapshot");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleFloatingPreview::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"floatingpreview");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleSNITrayWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->itemKeyForConfig());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleSystemTrayItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->itemKeyForConfig());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleFashionTrayItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"fashiontrayitem");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleFashionTrayWidgetWrapper::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"fashiontraywrapper");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleFashionTrayControlWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"fashiontraycontrolwidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleAttentionContainer::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"attentioncontainer");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleHoldContainer::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"holdcontainer");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleNormalContainer::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"normalcontainer");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleSpliterAnimated::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"spliteranimated");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleIndicatorTrayWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->itemKeyForConfig());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleXEmbedTrayWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->itemKeyForConfig());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleShowDesktopWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"showdesktop");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleSoundItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"sounditem");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleSoundApplet::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"soundapplet");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleSinkInputWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"sinkinputwidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleVolumeSlider::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"volumeslider");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleHorizontalSeparator::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"horizontalseparator");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleTipsWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,m_w->text());
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleDatetimeWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"datetimewidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleOnboardItem::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"onboarditem");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleTrashWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"trashwidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessiblePopupControlWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"popupcontrolwidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleShutdownWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"shutdownwidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
QString AccessibleMultitaskingWidget::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Name:
return getAccesibleName(m_w,"multitaskingwidget");
case QAccessible::Description:
return m_description;
default:
return QString();
}
}
//QString AccessibleOverlayWarningWidget::text(QAccessible::Text t) const
//{
// switch (t) {
// case QAccessible::Name:
// return "overlaywarningwidget";
// case QAccessible::Description:
// return m_description;
// default:
// return QString();
// }
//}

246
frame/window/accessible.h Normal file
View File

@ -0,0 +1,246 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: fpc_diesel <fanpengcheng@uniontech.com>
*
* Maintainer: fpc_diesel <fanpengcheng@uniontech.com>
*
* 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 3 of the License, or
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef ACCESSIBLE_H
#define ACCESSIBLE_H
#include "../panel/mainpanelcontrol.h"
#include "../item/launcheritem.h"
#include "../item/appitem.h"
#include "../item/components/previewcontainer.h"
#include "../item/pluginsitem.h"
#include "../item/traypluginitem.h"
#include "../item/placeholderitem.h"
#include "../item/components/appdragwidget.h"
#include "../item/components/appsnapshot.h"
#include "../item/components/floatingpreview.h"
#include "../plugins/tray/snitraywidget.h"
#include "../plugins/tray/indicatortraywidget.h"
#include "../plugins/tray/xembedtraywidget.h"
#include "../plugins/tray/system-trays/systemtrayitem.h"
#include "../plugins/tray/fashiontray/fashiontrayitem.h"
#include "../plugins/tray/fashiontray/fashiontraywidgetwrapper.h"
#include "../plugins/tray/fashiontray/fashiontraycontrolwidget.h"
#include "../plugins/tray/fashiontray/containers/attentioncontainer.h"
#include "../plugins/tray/fashiontray/containers/holdcontainer.h"
#include "../plugins/tray/fashiontray/containers/normalcontainer.h"
#include "../plugins/tray/fashiontray/containers/spliteranimated.h"
#include "../plugins/show-desktop/showdesktopwidget.h"
#include "../plugins/sound/sounditem.h"
#include "../plugins/sound/soundapplet.h"
#include "../plugins/sound/sinkinputwidget.h"
#include "../plugins/sound/componments/volumeslider.h"
#include "../plugins/sound/componments/horizontalseparator.h"
#include "../../widgets/tipswidget.h"
#include "../plugins/datetime/datetimewidget.h"
#include "../plugins/onboard/onboarditem.h"
#include "../plugins/trash/trashwidget.h"
#include "../plugins/trash/popupcontrolwidget.h"
#include "../plugins/shutdown/shutdownwidget.h"
#include "../plugins/multitasking/multitaskingwidget.h"
//#include "../plugins/overlay-warning/overlaywarningwidget.h"
#include <QAccessible>
#include <QAccessibleWidget>
#include <QEvent>
#include <QMouseEvent>
#include <QApplication>
/**************************************************************************************/
// 构造函数
#define FUNC_CREATE(classname,accessibletype,accessdescription) Accessible##classname(classname *w) \
: QAccessibleWidget(w,accessibletype,#classname)\
, m_w(w)\
, m_description(accessdescription)\
{}\
private:\
classname *m_w;\
QString m_description;\
// 左键点击
#define FUNC_PRESS(classobj) QStringList actionNames() const override{return QStringList() << pressAction();}\
void doAction(const QString &actionName) override{\
if(actionName == pressAction())\
{\
QPointF localPos = classobj->geometry().center();\
QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\
QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\
qApp->sendEvent(classobj,&event);\
qApp->sendEvent(classobj,&event2);\
}\
}\
// 右键点击
#define FUNC_SHOWMENU(classobj) QStringList actionNames() const override{return QStringList() << showMenuAction();}\
void doAction(const QString &actionName) override{\
if(actionName == showMenuAction())\
{\
QPointF localPos = classobj->geometry().center();\
QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\
QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\
qApp->sendEvent(classobj,&event);\
qApp->sendEvent(classobj,&event2);\
}\
}\
// 左键和右键点击
#define FUNC_PRESS_SHOWMENU(classobj) QStringList actionNames() const override{return QStringList() << pressAction() << showMenuAction();}\
void doAction(const QString &actionName) override{\
if(actionName == pressAction())\
{\
QPointF localPos = classobj->geometry().center();\
QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\
QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);\
qApp->sendEvent(classobj,&event);\
qApp->sendEvent(classobj,&event2);\
}\
else if(actionName == showMenuAction())\
{\
QPointF localPos = classobj->geometry().center();\
QMouseEvent event(QEvent::MouseButtonPress,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\
QMouseEvent event2(QEvent::MouseButtonRelease,localPos,Qt::RightButton,Qt::RightButton,Qt::NoModifier);\
qApp->sendEvent(classobj,&event);\
qApp->sendEvent(classobj,&event2);\
}\
}\
// 实现rect接口
#define FUNC_RECT(classobj) QRect rect() const override{\
if (!classobj->isVisible())\
return QRect();\
return classobj->geometry();\
}\
// 启用accessible
#define USE_ACCESSIBLE(classnamestring,classname) if (classnamestring == QLatin1String(#classname) && object && object->isWidgetType())\
{\
interface = new Accessible##classname(static_cast<classname *>(object));\
}\
//// 启用accessible[指定objectname]---适用同一个类但objectname不同的情况
//#define USE_ACCESSIBLE_BY_OBJECTNAME(classnamestring,classname,objectname) if (classnamestring == QLatin1String(#classname) && object && (object->objectName() == objectname) && object->isWidgetType())\
//{\
// interface = new Accessible##classname(static_cast<classname *>(object));\
// }\
// 按钮类型的控件[仅有左键点击]
#define SET_BUTTON_ACCESSIBLE_PRESS_DESCRIPTION(classname,accessdescription) class Accessible##classname : public QAccessibleWidget\
{\
public:\
FUNC_CREATE(classname,QAccessible::Button,accessdescription)\
QString text(QAccessible::Text t) const override;/*需要单独实现*/\
FUNC_PRESS(m_w)\
};\
// 按钮类型的控件[仅有右键点击]
#define SET_BUTTON_ACCESSIBLE_SHOWMENU_DESCRIPTION(classname,accessdescription) class Accessible##classname : public QAccessibleWidget\
{\
public:\
FUNC_CREATE(classname,QAccessible::Button,accessdescription)\
QString text(QAccessible::Text t) const override;/*需要单独实现*/\
FUNC_SHOWMENU(m_w)\
};\
// 按钮类型的控件[有左键点击和右键点击]
#define SET_BUTTON_ACCESSIBLE_PRESS_SHOEMENU_DESCRIPTION(classname,accessdescription) class Accessible##classname : public QAccessibleWidget\
{\
public:\
FUNC_CREATE(classname,QAccessible::Button,accessdescription)\
QString text(QAccessible::Text t) const override;/*需要单独实现*/\
FUNC_PRESS_SHOWMENU(m_w)\
};\
// 标签类型的控件
#define SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,aaccessibletype,accessdescription) class Accessible##classname : public QAccessibleWidget\
{\
public:\
FUNC_CREATE(classname,aaccessibletype,accessdescription)\
QString text(QAccessible::Text t) const override;/*需要单独实现*/\
FUNC_RECT(m_w)\
};\
// 简化使用
#define SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU(classname) SET_BUTTON_ACCESSIBLE_PRESS_SHOEMENU_DESCRIPTION(classname,"")
#define SET_BUTTON_ACCESSIBLE_SHOWMENU(classname) SET_BUTTON_ACCESSIBLE_SHOWMENU_DESCRIPTION(classname,"")
#define SET_BUTTON_ACCESSIBLE(classname) SET_BUTTON_ACCESSIBLE_PRESS_DESCRIPTION(classname,"")
#define SET_LABEL_ACCESSIBLE(classname) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::StaticText,"")
#define SET_FORM_ACCESSIBLE(classname) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::Form,"")
#define SET_SLIDER_ACCESSIBLE(classname) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::Slider,"")
#define SET_SEPARATOR_ACCESSIBLE(classname) SET_LABEL_ACCESSIBLE_WITH_DESCRIPTION(classname,QAccessible::Separator,"")
/**************************************************************************************/
// 添加accessible
SET_BUTTON_ACCESSIBLE_SHOWMENU(MainPanelControl)
SET_BUTTON_ACCESSIBLE(LauncherItem)
SET_BUTTON_ACCESSIBLE(AppItem)
SET_BUTTON_ACCESSIBLE(PreviewContainer)
SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU(PluginsItem)
SET_BUTTON_ACCESSIBLE(TrayPluginItem)
SET_BUTTON_ACCESSIBLE(PlaceholderItem)
SET_BUTTON_ACCESSIBLE(AppDragWidget)
SET_BUTTON_ACCESSIBLE(AppSnapshot)
SET_BUTTON_ACCESSIBLE(FloatingPreview)
// tray plugin
SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU(XEmbedTrayWidget)
SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU(IndicatorTrayWidget)
SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU(SNITrayWidget)
SET_BUTTON_ACCESSIBLE_PRESS_SHOWMENU(SystemTrayItem)
SET_FORM_ACCESSIBLE(FashionTrayItem)
SET_FORM_ACCESSIBLE(FashionTrayWidgetWrapper)
SET_FORM_ACCESSIBLE(FashionTrayControlWidget)
SET_FORM_ACCESSIBLE(AttentionContainer)
SET_FORM_ACCESSIBLE(HoldContainer)
SET_FORM_ACCESSIBLE(NormalContainer)
SET_FORM_ACCESSIBLE(SpliterAnimated)
// showdesktop plugin
SET_BUTTON_ACCESSIBLE(ShowDesktopWidget)// 未生效
// sound plugin
SET_BUTTON_ACCESSIBLE(SoundItem)
SET_FORM_ACCESSIBLE(SoundApplet)
SET_FORM_ACCESSIBLE(SinkInputWidget)
SET_SLIDER_ACCESSIBLE(VolumeSlider)
SET_SEPARATOR_ACCESSIBLE(HorizontalSeparator)
SET_LABEL_ACCESSIBLE(TipsWidget)
// fixed plugin
SET_FORM_ACCESSIBLE(DatetimeWidget)
SET_FORM_ACCESSIBLE(OnboardItem)
SET_FORM_ACCESSIBLE(TrashWidget)
SET_FORM_ACCESSIBLE(PopupControlWidget)
SET_FORM_ACCESSIBLE(ShutdownWidget)
// multitasking plugin
SET_FORM_ACCESSIBLE(MultitaskingWidget)
//SET_FORM_ACCESSIBLE(OverlayWarningWidget)
#endif // ACCESSIBLE_H

View File

@ -149,6 +149,7 @@ MainWindow::MainWindow(QWidget *parent)
m_dragWidget(new DragWidget(this))
{
setAccessibleName("dock-mainwindow");
m_mainPanel->setAccessibleName("mainpanel");
setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
setAcceptDrops(true);

View File

@ -140,7 +140,7 @@ void OverlayWarningPlugin::loadPlugin()
m_pluginLoaded = true;
m_warningWidget = new PluginWidget;
m_warningWidget = new OverlayWarningWidget;
if (!isOverlayRoot()) {
return;

View File

@ -24,7 +24,7 @@
#define OVERLAY_WARNING_PLUGIN_H
#include "pluginsiteminterface.h"
#include "pluginwidget.h"
#include "overlaywarningwidget.h"
#include "../widgets/tipswidget.h"
#include <QLabel>
@ -71,7 +71,7 @@ private slots:
private:
bool m_pluginLoaded;
PluginWidget *m_warningWidget;
OverlayWarningWidget *m_warningWidget;
QTimer *m_showDisableOverlayDialogTimer;
};

View File

@ -20,7 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pluginwidget.h"
#include "overlaywarningwidget.h"
#include <QSvgRenderer>
#include <QPainter>
@ -28,17 +28,17 @@
#include <QApplication>
#include <QIcon>
PluginWidget::PluginWidget(QWidget *parent)
OverlayWarningWidget::OverlayWarningWidget(QWidget *parent)
: QWidget(parent)
{
}
QSize PluginWidget::sizeHint() const
QSize OverlayWarningWidget::sizeHint() const
{
return QSize(26, 26);
}
void PluginWidget::paintEvent(QPaintEvent *e)
void OverlayWarningWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
@ -62,7 +62,7 @@ void PluginWidget::paintEvent(QPaintEvent *e)
painter.drawPixmap(rf.center() - rfp.center() / devicePixelRatioF(), pixmap);
}
const QPixmap PluginWidget::loadSvg(const QString &fileName, const QSize &size) const
const QPixmap OverlayWarningWidget::loadSvg(const QString &fileName, const QSize &size) const
{
const auto ratio = devicePixelRatioF();

View File

@ -23,16 +23,16 @@
#ifndef PLUGINWIDGET_H
#define PLUGINWIDGET_H
#include "constants.h"
#include "../../interfaces/constants.h"
#include <QWidget>
class PluginWidget : public QWidget
class OverlayWarningWidget : public QWidget
{
Q_OBJECT
public:
explicit PluginWidget(QWidget *parent = 0);
explicit OverlayWarningWidget(QWidget *parent = 0);
protected:
QSize sizeHint() const;

View File

@ -31,7 +31,7 @@ ShowDesktopPlugin::ShowDesktopPlugin(QObject *parent)
, m_tipsLabel(new TipsWidget)
{
m_tipsLabel->setVisible(false);
m_tipsLabel->setObjectName("show-desktop");
m_tipsLabel->setAccessibleName("show-desktop");
}
const QString ShowDesktopPlugin::pluginName() const

View File

@ -235,7 +235,7 @@ void ShutdownPlugin::loadPlugin()
m_pluginLoaded = true;
m_shutdownWidget = new PluginWidget;
m_shutdownWidget = new ShutdownWidget;
m_proxyInter->itemAdded(this, pluginName());
displayModeChanged(displayMode());

View File

@ -23,7 +23,7 @@
#define SHUTDOWNPLUGIN_H
#include "pluginsiteminterface.h"
#include "pluginwidget.h"
#include "shutdownwidget.h"
#include "../widgets/tipswidget.h"
#include "./dbus/dbuslogin1manager.h"
@ -107,7 +107,7 @@ private:
private:
bool m_pluginLoaded;
PluginWidget *m_shutdownWidget;
ShutdownWidget *m_shutdownWidget;
TipsWidget *m_tipsLabel;
DBusLogin1Manager* m_login1Inter;
};

View File

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pluginwidget.h"
#include "shutdownwidget.h"
#include <QSvgRenderer>
#include <QPainter>
@ -32,7 +32,7 @@
DWIDGET_USE_NAMESPACE;
PluginWidget::PluginWidget(QWidget *parent)
ShutdownWidget::ShutdownWidget(QWidget *parent)
: QWidget(parent)
, m_hover(false)
, m_pressed(false)
@ -46,7 +46,7 @@ PluginWidget::PluginWidget(QWidget *parent)
m_icon = QIcon::fromTheme(":/icons/resources/icons/system-shutdown.svg");
}
void PluginWidget::paintEvent(QPaintEvent *e)
void ShutdownWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
@ -110,7 +110,7 @@ void PluginWidget::paintEvent(QPaintEvent *e)
painter.drawPixmap(rf.center() - rfp.center() / pixmap.devicePixelRatioF(), pixmap);
}
const QPixmap PluginWidget::loadSvg(const QString &fileName, const QSize &size) const
const QPixmap ShutdownWidget::loadSvg(const QString &fileName, const QSize &size) const
{
const auto ratio = devicePixelRatioF();
@ -121,7 +121,7 @@ const QPixmap PluginWidget::loadSvg(const QString &fileName, const QSize &size)
return pixmap;
}
void PluginWidget::mousePressEvent(QMouseEvent *event)
void ShutdownWidget::mousePressEvent(QMouseEvent *event)
{
m_pressed = true;
update();
@ -129,7 +129,7 @@ void PluginWidget::mousePressEvent(QMouseEvent *event)
QWidget::mousePressEvent(event);
}
void PluginWidget::mouseReleaseEvent(QMouseEvent *event)
void ShutdownWidget::mouseReleaseEvent(QMouseEvent *event)
{
m_pressed = false;
m_hover = false;
@ -138,13 +138,13 @@ void PluginWidget::mouseReleaseEvent(QMouseEvent *event)
QWidget::mouseReleaseEvent(event);
}
void PluginWidget::mouseMoveEvent(QMouseEvent *event)
void ShutdownWidget::mouseMoveEvent(QMouseEvent *event)
{
m_hover = true;
QWidget::mouseMoveEvent(event);
}
void PluginWidget::leaveEvent(QEvent *event)
void ShutdownWidget::leaveEvent(QEvent *event)
{
m_hover = false;
m_pressed = false;

View File

@ -27,12 +27,12 @@
#include <QWidget>
#include <QIcon>
class PluginWidget : public QWidget
class ShutdownWidget : public QWidget
{
Q_OBJECT
public:
explicit PluginWidget(QWidget *parent = 0);
explicit ShutdownWidget(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *e) override;

View File

@ -29,6 +29,7 @@
#include <QLabel>
#include <QIcon>
#include <QScrollBar>
#include <DApplication>
#define WIDTH 200
@ -49,18 +50,22 @@ SoundApplet::SoundApplet(QWidget *parent)
, m_audioInter(new DBusAudio(this))
, m_defSinkInter(nullptr)
{
// QIcon::setThemeName("deepin");
// QIcon::setThemeName("deepin");
m_centralWidget->setAccessibleName("volumn-centralwidget");
m_volumeBtn->setAccessibleName("volume-button");
m_volumeIconMax->setAccessibleName("volume-iconmax");
m_volumeSlider->setAccessibleName("volume-slider");
m_soundShow->setAccessibleName("volume-soundtips");
this->horizontalScrollBar()->setAccessibleName("volume-horizontalscrollbar");
this->verticalScrollBar()->setAccessibleName("volume-verticalscrollbar");
m_volumeIconMax->setFixedSize(ICON_SIZE, ICON_SIZE);
m_volumeSlider->setAccessibleName("volume-slider");
m_soundShow->setText(QString("%1%").arg(0));
TipsWidget *deviceLabel = new TipsWidget;
deviceLabel->setText(tr("Device"));
QHBoxLayout *deviceLayout =new QHBoxLayout;
deviceLayout->addSpacing(2);
deviceLayout->addWidget(deviceLabel,0, Qt::AlignLeft);
@ -70,7 +75,7 @@ SoundApplet::SoundApplet(QWidget *parent)
QVBoxLayout *deviceLineLayout = new QVBoxLayout;
deviceLineLayout->addLayout(deviceLayout);
// deviceLineLayout->addSpacing(12);
// deviceLineLayout->addSpacing(12);
deviceLineLayout->addWidget(new HorizontalSeparator);
deviceLineLayout->setMargin(0);
deviceLineLayout->setSpacing(10);
@ -102,6 +107,7 @@ SoundApplet::SoundApplet(QWidget *parent)
appLineVLayout->setMargin(0);
m_applicationTitle->setLayout(appLineVLayout);
m_applicationTitle->setAccessibleName("applicationtitle");
m_volumeBtn->setFixedSize(ICON_SIZE, ICON_SIZE);
m_volumeSlider->setMinimum(0);

View File

@ -47,6 +47,7 @@ SoundItem::SoundItem(QWidget *parent)
m_sinkInter(nullptr)
{
m_tipsLabel->setObjectName("sound");
m_tipsLabel->setAccessibleName("soundtips");
m_tipsLabel->setVisible(false);
m_applet->setVisible(false);

View File

@ -37,7 +37,7 @@ target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
${DFrameworkDBus_INCLUDE_DIRS}
${QGSettings_INCLUDE_DIRS}
../../interfaces
../../frame)
../../frame )
target_link_libraries(${PLUGIN_NAME} PRIVATE
${DtkWidget_LIBRARIES}
${Qt5Widgets_LIBRARIES}

View File

@ -2,7 +2,7 @@
#define ABSTRACTCONTAINER_H
#include "constants.h"
#include "trayplugin.h"
#include "../../trayplugin.h"
#include "../fashiontraywidgetwrapper.h"
#include <QWidget>

View File

@ -55,6 +55,7 @@ FashionTrayItem::FashionTrayItem(TrayPlugin *trayPlugin, QWidget *parent)
m_mainBoxLayout->setSpacing(0);
m_leftSpace->setFixedSize(TraySpace, TraySpace);
m_leftSpace->setAccessibleName("leftspace");
m_mainBoxLayout->addWidget(m_leftSpace);
m_mainBoxLayout->addWidget(m_normalContainer);

View File

@ -23,7 +23,7 @@
#define FASHIONTRAYITEM_H
#include "constants.h"
#include "trayplugin.h"
#include "../trayplugin.h"
#include "fashiontraywidgetwrapper.h"
#include "fashiontraycontrolwidget.h"
#include "containers/normalcontainer.h"
@ -35,7 +35,7 @@
#include <QBoxLayout>
#include <QLabel>
#include <abstracttraywidget.h>
#include "../abstracttraywidget.h"
#define FASHION_MODE_ITEM_KEY "fashion-mode-item"

View File

@ -22,7 +22,7 @@
#ifndef FASHIONTRAYWIDGETWRAPPER_H
#define FASHIONTRAYWIDGETWRAPPER_H
#include "abstracttraywidget.h"
#include "../abstracttraywidget.h"
#include <QWidget>
#include <QVBoxLayout>

View File

@ -21,7 +21,7 @@
#include "snitraywidget.h"
#include "util/themeappicon.h"
#include <dbusmenu-qt5/dbusmenuimporter.h>
#include <QPainter>
#include <QApplication>

View File

@ -28,12 +28,12 @@
#include "../../widgets/tipswidget.h"
#include <org_kde_statusnotifieritem.h>
#include <dbusmenu-qt5/dbusmenuimporter.h>
#include <QMenu>
#include <QDBusObjectPath>
DWIDGET_USE_NAMESPACE
DGUI_USE_NAMESPACE
class DBusMenuImporter;
//using namespace com::deepin::dde;
using namespace org::kde;

View File

@ -23,7 +23,7 @@
#define SYSTEMTRAYITEM_H
#include "constants.h"
#include "abstracttraywidget.h"
#include "../abstracttraywidget.h"
#include "util/dockpopupwindow.h"
#include "pluginsiteminterface.h"

View File

@ -9,6 +9,7 @@ class TipsWidget : public QFrame
public:
explicit TipsWidget(QWidget *parent = nullptr);
const QString& text(){return m_text;}
void setText(const QString &text);
void refreshFont();