Merge branch 'maintain/5.2'

Change-Id: Ibf45f76bffd88100a2de4ec13b5da539ea843db6

# Conflicts:
#	debian/control
#	frame/item/components/previewcontainer.cpp
#	translations/dde-dock_az.ts
This commit is contained in:
范朋程 2021-02-26 09:48:26 +08:00
commit 29082f5f01
66 changed files with 1122 additions and 361 deletions

1
debian/control vendored
View File

@ -34,6 +34,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends},
deepin-desktop-schemas (>=5.8.0.34),
libdframeworkdbus2 (>=5.3.0.24),
libdde-network-utils (>=5.3.0.5),
dde-qt5xcb-plugin (>=5.0.19),
dde-daemon (>=5.12.0.31),
startdde (>=5.6.0.34),
lastore-daemon (>=5.1.0.21)

View File

@ -45,8 +45,12 @@ void DBusDockAdaptors::callShow()
return parent()->callShow();
}
void DBusDockAdaptors::ReloadPlugins()
{
return parent()->relaodPlugins();
}
QRect DBusDockAdaptors::geometry() const
{
return parent()->geometry();
}

View File

@ -36,6 +36,7 @@ class DBusDockAdaptors: public QDBusAbstractAdaptor
" <interface name=\"com.deepin.dde.Dock\">\n"
" <property access=\"read\" type=\"(iiii)\" name=\"geometry\"/>\n"
" <method name=\"callShow\"/>"
" <method name=\"ReloadPlugins\"/>"
" <signal name=\"geometryChanged\">"
"<arg name=\"geometry\" type=\"(iiii)\"/>"
"</signal>"
@ -50,6 +51,7 @@ public:
public Q_SLOTS: // METHODS
void callShow();
void ReloadPlugins();
public: // PROPERTIES
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)

View File

@ -142,6 +142,11 @@ AppItem::~AppItem()
m_appNameTips->deleteLater();
}
void AppItem::checkEntry()
{
m_itemEntryInter->Check();
}
const QString AppItem::appId() const
{
return m_id;

View File

@ -46,6 +46,7 @@ public:
explicit AppItem(const QDBusObjectPath &entry, QWidget *parent = nullptr);
~AppItem() override;
void checkEntry() override;
const QString appId() const;
bool isValid() const;
void updateWindowIconGeometries();

View File

@ -203,7 +203,6 @@ void AppDragWidget::dropEvent(QDropEvent *event)
} else {
hide();
}
emit animationFinished();
AppItem *appItem = static_cast<AppItem *>(event->source());
appItem->undock();
m_popupWindow->setVisible(false);
@ -267,7 +266,6 @@ void AppDragWidget::initAnimations()
connect(m_animGroup, &QParallelAnimationGroup::stateChanged,
this, &AppDragWidget::onRemoveAnimationStateChanged);
connect(m_goBackAnim, &QPropertyAnimation::finished, this, &AppDragWidget::hide);
connect(m_goBackAnim, &QPropertyAnimation::finished, this, &AppDragWidget::animationFinished);
}
void AppDragWidget::initConfigurations()

View File

@ -51,7 +51,6 @@ public:
signals:
void requestRemoveItem();
void animationFinished();
protected:
void mouseMoveEvent(QMouseEvent *event) override;

View File

@ -58,14 +58,14 @@ AppSnapshot::AppSnapshot(const WId wid, QWidget *parent)
: QWidget(parent)
, m_wid(wid)
, m_isWidowHidden(false)
, m_title(new TipsWidget)
, m_title(new TipsWidget(this))
, m_waitLeaveTimer(new QTimer(this))
, m_closeBtn2D(new DIconButton(this))
, m_wmHelper(DWindowManagerHelper::instance())
, m_dockDaemonInter(new DockDaemonInter("com.deepin.dde.daemon.Dock", "/com/deepin/dde/daemon/Dock", QDBusConnection::sessionBus(), this))
{
m_closeBtn2D->setFixedSize(24, 24);
m_closeBtn2D->setIconSize(QSize(24, 24));
m_closeBtn2D->setFixedSize(SNAP_CLOSE_BTN_WIDTH, SNAP_CLOSE_BTN_WIDTH);
m_closeBtn2D->setIconSize(QSize(SNAP_CLOSE_BTN_WIDTH, SNAP_CLOSE_BTN_WIDTH));
m_closeBtn2D->setObjectName("closebutton-2d");
m_closeBtn2D->setIcon(QIcon(":/icons/resources/close_round_normal.svg"));
m_closeBtn2D->setVisible(false);
@ -210,7 +210,7 @@ void AppSnapshot::enterEvent(QEvent *e)
QWidget::enterEvent(e);
if (!m_wmHelper->hasComposite()) {
m_closeBtn2D->move(width() - m_closeBtn2D->width() - 5, (height() - m_closeBtn2D->height()) / 2);
m_closeBtn2D->move(width() - m_closeBtn2D->width() - SNAP_CLOSE_BTN_MARGIN, (height() - m_closeBtn2D->height()) / 2);
m_closeBtn2D->setVisible(true);
} else {
emit entered(wid());
@ -284,14 +284,12 @@ void AppSnapshot::mousePressEvent(QMouseEvent *e)
bool AppSnapshot::eventFilter(QObject *watched, QEvent *e)
{
if(watched == m_closeBtn2D) {
if(watched == m_closeBtn2D && (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverMove)) {
if (watched == m_closeBtn2D) {
if (watched == m_closeBtn2D && (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverMove)) {
m_closeBtn2D->setIcon(QIcon(":/icons/resources/close_round_hover.svg"));
}
else if (watched == m_closeBtn2D && e->type() == QEvent::HoverLeave) {
} else if (watched == m_closeBtn2D && e->type() == QEvent::HoverLeave) {
m_closeBtn2D->setIcon(QIcon(":/icons/resources/close_round_normal.svg"));
}
else if (watched == m_closeBtn2D && e->type() == QEvent::MouseButtonPress) {
} else if (watched == m_closeBtn2D && e->type() == QEvent::MouseButtonPress) {
m_closeBtn2D->setIcon(QIcon(":/icons/resources/close_round_press.svg"));
}
}
@ -383,7 +381,7 @@ void AppSnapshot::getWindowState()
}
Atom *atoms = reinterpret_cast<Atom *>(properties);
for(i = 0; i < num_items; ++i) {
for (i = 0; i < num_items; ++i) {
const char *atomName = XGetAtomName(display, atoms[i]);
if (strcmp(atomName, "_NET_WM_STATE_HIDDEN") == 0) {

View File

@ -38,6 +38,9 @@ DGUI_USE_NAMESPACE
#define SNAP_WIDTH 200
#define SNAP_HEIGHT 130
#define SNAP_CLOSE_BTN_WIDTH (24)
#define SNAP_CLOSE_BTN_MARGIN (5)
struct SHMInfo;
struct _XImage;
typedef _XImage XImage;

View File

@ -38,7 +38,7 @@ PreviewContainer::PreviewContainer(QWidget *parent)
m_mouseLeaveTimer(new QTimer(this)),
m_wmHelper(DWindowManagerHelper::instance())
{
m_windowListLayout = new QBoxLayout(QBoxLayout::LeftToRight);
m_windowListLayout = new QBoxLayout(QBoxLayout::LeftToRight, this);
m_windowListLayout->setSpacing(SPACING);
m_windowListLayout->setContentsMargins(MARGIN, MARGIN, MARGIN, MARGIN);
@ -52,7 +52,6 @@ PreviewContainer::PreviewContainer(QWidget *parent)
m_waitForShowPreviewTimer->setInterval(200);
setAcceptDrops(true);
setLayout(m_windowListLayout);
setFixedSize(SNAP_WIDTH, SNAP_HEIGHT);
connect(m_mouseLeaveTimer, &QTimer::timeout, this, &PreviewContainer::checkMouseLeave, Qt::QueuedConnection);
@ -62,13 +61,11 @@ PreviewContainer::PreviewContainer(QWidget *parent)
void PreviewContainer::setWindowInfos(const WindowInfoMap &infos, const WindowList &allowClose)
{
// check removed window
for (auto it(m_snapshots.begin()); it != m_snapshots.end();)
{
for (auto it(m_snapshots.begin()); it != m_snapshots.end();) {
//初始化预览界面边距
it.value()->setContentsMargins(0, 0, 0, 0);
if (!infos.contains(it.key()))
{
if (!infos.contains(it.key())) {
m_windowListLayout->removeWidget(it.value());
it.value()->deleteLater();
it = m_snapshots.erase(it);
@ -77,8 +74,7 @@ void PreviewContainer::setWindowInfos(const WindowInfoMap &infos, const WindowLi
}
}
for (auto it(infos.cbegin()); it != infos.cend(); ++it)
{
for (auto it(infos.cbegin()); it != infos.cend(); ++it) {
const WId key = it.key();
if (!m_snapshots.contains(key))
appendSnapWidget(key);
@ -86,9 +82,10 @@ void PreviewContainer::setWindowInfos(const WindowInfoMap &infos, const WindowLi
m_snapshots[key]->setCloseAble(allowClose.contains(key));
}
if (m_snapshots.isEmpty())
if (m_snapshots.isEmpty()) {
emit requestCancelPreviewWindow();
emit requestHidePopup();
}
adjustSize();
}
@ -140,41 +137,43 @@ void PreviewContainer::adjustSize()
{
const int count = m_snapshots.size();
const bool composite = m_wmHelper->hasComposite();
if (!composite)
{
if (composite) {
// 3D
const QRect r = qApp->primaryScreen()->geometry();
const int padding = 20;
const bool horizontal = m_windowListLayout->direction() == QBoxLayout::LeftToRight;
if (horizontal) {
const int h = SNAP_HEIGHT + MARGIN * 2;
const int w = SNAP_WIDTH * count + MARGIN * 2 + SPACING * (count - 1);
setFixedHeight(h);
setFixedWidth(std::min(w, r.width() - padding));
} else {
const int w = SNAP_WIDTH + MARGIN * 2;
const int h = SNAP_HEIGHT * count + MARGIN * 2 + SPACING * (count - 1);
setFixedWidth(w);
setFixedHeight(std::min(h, r.height() - padding));
}
} else if (m_windowListLayout->count()) {
// 2D
const int h = SNAP_HEIGHT_WITHOUT_COMPOSITE * count + MARGIN * 2 + SPACING * (count - 1);
//根据appitem title 设置自适应宽度
auto appSnapshot = static_cast<AppSnapshot*>(this->layout()->itemAt(0)->widget());
// 根据appitem title 设置自适应宽度
auto appSnapshot = static_cast<AppSnapshot *>(m_windowListLayout->itemAt(0)->widget());
auto font = appSnapshot->layout()->itemAt(0)->widget()->font();
QFontMetrics fontMetrics(font);
const int fontSize = fontMetrics.boundingRect(appSnapshot->title()).width();
//预留字体到边缘的间距,边缘距离10px,关闭按钮24px
if (fontSize < SNAP_WIDTH - 44)
setFixedSize(fontSize + 44, h);
else
const int titleWidth = fontMetrics.boundingRect(appSnapshot->title()).width();
// 关闭按键的宽度和边缘间距的和,调整标题居中
const int closeBtnMargin = 2 * (SNAP_CLOSE_BTN_WIDTH + SNAP_CLOSE_BTN_MARGIN);
if (titleWidth < SNAP_WIDTH - closeBtnMargin) {
setFixedSize(titleWidth + closeBtnMargin, h);
} else {
setFixedSize(SNAP_WIDTH, h);
return;
}
const QRect r = qApp->primaryScreen()->geometry();
const int padding = 20;
const bool horizontal = m_windowListLayout->direction() == QBoxLayout::LeftToRight;
if (horizontal)
{
const int h = SNAP_HEIGHT + MARGIN * 2;
const int w = SNAP_WIDTH * count + MARGIN * 2 + SPACING * (count - 1);
setFixedHeight(h);
setFixedWidth(std::min(w, r.width() - padding));
} else {
const int w = SNAP_WIDTH + MARGIN * 2;
const int h = SNAP_HEIGHT * count + MARGIN * 2 + SPACING * (count - 1);
setFixedWidth(w);
setFixedHeight(std::min(h, r.height() - padding));
}
}
}
@ -185,7 +184,7 @@ void PreviewContainer::appendSnapWidget(const WId wid)
connect(snap, &AppSnapshot::clicked, this, &PreviewContainer::onSnapshotClicked, Qt::QueuedConnection);
connect(snap, &AppSnapshot::entered, this, &PreviewContainer::previewEntered, Qt::QueuedConnection);
connect(snap, &AppSnapshot::requestCheckWindow, this, &PreviewContainer::requestCheckWindows, Qt::QueuedConnection);
connect(snap, &AppSnapshot::requestCloseAppSnapshot, this, [this](){
connect(snap, &AppSnapshot::requestCloseAppSnapshot, this, [this]() {
if (!m_wmHelper->hasComposite())
return ;
@ -281,7 +280,7 @@ void PreviewContainer::previewEntered(const WId wid)
void PreviewContainer::previewFloating()
{
if(!m_waitForShowPreviewTimer->isActive()){
if (!m_waitForShowPreviewTimer->isActive()) {
m_floatingPreview->setVisible(true);
m_floatingPreview->raise();

View File

@ -67,6 +67,7 @@ public slots:
void showPopupApplet(QWidget *const applet);
void hidePopup();
virtual void setDraging(bool bDrag);
virtual void checkEntry() {}
bool isDragging();
signals:

View File

@ -54,7 +54,6 @@ DCORE_USE_NAMESPACE
DUTIL_USE_NAMESPACE
#endif
const int MAX_STACK_FRAMES = 128;
const QString g_cfgPath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation)[0] + "/dde-cfg.ini";
using namespace std;
@ -64,15 +63,14 @@ bool IsSaveMode()
QSettings settings(g_cfgPath, QSettings::IniFormat);
settings.beginGroup(qApp->applicationName());
int collapseNum = settings.value("collapse").toInt();
// 自动进入安全模式
/* 崩溃次数达到3次进入安全模式不加载插件 */
if (collapseNum >= 3) {
settings.remove(""); // 删除记录的数据
settings.setValue("collapse", 0);
settings.endGroup();
settings.sync();
return true;
}
return false;
}
@ -95,16 +93,38 @@ bool IsSaveMode()
QSettings settings(g_cfgPath, QSettings::IniFormat);
settings.beginGroup("dde-dock");
QDateTime lastDate = QDateTime::fromString(settings.value("lastDate").toString(), "yyyy-MM-dd hh:mm:ss:zzz");
int collapseNum = settings.value("collapse").toInt();
// 10秒以内发生崩溃则累加,记录到文件中
if (qAbs(lastDate.secsTo(QDateTime::currentDateTime())) < 10) {
settings.setValue("collapse", collapseNum + 1);
} else {
settings.setValue("collapse", 0);
/* 第一次崩溃或进入安全模式后的第一次崩溃,将时间重置 */
if (collapseNum == 0) {
settings.setValue("first_time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"));
}
settings.setValue("lastDate", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"));
QDateTime lastDate = QDateTime::fromString(settings.value("first_time").toString(), "yyyy-MM-dd hh:mm:ss:zzz");
/* 将当前崩溃时间与第一次崩溃时间比较小于9分钟记录一次崩溃大于9分钟覆盖之前的崩溃时间 */
if (qAbs(lastDate.secsTo(QDateTime::currentDateTime())) < 9 * 60) {
settings.setValue("collapse", collapseNum + 1);
switch (collapseNum) {
case 0:
settings.setValue("first_time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"));
break;
case 1:
settings.setValue("second_time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"));
break;
case 2:
settings.setValue("third_time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"));
break;
default:
qDebug() << "Error, the collapse is wrong!";
break;
}
} else {
if (collapseNum == 2){
settings.setValue("first_time", settings.value("second_time").toString());
settings.setValue("second_time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"));
} else {
settings.setValue("first_time", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"));
}
}
settings.endGroup();
settings.sync();
@ -128,38 +148,6 @@ bool IsSaveMode()
+ QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss:zzz]")
+ "[crash signal number:" + QString::number(sig) + "]\n";
file->write(head.toUtf8());
#ifdef Q_OS_LINUX
void *array[MAX_STACK_FRAMES];
size_t size = 0;
char **strings = nullptr;
size_t i;
signal(sig, SIG_DFL);
size = static_cast<size_t>(backtrace(array, MAX_STACK_FRAMES));
strings = backtrace_symbols(array, int(size));
for (i = 0; i < size; ++i) {
QString line = QString::number(i) + " " + QString::fromStdString(strings[i]) + "\n";
file->write(line.toUtf8());
std::string symbol(strings[i]);
QString strSymbol = QString::fromStdString(symbol);
int pos1 = strSymbol.indexOf("[");
int pos2 = strSymbol.lastIndexOf("]");
QString address = strSymbol.mid(pos1 + 1,pos2 - pos1 - 1);
// 按照内存地址找到对应代码的行号
QString cmd = "addr2line -C -f -e " + qApp->applicationName() + " " + address;
QProcess *p = new QProcess;
p->setReadChannel(QProcess::StandardOutput);
p->start(cmd);
p->waitForFinished();
p->waitForReadyRead();
file->write(p->readAllStandardOutput());
delete p;
p = nullptr;
}
free(strings);
#endif // __linux
} catch (...) {
//
}
@ -180,7 +168,6 @@ int main(int argc, char *argv[])
DockApplication app(argc, argv);
//崩溃信号
signal(SIGTERM, sig_crash);
signal(SIGSEGV, sig_crash);
signal(SIGILL, sig_crash);
signal(SIGINT, sig_crash);
@ -243,6 +230,9 @@ int main(int argc, char *argv[])
if (!IsSaveMode() && !parser.isSet(disablePlugOption)) {
DockItemManager::instance()->startLoadPlugins();
qApp->setProperty("PLUGINSLOADED", true);
} else {
mw.sendNotifications();
}
return app.exec();

View File

@ -351,6 +351,7 @@ void MainPanelControl::insertItem(int index, DockItem *item)
QTimer::singleShot(0, [ = ] {
updatePluginsLayout();
});
item->checkEntry();
}
void MainPanelControl::removeItem(DockItem *item)
@ -684,8 +685,9 @@ void MainPanelControl::mousePressEvent(QMouseEvent *e)
QWidget::mousePressEvent(e);
}
void MainPanelControl::startDrag(DockItem *item)
void MainPanelControl::startDrag(DockItem *dockItem)
{
QPointer<DockItem> item = dockItem;
const QPixmap pixmap = item->grab();
item->setDraging(true);
@ -699,18 +701,7 @@ void MainPanelControl::startDrag(DockItem *item)
connect(m_appDragWidget, &AppDragWidget::destroyed, this, [ = ] {
m_appDragWidget = nullptr;
});
connect(m_appDragWidget, &AppDragWidget::requestRemoveItem, this, [ = ] {
if (-1 != m_appAreaSonLayout->indexOf(item)) {
m_dragIndex = m_appAreaSonLayout->indexOf(item);
removeItem(item);
}
});
connect(m_appDragWidget, &AppDragWidget::animationFinished, this, [ = ] {
m_appDragWidget = nullptr;
if (qobject_cast<AppItem *>(item)->isValid()) {
if (!item.isNull() && qobject_cast<AppItem *>(item)->isValid()) {
if (-1 == m_appAreaSonLayout->indexOf(item) && m_dragIndex != -1) {
insertItem(m_dragIndex, item);
m_dragIndex = -1;
@ -720,6 +711,13 @@ void MainPanelControl::startDrag(DockItem *item)
}
});
connect(m_appDragWidget, &AppDragWidget::requestRemoveItem, this, [ = ] {
if (-1 != m_appAreaSonLayout->indexOf(item)) {
m_dragIndex = m_appAreaSonLayout->indexOf(item);
removeItem(item);
}
});
appDrag->appDragWidget()->setOriginPos((m_appAreaSonWidget->mapToGlobal(item->pos())));
appDrag->appDragWidget()->setDockInfo(m_position, QRect(mapToGlobal(pos()), size()));
const QPixmap &dragPix = qobject_cast<AppItem *>(item)->appIcon();
@ -1093,8 +1091,10 @@ void MainPanelControl::calcuDockIconSize(int w, int h, PluginsItem *trashPlugin,
if (layout) {
PluginsItem *pItem = static_cast<PluginsItem *>(layout->itemAt(0)->widget());
if (pItem) {
if (pItem->sizeHint().width() == -1) {
if (pItem->sizeHint().height() == -1) {
pItem->setFixedSize(tray_item_size, tray_item_size);
} else if (pItem->sizeHint().height() > height()) {
pItem->resize(pItem->width(), height());
}
}
}
@ -1108,6 +1108,8 @@ void MainPanelControl::calcuDockIconSize(int w, int h, PluginsItem *trashPlugin,
if (pItem) {
if (pItem->sizeHint().width() == -1) {
pItem->setFixedSize(tray_item_size, tray_item_size);
} else if (pItem->sizeHint().width() > width()) {
pItem->resize(width(), pItem->height());
}
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (C) 2018 ~ 2028 Deepin Technology Co., Ltd.
*
* Author: fanpengcheng <fanpengcheng_cm@deepin.com>
@ -207,6 +207,7 @@ void MultiScreenWorker::handleDbusSignal(QDBusMessage msg)
m_screenRawWidth = m_displayInter->screenWidth();
}
}
updateScreenSize();
}
}
@ -735,78 +736,72 @@ void MultiScreenWorker::onRequestUpdateFrontendGeometry()
emit requestUpdateDockEntry();
}
/**
* @brief xcb去设置任务栏的高度_NET_WM_STRUT_PARTIAL属性
*
*/
void MultiScreenWorker::onRequestNotifyWindowManager()
{
static QRect lastRect = QRect();
static int lastScreenWith = 0;
static int lastScreenHeight = 0;
const auto ratio = qApp->devicePixelRatio();
QRect rect;
if (m_hideMode == HideMode::KeepShowing) {
rect = getDockShowGeometry(m_ds.current(), m_position, m_displayMode);
} else {
rect = getDockHideGeometry(m_ds.current(), m_position, m_displayMode);
}
// 已经设置过了,避免重复设置
if (rect == lastRect)
return;
lastRect = rect;
qDebug() << "dock geometry:" << rect;
// 先清除原先的窗管任务栏区域
XcbMisc::instance()->clear_strut_partial(xcb_window_t(parent()->winId()));
// 在副屏时,且为一直显示时,不要挤占应用,这是sp3的新需求
if (m_ds.current() != m_ds.primary() && m_hideMode == HideMode::KeepShowing) {
/* 在非主屏或非一直显示状态时,清除任务栏区域,不挤占应用 */
if (m_ds.current() != m_ds.primary() || m_hideMode != HideMode::KeepShowing) {
lastRect = QRect();
qDebug() << "don`t set dock area";
XcbMisc::instance()->clear_strut_partial(xcb_window_t(parent()->winId()));
return;
}
// 除了"一直显示"模式,其他的都不要设置任务栏区域
if (m_hideMode != Dock::KeepShowing) {
lastRect = QRect();
QRect dockGeometry = getDockShowGeometry(m_ds.current(), m_position, m_displayMode, true);
if (lastRect == dockGeometry && lastScreenWith == m_screenRawWidth && lastScreenHeight == m_screenRawHeight) {
return;
}
lastRect = dockGeometry;
lastScreenWith = m_screenRawWidth;
lastScreenHeight = m_screenRawHeight;
qDebug() << "dock real geometry:" << dockGeometry;
qDebug() << "screen width:" << m_screenRawWidth << ", height:" << m_screenRawHeight;
const QPoint &p = rawXPosition(rect.topLeft());
qDebug() << "dock topLeft position:" << p;
QScreen const *currentScreen = Utils::screenAtByScaled(rect.topLeft());
const qreal ratio = qApp->devicePixelRatio();
XcbMisc::Orientation orientation = XcbMisc::OrientationTop;
uint strut = 0;
uint strutStart = 0;
uint strutEnd = 0;
double strut = 0;
double strutStart = 0;
double strutEnd = 0;
switch (m_position) {
case Position::Top:
orientation = XcbMisc::OrientationTop;
strut = p.y() + rect.height() * ratio;
strutStart = p.x();
strutEnd = qMin(qRound(p.x() + rect.width() * ratio), rect.right());
strut = dockGeometry.y() + dockGeometry.height();
strutStart = dockGeometry.x();
strutEnd = qMin(dockGeometry.x() + dockGeometry.width(), dockGeometry.right());
break;
case Position::Bottom:
orientation = XcbMisc::OrientationBottom;
strut = currentScreen->geometry().height() * ratio - p.y();
strutStart = p.x();
strutEnd = qMin(qRound(p.x() + rect.width() * ratio), rect.right());
strut = m_screenRawHeight - dockGeometry.y();
strutStart = dockGeometry.x();
strutEnd = qMin(dockGeometry.x() + dockGeometry.width(), dockGeometry.right());
break;
case Position::Left:
orientation = XcbMisc::OrientationLeft;
strut = p.x() + rect.width() * ratio;
strutStart = p.y();
strutEnd = qMin(qRound(p.y() + rect.height() * ratio), rect.bottom());
strut = dockGeometry.x() + dockGeometry.width();
strutStart = dockGeometry.y();
strutEnd = qMin(dockGeometry.y() + dockGeometry.height(), dockGeometry.bottom());
break;
case Position::Right:
orientation = XcbMisc::OrientationRight;
strut = currentScreen->geometry().width() * ratio - p.x();
strutStart = p.y();
strutEnd = qMin(qRound(p.y() + rect.height() * ratio), rect.bottom());
strut = m_screenRawWidth - dockGeometry.x();
strutStart = dockGeometry.y();
strutEnd = qMin(dockGeometry.y() + dockGeometry.height(), dockGeometry.bottom());
break;
}
qDebug() << "set dock geometry to xcb:" << strut << strutStart << strutEnd;
XcbMisc::instance()->set_strut_partial(parent()->winId(), orientation, strut + WINDOWMARGIN * ratio, strutStart, strutEnd);
qDebug() << "set reserved area to xcb:" << strut << strutStart << strutEnd;
XcbMisc::instance()->set_strut_partial(static_cast<xcb_window_t>(parent()->winId()), orientation,
static_cast<uint>(strut + WINDOWMARGIN * ratio), // 设置窗口与屏幕边缘距离,需要乘缩放
static_cast<uint>(strutStart), // 设置任务栏起点坐标上下为x左右为y
static_cast<uint>(strutEnd)); // 设置任务栏终点坐标上下为x左右为y
}
void MultiScreenWorker::onRequestUpdatePosition(const Position &fromPos, const Position &toPos)
@ -1092,6 +1087,7 @@ void MultiScreenWorker::initDBus()
m_screenRawWidth = m_displayInter->screenWidth();
m_ds = DockScreen(m_displayInter->primary());
m_mtrInfo.setPrimary(m_displayInter->primary());
updateScreenSize();
}
}
@ -1550,82 +1546,47 @@ MainWindow *MultiScreenWorker::parent()
return static_cast<MainWindow *>(m_parent);
}
/**
* @brief
*
* @param screenName
* @param pos
* @param displaymode
* @param withoutScale true:; false:()
* @return QRect
*/
QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale)
{
//!!! 注意,目前双屏情况下缩放保持一致,不会出现两个屏幕的缩放不一致的情况,如果后面出现了,那么这里可能会有问题
const qreal scale = qApp->devicePixelRatio();
QRect rect;
if (withoutScale) {//后端真实大小
foreach (Monitor *inter, m_mtrInfo.validMonitor()) {
if (inter->name() == screenName) {
// windowSizeFashion和windowSizeEfficient给出的值始终对应前端认为的界面高度或宽度受缩放影响
const int dockSize = int(displaymode == DisplayMode::Fashion ? m_dockInter->windowSizeFashion() : m_dockInter->windowSizeEfficient()) * scale;
switch (static_cast<Position>(pos)) {
case Top: {
rect.setX(inter->x() + WINDOWMARGIN);
rect.setY(inter->y() + WINDOWMARGIN);
rect.setWidth(inter->w() - 2 * WINDOWMARGIN);
rect.setHeight(dockSize);
}
const double ratio = withoutScale ? 1 : qApp->devicePixelRatio();
const int margin = static_cast<int>((displaymode == DisplayMode::Fashion ? 10 : 0) * (withoutScale ? qApp->devicePixelRatio() : 1));
const int dockSize = static_cast<int>((displaymode == DisplayMode::Fashion ? m_dockInter->windowSizeFashion() : m_dockInter->windowSizeEfficient()) * (withoutScale ? qApp->devicePixelRatio() : 1));
for (Monitor *monitor : m_mtrInfo.validMonitor()) {
if (monitor->name() == screenName) {
switch (pos) {
case Position::Top:
rect.setX(static_cast<int>(monitor->x() + margin));
rect.setY(static_cast<int>(monitor->y() + margin));
rect.setWidth(static_cast<int>(monitor->w() / ratio - 2 * margin));
rect.setHeight(dockSize);
break;
case Bottom: {
rect.setX(inter->x() + WINDOWMARGIN);
rect.setY(inter->y() + inter->h() - WINDOWMARGIN - dockSize);
rect.setWidth(inter->w() - 2 * WINDOWMARGIN);
rect.setHeight(dockSize);
}
case Position::Bottom:
rect.setX(static_cast<int>(monitor->x() + margin));
rect.setY(static_cast<int>(monitor->y() + monitor->h() / ratio - margin - dockSize));
rect.setWidth(static_cast<int>(monitor->w() / ratio - 2 * margin));
rect.setHeight(dockSize);
break;
case Left: {
rect.setX(inter->x() + WINDOWMARGIN);
rect.setY(inter->y() + WINDOWMARGIN);
rect.setWidth(dockSize);
rect.setHeight(inter->h() - 2 * WINDOWMARGIN);
}
case Position::Left:
rect.setX(static_cast<int>(monitor->x() + margin));
rect.setY(static_cast<int>(monitor->y() + margin));
rect.setWidth(dockSize);
rect.setHeight(static_cast<int>(monitor->h() / ratio - 2 * margin));
break;
case Right: {
rect.setX(inter->x() + inter->w() - WINDOWMARGIN - dockSize);
rect.setY(inter->y() + WINDOWMARGIN);
rect.setWidth(dockSize);
rect.setHeight(inter->h() - 2 * WINDOWMARGIN);
}
}
break;
}
}
} else {//前端真实大小
foreach (Monitor *inter, m_mtrInfo.validMonitor()) {
if (inter->name() == screenName) {
// windowSizeFashion和windowSizeEfficient给出的值始终对应前端认为的界面高度或宽度受缩放影响
const int dockSize = int(displaymode == DisplayMode::Fashion ? m_dockInter->windowSizeFashion() : m_dockInter->windowSizeEfficient());
switch (static_cast<Position>(pos)) {
case Top: {
rect.setX(inter->x() + WINDOWMARGIN);
rect.setY(inter->y() + WINDOWMARGIN);
rect.setWidth(inter->w() / scale - 2 * WINDOWMARGIN);
rect.setHeight(dockSize);
}
break;
case Bottom: {
rect.setX(inter->x() + WINDOWMARGIN);
rect.setY(inter->y() + inter->h() / scale - WINDOWMARGIN - dockSize);
rect.setWidth(inter->w() / scale - 2 * WINDOWMARGIN);
rect.setHeight(dockSize);
}
break;
case Left: {
rect.setX(inter->x() + WINDOWMARGIN);
rect.setY(inter->y() + WINDOWMARGIN);
rect.setWidth(dockSize);
rect.setHeight(inter->h() / scale - 2 * WINDOWMARGIN);
}
break;
case Right: {
rect.setX(inter->x() + inter->w() / scale - WINDOWMARGIN - dockSize);
rect.setY(inter->y() + WINDOWMARGIN);
rect.setWidth(dockSize);
rect.setHeight(inter->h() / scale - 2 * WINDOWMARGIN);
}
}
case Position::Right:
rect.setX(static_cast<int>(monitor->x() + monitor->w() / ratio - margin - dockSize));
rect.setY(static_cast<int>(monitor->y() + margin));
rect.setWidth(dockSize);
rect.setHeight(static_cast<int>(monitor->h() / ratio - 2 * margin));
break;
}
}
@ -1633,83 +1594,47 @@ QRect MultiScreenWorker::getDockShowGeometry(const QString &screenName, const Po
return rect;
}
/**
* @brief
*
* @param screenName
* @param pos
* @param displaymode
* @param withoutScale true:; false:()
* @return QRect
*/
QRect MultiScreenWorker::getDockHideGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale)
{
//!!! 注意,目前双屏情况下缩放保持一致,不会出现两个屏幕的缩放不一致的情况,如果后面出现了,那么这里可能会有问题
const qreal scale = qApp->devicePixelRatio();
QRect rect;
if (withoutScale) {//后端真实大小
foreach (Monitor *inter, m_mtrInfo.validMonitor()) {
if (inter->name() == screenName) {
const int margin = (displaymode == DisplayMode::Fashion ? WINDOWMARGIN : 0);
switch (static_cast<Position>(pos)) {
case Top: {
rect.setX(inter->x() + margin);
rect.setY(inter->y());
rect.setWidth(inter->w() - 2 * margin);
rect.setHeight(0);
}
const double ratio = withoutScale ? 1 : qApp->devicePixelRatio();
const int margin = static_cast<int>((displaymode == DisplayMode::Fashion ? 10 : 0) * (withoutScale ? qApp->devicePixelRatio() : 1));
for (Monitor *monitor : m_mtrInfo.validMonitor()) {
if (monitor->name() == screenName) {
switch (pos) {
case Position::Top:
rect.setX(static_cast<int>(monitor->x() + margin));
rect.setY(static_cast<int>(monitor->y() + margin));
rect.setWidth(static_cast<int>(monitor->w() / ratio - 2 * margin));
rect.setHeight(0);
break;
case Bottom: {
rect.setX(inter->x() + margin);
rect.setY(inter->y() + inter->h());
rect.setWidth(inter->w() - 2 * margin);
rect.setHeight(0);
}
case Position::Bottom:
rect.setX(static_cast<int>(monitor->x() + margin));
rect.setY(static_cast<int>(monitor->y() + monitor->h() / ratio - margin));
rect.setWidth(static_cast<int>(monitor->w() / ratio - 2 * margin));
rect.setHeight(0);
break;
case Left: {
rect.setX(inter->x());
rect.setY(inter->y() + margin);
rect.setWidth(0);
rect.setHeight(inter->h() - 2 * margin);
}
case Position::Left:
rect.setX(static_cast<int>(monitor->x() + margin));
rect.setY(static_cast<int>(monitor->y() + margin));
rect.setWidth(0);
rect.setHeight(static_cast<int>(monitor->h() / ratio - 2 * margin));
break;
case Right: {
rect.setX(inter->x() + inter->w());
rect.setY(inter->y() + margin);
rect.setWidth(0);
rect.setHeight(inter->h() - 2 * margin);
}
case Position::Right:
rect.setX(static_cast<int>(monitor->x() + monitor->w() / ratio - margin));
rect.setY(static_cast<int>(monitor->y() + margin));
rect.setWidth(0);
rect.setHeight(static_cast<int>(monitor->h() / ratio - 2 * margin));
break;
}
}
}
} else {//前端真实大小
foreach (Monitor *inter, m_mtrInfo.validMonitor()) {
if (inter->name() == screenName) {
const int margin = (displaymode == DisplayMode::Fashion ? WINDOWMARGIN : 0);
switch (static_cast<Position>(pos)) {
case Top: {
rect.setX(inter->x() + margin);
rect.setY(inter->y());
rect.setWidth(inter->w() / scale - 2 * margin);
rect.setHeight(0);
}
break;
case Bottom: {
rect.setX(inter->x() + margin);
rect.setY(inter->y() + inter->h() / scale);
rect.setWidth(inter->w() / scale - 2 * margin);
rect.setHeight(0);
}
break;
case Left: {
rect.setX(inter->x());
rect.setY(inter->y() + margin);
rect.setWidth(0);
rect.setHeight(inter->h() / scale - 2 * margin);
}
break;
case Right: {
rect.setX(inter->x() + inter->w() / scale);
rect.setY(inter->y() + margin);
rect.setWidth(0);
rect.setHeight(inter->h() / scale - 2 * margin);
}
break;
}
}
}
}
@ -1795,6 +1720,40 @@ const QPoint MultiScreenWorker::rawXPosition(const QPoint &scaledPos)
: scaledPos;
}
/**
* @brief xcb
* display
* display
*/
void MultiScreenWorker::updateScreenSize()
{
/* Open the connection to the X server. Use the DISPLAY environment variable */
int screenNum;
xcb_connection_t *connection = xcb_connect(NULL, &screenNum);
/* Check for failure */
if (xcb_connection_has_error(connection)) {
xcb_disconnect(connection);
return;
}
/* Get the screen whose number is screenNum */
const xcb_setup_t *setup = xcb_get_setup(connection);
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
/* we want the screen at index screenNum of the iterator */
for (int i = 0; i < screenNum; ++i) {
xcb_screen_next(&iter);
}
xcb_screen_t *screen = iter.data;
m_screenRawWidth = screen->width_in_pixels;
m_screenRawHeight = screen->height_in_pixels;
xcb_disconnect(connection);
}
void MultiScreenWorker::onTouchPress(int type, int x, int y, const QString &key)
{
Q_UNUSED(type);

View File

@ -436,14 +436,7 @@ private:
void checkXEventMonitorService();
MainWindow *parent();
/**
* @brief getDockShowGeometry
* @param screenName
* @param pos
* @param displaymode
* @param real ,false为计算,true为不计算(.,)
* @return
*/
QRect getDockShowGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale = false);
QRect getDockHideGeometry(const QString &screenName, const Position &pos, const DisplayMode &displaymode, bool withoutScale = false);
@ -454,6 +447,7 @@ private:
bool contains(const MonitRect &rect, const QPoint &pos);
bool contains(const QList<MonitRect> &rectList, const QPoint &pos);
const QPoint rawXPosition(const QPoint &scaledPos);
void updateScreenSize();
private:
QWidget *m_parent;
@ -490,7 +484,7 @@ private:
//当前屏幕的方向
int m_monitorRotation;
//当前屏幕的所有方向
RotationList m_rotations;
RotationList m_rotations; // 逆时针旋转(向下,向右,向上,向左)
/***************不和其他流程产生交互,尽量不要动这里的变量***************/
int m_screenRawHeight;

View File

@ -187,6 +187,16 @@ void MainWindow::callShow()
});
}
void MainWindow::relaodPlugins()
{
if (qApp->property("PLUGINSLOADED").toBool()) {
return;
}
DockItemManager::instance()->startLoadPlugins();
qApp->setProperty("PLUGINSLOADED", true);
}
void MainWindow::showEvent(QShowEvent *e)
{
QWidget::showEvent(e);
@ -371,6 +381,7 @@ void MainWindow::adjustShadowMask()
}
m_platformWindowHandle.setWindowRadius(radius);
m_mainPanel->updatePluginsLayout();
}
void MainWindow::onDbusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
@ -557,13 +568,38 @@ void MainWindow::touchRequestResizeDock()
void MainWindow::setGeometry(const QRect &rect)
{
static QRect lastRect;
if (lastRect == rect) {
if (rect == this->geometry()) {
return;
}
lastRect = rect;
DBlurEffectWidget::setGeometry(rect);
emit panelGeometryChanged();
}
/**
* @brief
*/
void MainWindow::sendNotifications()
{
QStringList actionButton;
actionButton << "reload" << tr("Exit Safe Mode");
QVariantMap hints;
hints["x-deepin-action-reload"] = QString("dbus-send,--session,--dest=com.deepin.dde.Dock,--print-reply,/com/deepin/dde/Dock,com.deepin.dde.Dock.ReloadPlugins");
QTimer::singleShot(0, this, [=] {
DDBusSender()
.service("com.deepin.dde.Notification")
.path("/com/deepin/dde/Notification")
.interface("com.deepin.dde.Notification")
.method(QString("Notify"))
.arg(QString("dde-control-center")) // appname
.arg(static_cast<uint>(0)) // id
.arg(QString("preferences-system")) // icon
.arg(QString(tr("Dock - Safe Mode"))) // summary
.arg(QString(tr("The Dock is in safe mode, please exit to show it properly"))) // content
.arg(actionButton) // actions
.arg(hints) // hints
.arg(15000) // timeout
.call();
});
}
#include "mainwindow.moc"

View File

@ -122,6 +122,7 @@ public:
void setEffectEnabled(const bool enabled);
void setComposite(const bool hasComposite);
void setGeometry(const QRect &rect);
void sendNotifications();
friend class MainPanel;
friend class MainPanelControl;
@ -131,6 +132,7 @@ public:
public slots:
void launch();
void callShow();
void relaodPlugins();
private:
using QWidget::show;

View File

@ -24,6 +24,7 @@
#include "componments/adapter.h"
#include "bluetoothapplet.h"
#include "bluetoothconstants.h"
#include "refreshbutton.h"
#include <QBoxLayout>
#include <QStandardItemModel>
@ -121,6 +122,7 @@ BluetoothAdapterItem::BluetoothAdapterItem(Adapter *adapter, QWidget *parent)
, m_adapterStateBtn(new DSwitchButton(this))
, m_deviceListview(new DListView(this))
, m_deviceModel(new QStandardItemModel(m_deviceListview))
, m_refreshBtn(new RefreshButton(this))
{
initData();
initUi();
@ -162,6 +164,15 @@ void BluetoothAdapterItem::onAdapterNameChanged(const QString name)
m_adapterLabel->label()->setText(name);
}
void BluetoothAdapterItem::updateIconTheme(DGuiApplicationHelper::ColorType type)
{
if (type == DGuiApplicationHelper::LightType) {
m_refreshBtn->setRotateIcon(":/wireless/resources/wireless/refresh_dark.svg");
} else {
m_refreshBtn->setRotateIcon(":/wireless/resources/wireless/refresh.svg");
}
}
int BluetoothAdapterItem::currentDeviceCount()
{
return m_deviceItems.size();
@ -222,10 +233,14 @@ void BluetoothAdapterItem::onDeviceRemoved(const Device *device)
void BluetoothAdapterItem::initUi()
{
m_refreshBtn->setFixedSize(24, 24);
m_refreshBtn->setVisible(m_adapter->powered());
setAccessibleName(m_adapter->name());
setContentsMargins(0, 0, 0, 0);
m_adapterLabel->setFixedSize(ItemWidth, TitleHeight);
m_adapterLabel->addSwichButton(m_adapterStateBtn);
m_adapterLabel->addButton(m_refreshBtn, 0);
m_adapterLabel->addButton(m_adapterStateBtn, 10);
DFontSizeManager::instance()->bind(m_adapterLabel->label(), DFontSizeManager::T4);
m_adapterStateBtn->setChecked(m_adapter->powered());
@ -250,16 +265,35 @@ void BluetoothAdapterItem::initUi()
mainLayout->addWidget(m_adapterLabel);
mainLayout->addSpacing(2);
mainLayout->addWidget(m_deviceListview);
updateIconTheme(DGuiApplicationHelper::instance()->themeType());
if (m_adapter->discover()) {
m_refreshBtn->startRotate();
}
}
void BluetoothAdapterItem::initConnect()
{
connect(DApplicationHelper::instance(), &DApplicationHelper::themeTypeChanged, this, &BluetoothAdapterItem::updateIconTheme);
connect(m_adapter, &Adapter::deviceAdded, this, &BluetoothAdapterItem::onDeviceAdded);
connect(m_adapter, &Adapter::deviceRemoved, this, &BluetoothAdapterItem::onDeviceRemoved);
connect(m_adapter, &Adapter::nameChanged, this, &BluetoothAdapterItem::onAdapterNameChanged);
connect(m_deviceListview, &DListView::clicked, this, &BluetoothAdapterItem::onConnectDevice);
connect(m_adapter, &Adapter::discoveringChanged, this, [ = ] (bool state) {
if (state) {
m_refreshBtn->startRotate();
} else {
m_refreshBtn->stopRotate();
}
});
connect(m_refreshBtn, &RefreshButton::clicked, this, [ = ] {
emit requestRefreshAdapter(m_adapter);
});
connect(m_adapter, &Adapter::poweredChanged, this, [ = ] (bool state) {
initData();
m_refreshBtn->setVisible(state);
m_deviceListview->setVisible(state);
m_adapterStateBtn->setChecked(state);
m_adapterStateBtn->setEnabled(true);
@ -271,6 +305,7 @@ void BluetoothAdapterItem::initConnect()
m_deviceModel->clear();
m_deviceListview->setVisible(false);
m_adapterStateBtn->setEnabled(false);
m_refreshBtn->setVisible(state);
emit requestSetAdapterPower(m_adapter, state);
});
}

View File

@ -42,6 +42,7 @@ DWIDGET_END_NAMESPACE
class Adapter;
class SettingLabel;
class QStandardItemModel;
class RefreshButton;
const QString LightString = QString(":/light/buletooth_%1_light.svg");
const QString DarkString = QString(":/dark/buletooth_%1_dark.svg");
@ -101,10 +102,12 @@ public slots:
void onTopDeviceItem(DStandardItem* item);
// 设置蓝牙适配器名称
void onAdapterNameChanged(const QString name);
void updateIconTheme(DGuiApplicationHelper::ColorType type);
signals:
void adapterPowerChanged();
void requestSetAdapterPower(Adapter *adapter, bool state);
void requestRefreshAdapter(Adapter *adapter);
void connectDevice(const Device *device, Adapter *adapter);
void deviceCountChanged();
void deviceStateChanged(const Device* device);
@ -119,6 +122,7 @@ private:
DSwitchButton *m_adapterStateBtn = nullptr;
DListView *m_deviceListview = nullptr;
QStandardItemModel *m_deviceModel = nullptr;
RefreshButton *m_refreshBtn = nullptr;
QMap<QString, BluetoothDeviceItem *> m_deviceItems;
};

View File

@ -50,12 +50,13 @@ SettingLabel::SettingLabel(QString text, QWidget *parent)
m_layout->setMargin(0);
m_layout->addSpacing(20);
m_layout->addWidget(m_label, 0, Qt::AlignLeft | Qt::AlignHCenter);
m_layout->addStretch();
}
void SettingLabel::addSwichButton(DSwitchButton *button)
void SettingLabel::addButton(QWidget *button, int space)
{
m_layout->addWidget(button, 0, Qt::AlignRight | Qt::AlignHCenter);
m_layout->addSpacing(10);
m_layout->addSpacing(space);
}
void SettingLabel::mousePressEvent(QMouseEvent *ev)
@ -153,6 +154,7 @@ void BluetoothApplet::onAdapterAdded(Adapter *adapter)
connect(adapterItem, &BluetoothAdapterItem::deviceCountChanged, this, &BluetoothApplet::updateSize);
connect(adapterItem, &BluetoothAdapterItem::adapterPowerChanged, this, &BluetoothApplet::updateBluetoothPowerState);
connect(adapterItem, &BluetoothAdapterItem::deviceStateChanged, this, &BluetoothApplet::deviceStateChanged);
connect(adapterItem, &BluetoothAdapterItem::requestRefreshAdapter, m_adaptersManager, &AdaptersManager::adapterRefresh);
m_adapterItems.insert(adapter->id(), adapterItem);
m_contentLayout->insertWidget(0, adapterItem, Qt::AlignTop | Qt::AlignVCenter);

View File

@ -49,7 +49,7 @@ class SettingLabel : public QWidget
Q_OBJECT
public:
explicit SettingLabel(QString text, QWidget *parent = nullptr);
void addSwichButton(DSwitchButton *button);
void addButton(QWidget *button, int space);
DLabel *label() { return m_label; }
signals:
void clicked();

View File

@ -0,0 +1,73 @@
#include "refreshbutton.h"
#include <QTimer>
#include <QPainter>
#include <QIcon>
#include <QMouseEvent>
#include <QPropertyAnimation>
#include <QDebug>
RefreshButton::RefreshButton(QWidget *parent)
: QWidget(parent)
, m_refreshTimer(new QTimer(this))
, m_rotateAngle(0)
{
setAccessibleName("RefreshButton");
m_refreshTimer->setInterval(500 / 60);
initConnect();
}
void RefreshButton::setRotateIcon(QString path)
{
m_pixmap = QIcon(path).pixmap(size());
}
void RefreshButton::startRotate()
{
m_refreshTimer->start();
if (m_rotateAngle == 360) {
m_rotateAngle = 0;
}
m_rotateAngle += 360 / 60;
update();
}
void RefreshButton::stopRotate()
{
m_refreshTimer->stop();
m_rotateAngle = 0;
update();
}
void RefreshButton::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::NoBrush);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.translate(this->width() / 2, this->height() / 2);
painter.rotate(m_rotateAngle);
painter.translate(-(this->width() / 2), -(this->height() / 2));
painter.drawPixmap(this->rect(), m_pixmap);
QWidget::paintEvent(e);
}
void RefreshButton::mousePressEvent(QMouseEvent *event)
{
m_pressPos = event->pos();
return QWidget::mousePressEvent(event);
}
void RefreshButton::mouseReleaseEvent(QMouseEvent *event)
{
if (rect().contains(m_pressPos) && rect().contains(event->pos()) && !m_refreshTimer->isActive())
Q_EMIT clicked();
return QWidget::mouseReleaseEvent(event);
}
void RefreshButton::initConnect()
{
connect(m_refreshTimer, &QTimer::timeout, this, &RefreshButton::startRotate);
}

View File

@ -0,0 +1,34 @@
#ifndef REFRESHBUTTON_H
#define REFRESHBUTTON_H
#include <QWidget>
class QTimer;
class RefreshButton : public QWidget
{
Q_OBJECT
public:
explicit RefreshButton(QWidget *parent = nullptr);
void setRotateIcon(QString path);
void startRotate();
void stopRotate();
signals:
void clicked();
protected:
void paintEvent(QPaintEvent *e) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
private:
void initConnect();
QTimer *m_refreshTimer;
QPixmap m_pixmap;
QPoint m_pressPos;
int m_rotateAngle;
};
#endif // REFRESHBUTTON_H

View File

@ -477,9 +477,9 @@ void NetworkItem::wiredsEnable(bool enable)
for (auto wiredItem : m_wiredItems) {
if (wiredItem) {
wiredItem->setDeviceEnabled(enable);
wiredItem->setVisible(enable);
}
}
// updateSelf();
}
void NetworkItem::wirelessEnable(bool enable)
@ -492,7 +492,6 @@ void NetworkItem::wirelessEnable(bool enable)
wirelessItem->itemApplet()->setVisible(enable);
}
}
updateSelf();
}
void NetworkItem::onThemeTypeChanged(DGuiApplicationHelper::ColorType themeType)
@ -1113,49 +1112,65 @@ int NetworkItem::getStrongestAp()
return retStrength;
}
/**
* @brief 线线
*/
void NetworkItem::updateMasterControlSwitch()
{
bool deviceState = false;
for (auto wirelessItem : m_wirelessItems) {
if (wirelessItem)
if (wirelessItem->deviceEanbled()) {
deviceState = true;
break;
}
}
m_switchWirelessBtn->blockSignals(true);
m_switchWirelessBtn->setChecked(deviceState);
m_loadingIndicator->setVisible(deviceState);
m_switchWirelessBtn->blockSignals(false);
if (deviceState) {
for (auto wirelessItem : m_wirelessItems) {
if (wirelessItem) {
m_wirelessLayout->addWidget(wirelessItem->itemApplet());
wirelessItem->itemApplet()->setVisible(true);
}
}
} else {
for (auto wirelessItem : m_wirelessItems) {
if (wirelessItem) {
m_wirelessLayout->removeWidget(wirelessItem->itemApplet());
wirelessItem->itemApplet()->setVisible(false);
}
}
}
m_switchWirelessBtnState = deviceState;
m_switchWiredBtnState = false;
m_switchWirelessBtnState = false;
deviceState = false;
for (auto wiredItem : m_wiredItems) {
if (wiredItem)
if (wiredItem->deviceEabled()) {
deviceState = true;
break;
}
/* 获取有线适配器启用状态 */
for (WiredItem *wiredItem : m_wiredItems) {
if (wiredItem && wiredItem->deviceEabled()) {
m_switchWiredBtnState = wiredItem->deviceEabled();
break;
}
}
/* 更新有线适配器总开关状态(阻塞信号是为了防止重复设置适配器启用状态)*/
m_switchWiredBtn->blockSignals(true);
m_switchWiredBtn->setChecked(deviceState);
m_switchWiredBtn->setChecked(m_switchWiredBtnState);
m_switchWiredBtn->blockSignals(false);
m_switchWiredBtnState = deviceState;
/* 根据有线适配器启用状态增/删布局中的组件 */
for (WiredItem *wiredItem : m_wiredItems) {
if (!wiredItem) {
continue;
}
if (m_switchWiredBtnState) {
m_wiredLayout->addWidget(wiredItem->itemApplet());
} else {
m_wiredLayout->removeWidget(wiredItem->itemApplet());
}
// wiredItem->itemApplet()->setVisible(m_switchWiredBtnState); // TODO
wiredItem->setVisible(m_switchWiredBtnState);
}
/* 获取无线适配器启用状态 */
for (auto wirelessItem : m_wirelessItems) {
if (wirelessItem && wirelessItem->deviceEanbled()) {
m_switchWirelessBtnState = wirelessItem->deviceEanbled();
break;
}
}
/* 更新无线适配器总开关状态(阻塞信号是为了防止重复设置适配器启用状态) */
m_switchWirelessBtn->blockSignals(true);
m_switchWirelessBtn->setChecked(m_switchWirelessBtnState);
m_switchWirelessBtn->blockSignals(false);
/* 根据无线适配器启用状态增/删布局中的组件 */
for (WirelessItem *wirelessItem : m_wirelessItems) {
if (!wirelessItem) {
continue;
}
if (m_switchWirelessBtnState) {
m_wirelessLayout->addWidget(wirelessItem->itemApplet());
} else {
m_wirelessLayout->removeWidget(wirelessItem->itemApplet());
}
wirelessItem->itemApplet()->setVisible(m_switchWirelessBtnState);
wirelessItem->setVisible(m_switchWirelessBtnState);
}
m_loadingIndicator->setVisible(m_switchWirelessBtnState || m_switchWiredBtnState);
}
void NetworkItem::refreshTips()
@ -1220,7 +1235,7 @@ void NetworkItem::refreshTips()
const QJsonObject ipv4 = info.value("Ip4").toObject();
if (!ipv4.contains("Address"))
continue;
if (m_connectedWiredDevice.size() == 1) {
if (m_connectedWirelessDevice.size() == 1) {
strTips = tr("Wireless connection: %1").arg(ipv4.value("Address").toString()) + '\n';
} else {
strTips = tr("Wireless Network").append(QString("%1").arg(wirelessIndex++)).append(":"+ipv4.value("Address").toString()) + '\n';

View File

@ -80,7 +80,7 @@ QSize PopupControlWidget::sizeHint() const
void PopupControlWidget::openTrashFloder()
{
QProcess::startDetached("gio", QStringList() << "open" << "trash:///");
DDesktopServices::showFolder(QUrl("trash:///"));
}
void PopupControlWidget::clearTrashFloder()

View File

@ -28,6 +28,7 @@
#include "../../widgets/tipswidget.h"
#include <DApplication>
#include <DDesktopServices>
#define PLUGIN_STATE_KEY "enable"
@ -110,9 +111,10 @@ QWidget *TrashPlugin::itemPopupApplet(const QString &itemKey)
const QString TrashPlugin::itemCommand(const QString &itemKey)
{
Q_UNUSED(itemKey);
DDesktopServices::showFolder(QUrl("trash:///"));
// return QString();
return "gio open trash:///";
return QString();
// return "gio open trash:///";
}
const QString TrashPlugin::itemContextMenu(const QString &itemKey)

View File

@ -1,4 +1,6 @@
<?xml version="1.0" ?><!DOCTYPE TS><TS language="en" version="2.1">
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en">
<context>
<name>AbstractPluginsController</name>
<message>
@ -151,6 +153,21 @@
<translation>Launcher</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>
@ -488,4 +505,4 @@
<translation>Wireless Network %1</translation>
</message>
</context>
</TS>
</TS>

View File

@ -151,6 +151,21 @@
<translation>المُطلق</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Başladıcı</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation></translation>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation></translation>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation> </translation>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Llançador</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Spouštěč</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Programstarter</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Starter</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Launcher</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Lanzador</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>لانچر</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Käynnistin</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Lanceur</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Lanzador</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation> </translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Pokretač</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Indító</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Launcher</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Leistukas</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Pelancar</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Programmastarter</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Launcher</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Lançador</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Lançador</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Lansator</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Выбор Программ</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation> </translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Spúšťač</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Zaganjalnik</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Nisës</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Покретач Програма</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Başlatıcı</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>ئۈستەليۈزى قوزغاتقۇچ</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Запускач</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation>Вийти з безпечного режиму</translation>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation>Док-станція безпечний режим</translation>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation>Док-станція перебуває у безпечному режимі будь ласка, вийдіть з нього для належного показу</translation>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation>Khởi chạy</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation type="unfinished"/>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation>退</translation>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation></translation>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation>退</translation>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation>退</translation>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation></translation>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation>退</translation>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>

View File

@ -151,6 +151,21 @@
<translation></translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<source>Exit Safe Mode</source>
<translation>退</translation>
</message>
<message>
<source>Dock - Safe Mode</source>
<translation></translation>
</message>
<message>
<source>The Dock is in safe mode, please exit to show it properly</source>
<translation>退</translation>
</message>
</context>
<context>
<name>MenuWorker</name>
<message>