From ea657469f3e9761fb0b970c5061bd2da546c29c4 Mon Sep 17 00:00:00 2001 From: SimplestStudio Date: Wed, 20 Dec 2023 10:32:23 +0200 Subject: [PATCH 1/7] [win-linux] ctabar: refactoring --- win-linux/src/components/ctabbar.cpp | 70 ++++++++++++---------------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/win-linux/src/components/ctabbar.cpp b/win-linux/src/components/ctabbar.cpp index a54d1ebf6..40a0856c4 100644 --- a/win-linux/src/components/ctabbar.cpp +++ b/win-linux/src/components/ctabbar.cpp @@ -54,6 +54,7 @@ #define tabIndex(i) tabList[i]->index #define signum(a) (a ? 1 : -1); #define PROCESSEVENTS() AscAppManager::getInstance().processEvents() +#define SKIP_EVENTS_QUEUE(callback) QTimer::singleShot(0, this, callback) class Tab : public QFrame @@ -269,7 +270,7 @@ void Tab::resizeEvent(QResizeEvent *event) } else { if (tab_width != new_width) { tab_width = new_width; - QTimer::singleShot(0, this, [=]() { + SKIP_EVENTS_QUEUE([=]() { emit onTabWidthChanged(tab_width); }); } @@ -316,6 +317,7 @@ class CTabBar::CTabBarPrivate Left, Right }; + Tab* createTab(int posX, const QString &text); int getIntersectedOffset(int index); int getIntersectedIndex(int direction, int &offsetX); int getLayoutsIntersectedIndex(Tab *tab, int &offsetX); @@ -362,6 +364,28 @@ CTabBar::CTabBarPrivate::CTabBarPrivate(CTabBar* owner) : CTabBar::CTabBarPrivate::~CTabBarPrivate() {} +Tab* CTabBar::CTabBarPrivate::createTab(int posX, const QString &text) +{ + Tab *tab = new Tab(tabArea); + tab->move(posX, 0); + tab->setFixedHeight(tabArea->height()); + tab->setText(text, elideMode); + if (tab->icon_label->minimumSize().isNull()) { + tab->icon_label->setBaseSize(iconSize); + tab->icon_label->setFixedSize(iconSize); + } + connect(tab->close_btn, &QToolButton::clicked, tab, [=]() { + emit owner->tabCloseRequested(tab->index); + }); + connect(tab, &Tab::onTabWidthChanged, tab, [=](int width) { + if (tab_width != width) { + tab_width = width; + onTabWidthChanged(width); + } + }); + return tab; +} + int CTabBar::CTabBarPrivate::getIntersectedOffset(int index) { if (indexIsValid(index)) { @@ -635,25 +659,9 @@ int CTabBar::addTab(const QString &text) const int lastIndex = d->tabList.size() - 1; const int posX = (lastIndex == -1) ? 0 : d->nextTabPosByPrev(lastIndex); - Tab *tab = new Tab(d->tabArea); - tab->move(posX, 0); - tab->setFixedHeight(d->tabArea->height()); - tab->setText(text, d->elideMode); - if (tab->icon_label->minimumSize().isNull()) { - tab->icon_label->setBaseSize(d->iconSize); - tab->icon_label->setFixedSize(d->iconSize); - } + Tab *tab = d->createTab(posX, text); tab->index = lastIndex + 1; d->tabList.append(tab); - connect(tab->close_btn, &QToolButton::clicked, this, [=]() { - emit tabCloseRequested(tab->index); - }); - connect(tab, &Tab::onTabWidthChanged, this, [=](int width) { - if (d->tab_width != width) { - d->tab_width = width; - d->onTabWidthChanged(width); - } - }); tabInserted(lastIndex + 1); d->onCurrentChanged(lastIndex + 1); return d->currentIndex; @@ -694,35 +702,15 @@ int CTabBar::insertTab(int index, const QString &text) if (!d->indexIsValid(index)) return addTab(text); - while (d->animationInProgress) - PROCESSEVENTS(); - int posX = d->_tabRect(index).left(); d->slide(index, d->tabList.size() - 1, d->cellWidth(), ANIMATION_DEFAULT_MS); while (d->animationInProgress) PROCESSEVENTS(); - Tab *tab = new Tab(d->tabArea); - tab->move(posX, 0); - tab->setFixedHeight(d->tabArea->height()); - tab->setText(text, d->elideMode); - if (tab->icon_label->minimumSize().isNull()) { - tab->icon_label->setBaseSize(d->iconSize); - tab->icon_label->setFixedSize(d->iconSize); - } + Tab *tab = d->createTab(posX, text); d->tabList.insert(index, tab); for (int i = index; i < d->tabList.size(); i++) d->tabIndex(i) = i; - - connect(tab->close_btn, &QToolButton::clicked, this, [=]() { - emit tabCloseRequested(tab->index); - }); - connect(tab, &Tab::onTabWidthChanged, this, [=](int width) { - if (d->tab_width != width) { - d->tab_width = width; - d->onTabWidthChanged(width); - } - }); tabInserted(index); d->onCurrentChanged(index); return d->currentIndex; @@ -863,7 +851,7 @@ void CTabBar::setTabIcon(int index, const QIcon &icon) void CTabBar::setTabText(int index, const QString &text) { if (d->indexIsValid(index)) - d->tabList[index]->setText(text); + d->tabList[index]->setText(text, d->elideMode); } void CTabBar::setTabToolTip(int index, const QString &text) @@ -1097,7 +1085,7 @@ bool CTabBar::eventFilter(QObject *watched, QEvent *event) d->movedTab->hide(); d->movedTab = nullptr; d->movedTabIndex = -1; - QTimer::singleShot(0, this, [=]() { + SKIP_EVENTS_QUEUE([=]() { removeTab(d->currentIndex); while (d->animationInProgress) PROCESSEVENTS(); From 2ad2aee4530621042809ee1cbe824a1f6d0bb0f2 Mon Sep 17 00:00:00 2001 From: SimplestStudio Date: Wed, 20 Dec 2023 10:32:56 +0200 Subject: [PATCH 2/7] [win-linux] ceditorwindow: debug --- win-linux/src/windows/ceditorwindow_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/win-linux/src/windows/ceditorwindow_p.h b/win-linux/src/windows/ceditorwindow_p.h index ce628b435..ee5be227f 100644 --- a/win-linux/src/windows/ceditorwindow_p.h +++ b/win-linux/src/windows/ceditorwindow_p.h @@ -747,6 +747,7 @@ class CEditorWindowPrivate : public CCefEventsGate iconcrypted->setPixmap(QIcon{":/title/icons/secure.svg"}.pixmap(QSize(20,20) * window->m_dpiRatio)); iconcrypted->setFixedSize(ICON_SIZE * window->m_dpiRatio); + iconcrypted->show(); int y = (window->m_labelTitle->height() - ICON_SIZE.height() * window->m_dpiRatio)/2; iconcrypted->move(0, y); connect(window->m_labelTitle, &CElipsisLabel::onResize, this, [=](QSize size, int textWidth) { From c41c1aeea21d25e22f3d317da5da262d455e3aac Mon Sep 17 00:00:00 2001 From: SimplestStudio Date: Wed, 20 Dec 2023 10:35:29 +0200 Subject: [PATCH 3/7] [win-linux] add feature: RTL mode --- win-linux/res/styles/styles.qss | 28 +++++---- win-linux/res/styles/styles@1.25x.qss | 2 + win-linux/res/styles/styles@1.5x.qss | 2 + win-linux/res/styles/styles@1.75x.qss | 2 + win-linux/res/styles/styles@2.25x.qss | 2 + win-linux/res/styles/styles@2.5x.qss | 2 + win-linux/res/styles/styles@2.75x.qss | 2 + win-linux/res/styles/styles@2x.qss | 2 + win-linux/res/styles/styles@3.5x.qss | 2 + win-linux/res/styles/styles@3x.qss | 2 + win-linux/res/styles/styles@4.5x.qss | 2 + win-linux/res/styles/styles@4x.qss | 2 + win-linux/res/styles/styles@5x.qss | 2 + win-linux/res/styles/tabbar.qss | 19 ++++++- .../src/cascapplicationmanagerwrapper.cpp | 39 +++++++++++++ win-linux/src/cascapplicationmanagerwrapper.h | 3 + win-linux/src/clangater.cpp | 5 ++ win-linux/src/clangater.h | 1 + win-linux/src/components/asctabwidget.cpp | 31 ++++++++-- win-linux/src/components/cdownloadwidget.cpp | 26 ++++++++- win-linux/src/components/cdownloadwidget.h | 1 + win-linux/src/components/celipsislabel.cpp | 12 ++++ win-linux/src/components/celipsislabel.h | 1 + win-linux/src/components/ctabbar.cpp | 57 +++++++++++++++++-- win-linux/src/components/ctabbar.h | 3 +- .../src/platform_linux/gtkfilechooser.cpp | 4 ++ win-linux/src/platform_linux/gtkmessage.cpp | 3 + .../src/platform_linux/gtkprintdialog.cpp | 3 + win-linux/src/platform_linux/updatedialog.cpp | 4 ++ win-linux/src/platform_win/message.cpp | 3 + win-linux/src/platform_win/updatedialog.cpp | 3 + win-linux/src/prop/cmainwindowimpl.cpp | 2 + win-linux/src/windows/ceditorwindow.cpp | 5 ++ win-linux/src/windows/ceditorwindow.h | 1 + win-linux/src/windows/ceditorwindow_p.h | 33 ++++++++++- win-linux/src/windows/cmainwindow.cpp | 17 +++++- win-linux/src/windows/cmainwindow.h | 1 + win-linux/src/windows/cpresenterwindow.cpp | 5 ++ win-linux/src/windows/cpresenterwindow.h | 1 + .../platform_linux/cwindowplatform.cpp | 8 +++ .../windows/platform_linux/cwindowplatform.h | 1 + .../windows/platform_win/cwindowplatform.cpp | 13 +++++ .../windows/platform_win/cwindowplatform.h | 2 + 43 files changed, 331 insertions(+), 28 deletions(-) diff --git a/win-linux/res/styles/styles.qss b/win-linux/res/styles/styles.qss index 7d12e1abb..e0c6e212f 100644 --- a/win-linux/res/styles/styles.qss +++ b/win-linux/res/styles/styles.qss @@ -93,8 +93,10 @@ QPushButton#toolButtonMain { font-size: 10px; font-family: 'Open Sans',sans-serif; font-weight: bold; + border-left: 0px; border-right: 1px solid #f1f1f1; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-right: 0px; border-left: 1px solid #f1f1f1;} /*QPushButton#toolButtonMain[theme=light] {*/ /* border: 1px solid #b6b6b6;*/ @@ -117,8 +119,9 @@ QPushButton#toolButtonMain[class=normal], QPushButton#toolButtonMain[class=normal] { background: #f1f1f1; - border-right-color: #dfdfdf; + border-color: #dfdfdf; } +#mainPanel[rtl=true] QPushButton#toolButtonMain[class=normal] {border-color: #dfdfdf;} QPushButton#toolButtonMain[class=normal]:hover { background: #cecece; @@ -145,7 +148,8 @@ QPushButton::menu-indicator {width: 0px; height: 0px;} /*border-image: url(:/res/icons/menu-indicator-dark.png) 0 10 0 0 repeat repeat;*/ /*}*/ -QPushButton#toolButtonDownload {border-right: 1px solid #dfdfdf; max-width: 40px; width: 40px; max-height: 28px; height: 28px;} +QPushButton#toolButtonDownload {border-left: 0px; border-right: 1px solid #dfdfdf; max-width: 40px; width: 40px; max-height: 28px; height: 28px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-right: 0px; border-left: 1px solid #dfdfdf;} /**************************/ /* dark theme definitions */ @@ -160,9 +164,11 @@ QPushButton#toolButtonDownload {border-right: 1px solid #dfdfdf; max-width: 40px color: #d9d9d9; } -#mainPanel[uitheme=theme-dark] QPushButton#toolButtonDownload, +#mainPanel[uitheme=theme-dark] QPushButton#toolButtonDownload { + border-color: #505050; +} #mainPanel[uitheme=theme-dark] QPushButton#toolButtonMain { - border-right-color: #333; + border-color: #333; } #mainPanel[uitheme=theme-dark] QPushButton#toolButtonMain[class=active] { @@ -171,7 +177,7 @@ QPushButton#toolButtonDownload {border-right: 1px solid #dfdfdf; max-width: 40px #mainPanel[uitheme=theme-dark] QPushButton#toolButtonMain[class=normal] { background: #404040; - border-right-color: #505050; + border-color: #505050; } #mainPanel[uitheme=theme-dark] QPushButton#toolButtonMain[class=normal]:hover { @@ -223,14 +229,16 @@ QPushButton#toolButtonDownload {border-right: 1px solid #dfdfdf; max-width: 40px background: #1e1e1e; } -#mainPanel[uitheme=theme-contrast-dark] QPushButton#toolButtonDownload, +#mainPanel[uitheme=theme-contrast-dark] QPushButton#toolButtonDownload { + border-color: #414141; +} #mainPanel[uitheme=theme-contrast-dark] QPushButton#toolButtonMain { - border-right-color: #1e1e1e; + border-color: #1e1e1e; } #mainPanel[uitheme=theme-contrast-dark] QPushButton#toolButtonMain[class=normal] { background: #2a2a2a; - border-right-color: #414141; + border-color: #414141; } #mainPanel[uitheme=theme-contrast-dark] QPushButton#toolButtonMain[class=normal]:hover { @@ -249,11 +257,11 @@ QPushButton#toolButtonDownload {border-right: 1px solid #dfdfdf; max-width: 40px /***********************************/ #mainPanel[uitheme=theme-classic-light] QPushButton#toolButtonMain { - border-right-color: #f1f1f1; + border-color: #f1f1f1; } #mainPanel[uitheme=theme-classic-light] QPushButton#toolButtonMain[class=normal] { - border-right-color: #cbcbcb; + border-color: #cbcbcb; } diff --git a/win-linux/res/styles/styles@1.25x.qss b/win-linux/res/styles/styles@1.25x.qss index 9ec5f21f0..f569d11e7 100644 --- a/win-linux/res/styles/styles@1.25x.qss +++ b/win-linux/res/styles/styles@1.25x.qss @@ -25,6 +25,7 @@ QPushButton#toolButtonMaximize[kde=true], QPushButton#toolButtonMinimize[kde=tru QPushButton#toolButtonMain { border-right-width: 1px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 1px;} QPushButton#toolButtonMain[theme=light] { border-width: 1px; @@ -38,6 +39,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 1px; max-width: 50px; width: 50px; max-height: 35px; height: 35px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 1px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@1.5x.qss b/win-linux/res/styles/styles@1.5x.qss index 1b3834555..8ba57ba52 100644 --- a/win-linux/res/styles/styles@1.5x.qss +++ b/win-linux/res/styles/styles@1.5x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { /*font-size: 20px;*/ border-right-width: 2px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 2px;} QPushButton#toolButtonMain[theme=light] { border-width: 2px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 2px; max-width: 60px; width: 60px; max-height: 42px; height: 42px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 2px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@1.75x.qss b/win-linux/res/styles/styles@1.75x.qss index aa533bc6d..dea8aa8f7 100644 --- a/win-linux/res/styles/styles@1.75x.qss +++ b/win-linux/res/styles/styles@1.75x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { /*font-size: 20px;*/ border-right-width: 2px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 2px;} QPushButton#toolButtonMain[theme=light] { border-width: 2px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 2px; max-width: 70px; width: 70px; max-height: 49px; height: 49px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 2px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@2.25x.qss b/win-linux/res/styles/styles@2.25x.qss index a89bdd71e..e095236f3 100644 --- a/win-linux/res/styles/styles@2.25x.qss +++ b/win-linux/res/styles/styles@2.25x.qss @@ -11,11 +11,13 @@ QPushButton#toolButtonMaximize[kde=true], QPushButton#toolButtonMinimize[kde=tru QPushButton#toolButtonClose[kde=true] {padding: 5px 0px 15px;} QPushButton#toolButtonMain {font-size: 23px; border-right-width: 2px;} +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 2px;} QPushButton#toolButtonMain[theme=light] {border-width: 2px; border-bottom: 0 none;} QPushButton#toolButtonMain[class=normal], QPushButton#toolButtonMain[class=normal]:hover {border-bottom-width: 2px;} QPushButton#toolButtonDownload {border-right-width: 2px; max-width: 90px; width: 90px; max-height: 63px; height: 63px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 2px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@2.5x.qss b/win-linux/res/styles/styles@2.5x.qss index 1110c156f..ede78c8ef 100644 --- a/win-linux/res/styles/styles@2.5x.qss +++ b/win-linux/res/styles/styles@2.5x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 25px; border-right-width: 3px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 3px;} QPushButton#toolButtonMain[theme=light] { border-width: 3px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 3px; max-width: 100px; width: 100px; max-height: 70px; height: 70px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 3px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@2.75x.qss b/win-linux/res/styles/styles@2.75x.qss index f713e1224..753f6d325 100644 --- a/win-linux/res/styles/styles@2.75x.qss +++ b/win-linux/res/styles/styles@2.75x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 28px; border-right-width: 3px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 3px;} QPushButton#toolButtonMain[theme=light] { border-width: 3px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 3px; max-width: 110px; width: 110px; max-height: 77px; height: 77px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 3px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@2x.qss b/win-linux/res/styles/styles@2x.qss index cc02d82c6..fe550d24b 100644 --- a/win-linux/res/styles/styles@2x.qss +++ b/win-linux/res/styles/styles@2x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 20px; border-right-width: 2px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 2px;} QPushButton#toolButtonMain[theme=light] { border-width: 2px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 2px; max-width: 80px; width: 80px; max-height: 56px; height: 56px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 2px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@3.5x.qss b/win-linux/res/styles/styles@3.5x.qss index f4e625d8c..f5b63e7f4 100644 --- a/win-linux/res/styles/styles@3.5x.qss +++ b/win-linux/res/styles/styles@3.5x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 35px; border-right-width: 4px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 4px;} QPushButton#toolButtonMain[theme=light] { border-width: 4px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 4px; max-width: 140px; width: 140px; max-height: 98px; height: 98px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 4px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@3x.qss b/win-linux/res/styles/styles@3x.qss index e0a14f3d8..acdb42766 100644 --- a/win-linux/res/styles/styles@3x.qss +++ b/win-linux/res/styles/styles@3x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 30px; border-right-width: 3px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 3px;} QPushButton#toolButtonMain[theme=light] { border-width: 3px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 3px; max-width: 120px; width: 120px; max-height: 84px; height: 84px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 3px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@4.5x.qss b/win-linux/res/styles/styles@4.5x.qss index aaf6f616c..084c739b1 100644 --- a/win-linux/res/styles/styles@4.5x.qss +++ b/win-linux/res/styles/styles@4.5x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 45px; border-right-width: 5px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 5px;} QPushButton#toolButtonMain[theme=light] { border-width: 5px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 5px; max-width: 180px; width: 180px; max-height: 126px; height: 126px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 5px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@4x.qss b/win-linux/res/styles/styles@4x.qss index 14c59fb86..0ed0d5fce 100644 --- a/win-linux/res/styles/styles@4x.qss +++ b/win-linux/res/styles/styles@4x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 40px; border-right-width: 4px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 4px;} QPushButton#toolButtonMain[theme=light] { border-width: 4px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 4px; max-width: 160px; width: 160px; max-height: 112px; height: 112px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 4px;} /* ToolTip*/ diff --git a/win-linux/res/styles/styles@5x.qss b/win-linux/res/styles/styles@5x.qss index 3ed528af6..3c3342768 100644 --- a/win-linux/res/styles/styles@5x.qss +++ b/win-linux/res/styles/styles@5x.qss @@ -26,6 +26,7 @@ QPushButton#toolButtonMain { font-size: 50px; border-right-width: 5px; } +#mainPanel[rtl=true] QPushButton#toolButtonMain {border-left-width: 5px;} QPushButton#toolButtonMain[theme=light] { border-width: 5px; @@ -39,6 +40,7 @@ QPushButton#toolButtonMain[class=normal], } QPushButton#toolButtonDownload {border-right-width: 5px; max-width: 200px; width: 200px; max-height: 140px; height: 140px;} +#mainPanel[rtl=true] QPushButton#toolButtonDownload {border-left-width: 5px;} /* ToolTip*/ diff --git a/win-linux/res/styles/tabbar.qss b/win-linux/res/styles/tabbar.qss index 69cee6372..e5ffd3987 100644 --- a/win-linux/res/styles/tabbar.qss +++ b/win-linux/res/styles/tabbar.qss @@ -16,10 +16,11 @@ CTabBar #tabScroll>#rightButton:disabled {image: url(:/tabbar/icons/scrolltab_rd CTabBar #tabScroll>#rightButton:hover {image: url(:/tabbar/icons/scrolltab_rh.svg);} CTabBar #tabScroll>#rightButton:pressed {image: url(:/tabbar/icons/scrolltab_rp.svg);} -Tab {background: #f1f1f1; border: none; border-right: 1px solid #dfdfdf; margin: 0px; padding: 0px;} +Tab {background: #f1f1f1; border: none; border-left: 0px; border-right: 1px solid #dfdfdf; margin: 0px; padding: 0px;} Tab #tabIcon {background: transparent;} Tab #tabText {background: transparent; font-family: "Arial", "Helvetica", "Helvetica Neue", sans-serif;} Tab #tabButton {border: none; margin-top: 0px; image: none; background: transparent;} +#mainPanel[rtl=true] Tab {border-right: 0px; border-left: 1px solid #dfdfdf;} Tab[selected=true] {background: #446995; border-color: #446995;} @@ -31,9 +32,11 @@ CTabBar[active=false] Tab[selected=true][hovered=true] {background: #cecece;} /* light */ #mainPanel[uitheme=theme-light] Tab {border-right-color: #dfdfdf;} +#mainPanel[uitheme=theme-light][rtl=true] Tab {border-left-color: #dfdfdf;} /* classic light */ #mainPanel[uitheme=theme-classic-light] Tab {border-right-color: #cbcbcb;} +#mainPanel[uitheme=theme-classic-light][rtl=true] Tab {border-left-color: #cbcbcb;} /* dark */ #mainPanel[uitheme=theme-dark] CTabBar {background: #404040;} @@ -45,6 +48,7 @@ CTabBar[active=false] Tab[selected=true][hovered=true] {background: #cecece;} #mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true] {background: #404040; border-color: #505050;} #mainPanel[uitheme=theme-dark] Tab[selected=false][hovered=true], #mainPanel[uitheme=theme-dark] CTabBar[active=false] Tab[selected=true][hovered=true] {background: #555;} +#mainPanel[uitheme=theme-dark][rtl=true] Tab {border-left-color: #505050;} /* contrast-dark */ #mainPanel[uitheme=theme-contrast-dark] CTabBar {background: #2a2a2a;} @@ -56,6 +60,7 @@ CTabBar[active=false] Tab[selected=true][hovered=true] {background: #cecece;} #mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true] {background: #2a2a2a; border-color: #414141;} #mainPanel[uitheme=theme-contrast-dark] Tab[selected=false][hovered=true], #mainPanel[uitheme=theme-contrast-dark] CTabBar[active=false] Tab[selected=true][hovered=true] {background: #424242;} +#mainPanel[uitheme=theme-contrast-dark][rtl=true] Tab {border-left-color: #414141;} /* portal */ @@ -109,6 +114,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="1.25x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 19px; min-height: 19px; max-width: 19px; max-height: 19px;} #mainPanel[zoom="1.25x"] Tab #tabText {font-size: 14px;} #mainPanel[zoom="1.25x"] Tab #tabButton {width: 20px; max-width: 20px; max-height: 20px; border-width: 2px;} +#mainPanel[zoom="1.25x"][rtl=true] Tab {border-left-width: 1px;} /* 1.5x */ #mainPanel[zoom="1.5x"] CTabBar #tabScroll {min-width: 48px; max-width: 48px;} @@ -117,6 +123,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="1.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 24px; min-height: 24px; max-width: 24px; max-height: 24px;} #mainPanel[zoom="1.5x"] Tab #tabText {font-size: 15px;} #mainPanel[zoom="1.5x"] Tab #tabButton {width: 24px; max-width: 24px; max-height: 24px; border-width: 2px;} +#mainPanel[zoom="1.5x"][rtl=true] Tab {border-left-width: 2px;} /* 1.75x */ #mainPanel[zoom="1.75x"] CTabBar #tabScroll {min-width: 64px; max-width: 64px;} @@ -125,6 +132,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="1.75x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 28px; min-height: 28px; max-width: 28px; max-height: 28px;} #mainPanel[zoom="1.75x"] Tab #tabText {font-size: 18px;} #mainPanel[zoom="1.75x"] Tab #tabButton {width: 28px; max-width: 28px; max-height: 28px; border-width: 2px;} +#mainPanel[zoom="1.75x"][rtl=true] Tab {border-left-width: 2px;} /* 2x */ #mainPanel[zoom="2x"] CTabBar #tabScroll {min-width: 64px; max-width: 64px;} @@ -133,6 +141,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="2x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 32px; min-height: 32px; max-width: 32px; max-height: 32px;} #mainPanel[zoom="2x"] Tab #tabText {font-size: 20px;} #mainPanel[zoom="2x"] Tab #tabButton {width: 32px; max-width: 32px; max-height: 32px; border-width: 2px;} +#mainPanel[zoom="2x"][rtl=true] Tab {border-left-width: 2px;} /* 2.25x */ #mainPanel[zoom="2.25x"] CTabBar #tabScroll {min-width: 72px; max-width: 72px;} @@ -141,6 +150,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="2.25x"] Tab #tabIcon {padding-left: 9px; padding-right: 9px; min-width: 36px; min-height: 36px; max-width: 36px; max-height: 36px;} #mainPanel[zoom="2.25x"] Tab #tabText {font-size: 23px;} #mainPanel[zoom="2.25x"] Tab #tabButton {width: 36px; max-width: 36px; max-height: 36px; border-width: 2px;} +#mainPanel[zoom="2.25x"][rtl=true] Tab {border-left-width: 2px;} /* 2.5x */ #mainPanel[zoom="2.5x"] CTabBar #tabScroll {min-width: 80px; max-width: 80px;} @@ -149,6 +159,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="2.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 40px; min-height: 40px; max-width: 40px; max-height: 40px;} #mainPanel[zoom="2.5x"] Tab #tabText {font-size: 25px;} #mainPanel[zoom="2.5x"] Tab #tabButton {width: 40px; max-width: 40px; max-height: 40px; border-width: 2px;} +#mainPanel[zoom="2.5x"][rtl=true] Tab {border-left-width: 3px;} /* 2.75x */ #mainPanel[zoom="2.75x"] CTabBar #tabScroll {min-width: 88px; max-width: 88px;} @@ -157,6 +168,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="2.75x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 44px; min-height: 44px; max-width: 44px; max-height: 44px;} #mainPanel[zoom="2.75x"] Tab #tabText {font-size: 28px;} #mainPanel[zoom="2.75x"] Tab #tabButton {width: 44px; max-width: 44px; max-height: 44px; border-width: 2px;} +#mainPanel[zoom="2.75x"][rtl=true] Tab {border-left-width: 3px;} /* 3x */ #mainPanel[zoom="3x"] CTabBar #tabScroll {min-width: 96px; max-width: 96px;} @@ -165,6 +177,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="3x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 48px; min-height: 48px; max-width: 48px; max-height: 48px;} #mainPanel[zoom="3x"] Tab #tabText {font-size: 30px;} #mainPanel[zoom="3x"] Tab #tabButton {width: 48px; max-width: 48px; max-height: 48px; border-width: 2px;} +#mainPanel[zoom="3x"][rtl=true] Tab {border-left-width: 3px;} /* 3.5x */ #mainPanel[zoom="3.5x"] CTabBar #tabScroll {min-width: 112px; max-width: 112px;} @@ -173,6 +186,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="3.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 56px; min-height: 56px; max-width: 56px; max-height: 56px;} #mainPanel[zoom="3.5x"] Tab #tabText {font-size: 35px;} #mainPanel[zoom="3.5x"] Tab #tabButton {width: 56px; max-width: 56px; max-height: 56px; border-width: 2px;} +#mainPanel[zoom="3.5x"][rtl=true] Tab {border-left-width: 4px;} /* 4x */ #mainPanel[zoom="4x"] CTabBar #tabScroll {min-width: 128px; max-width: 128px;} @@ -181,6 +195,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="4x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 64px; min-height: 64px; max-width: 64px; max-height: 64px;} #mainPanel[zoom="4x"] Tab #tabText {font-size: 40px;} #mainPanel[zoom="4x"] Tab #tabButton {width: 64px; max-width: 64px; max-height: 64px; border-width: 2px;} +#mainPanel[zoom="4x"][rtl=true] Tab {border-left-width: 4px;} /* 4.5x */ #mainPanel[zoom="4.5x"] CTabBar #tabScroll {min-width: 144px; max-width: 144px;} @@ -189,6 +204,7 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="4.5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 72px; min-height: 72px; max-width: 72px; max-height: 72px;} #mainPanel[zoom="4.5x"] Tab #tabText {font-size: 45px;} #mainPanel[zoom="4.5x"] Tab #tabButton {width: 72px; max-width: 72px; max-height: 72px; border-width: 2px;} +#mainPanel[zoom="4.5x"][rtl=true] Tab {border-left-width: 5px;} /* 5x */ #mainPanel[zoom="5x"] CTabBar #tabScroll {min-width: 160px; max-width: 160px;} @@ -197,3 +213,4 @@ Tab #tabButton {width: 16px; max-width: 16px; max-height: 16px; border-width: 2p #mainPanel[zoom="5x"] Tab #tabIcon {padding-left: 8px; padding-right: 8px; min-width: 80px; min-height: 80px; max-width: 80px; max-height: 80px;} #mainPanel[zoom="5x"] Tab #tabText {font-size: 50px;} #mainPanel[zoom="5x"] Tab #tabButton {width: 80px; max-width: 80px; max-height: 80px; border-width: 2px;} +#mainPanel[zoom="5x"][rtl=true] Tab {border-left-width: 5px;} diff --git a/win-linux/src/cascapplicationmanagerwrapper.cpp b/win-linux/src/cascapplicationmanagerwrapper.cpp index 65b994136..f0afb40c8 100644 --- a/win-linux/src/cascapplicationmanagerwrapper.cpp +++ b/win-linux/src/cascapplicationmanagerwrapper.cpp @@ -54,6 +54,8 @@ using namespace std; using namespace std::placeholders; +bool CAscApplicationManagerWrapper::m_rtlEnabled = false; + CAscApplicationManagerWrapper::CAscApplicationManagerWrapper(CAscApplicationManagerWrapper const&) { @@ -1159,6 +1161,11 @@ void CAscApplicationManagerWrapper::initializeApp() if ( !local_themes_array.isEmpty() ) EditorJSVariables::setVariable("localthemes", local_themes_array); + const bool _is_rtl = reg_user.contains("forcedRtl") ? reg_user.value("forcedRtl", false).toBool() : + CLangater::isRtlLanguage(CLangater::getCurrentLangCode()); + AscAppManager::setRtlEnabled(_is_rtl); + EditorJSVariables::setVariable("rtl", _is_rtl ? "yes" : "no"); + EditorJSVariables::setVariable("lang", CLangater::getCurrentLangCode()); EditorJSVariables::applyVariable("theme", { {"type", _app.m_themes->current().stype()}, @@ -1637,6 +1644,28 @@ bool CAscApplicationManagerWrapper::event(QEvent *event) return QObject::event(event); } +void CAscApplicationManagerWrapper::setRtlEnabled(bool state) +{ + if (m_rtlEnabled != state) { + m_rtlEnabled = state; + Qt::LayoutDirection direct = m_rtlEnabled ? Qt::RightToLeft : Qt::LeftToRight; + APP_CAST(_app); + if (_app.m_pMainWindow) + _app.m_pMainWindow->setLayoutDirection(direct); + for (auto const &r : _app.m_winsReporter) + r.second->setLayoutDirection(direct); + for (auto const &e : _app.m_vecEditors) { + CEditorWindow *editor = reinterpret_cast(e); + editor->setLayoutDirection(direct); + } + } +} + +bool CAscApplicationManagerWrapper::isRtlEnabled() +{ + return m_rtlEnabled; +} + bool CAscApplicationManagerWrapper::applySettings(const wstring& wstrjson) { QJsonParseError jerror; @@ -1691,6 +1720,16 @@ bool CAscApplicationManagerWrapper::applySettings(const wstring& wstrjson) setUserSettings(L"spell-check-input-mode", objRoot["spellcheckdetect"].toString() == "off" ? L"0" : L"default"); } + if ( objRoot.contains("rtl") ) { + _reg_user.setValue("forcedRtl", objRoot["rtl"].toBool(false)); + + /* + * show message and relaunch app + */ + } else { + _reg_user.remove("forcedRtl"); + } + wstring params = QString("lang=%1&username=%3&location=%2") .arg(_lang_id, Utils::systemLocationCode(), QUrl::toPercentEncoding(_user_newname)).toStdWString(); diff --git a/win-linux/src/cascapplicationmanagerwrapper.h b/win-linux/src/cascapplicationmanagerwrapper.h index 3e6fa2788..92d52e884 100644 --- a/win-linux/src/cascapplicationmanagerwrapper.h +++ b/win-linux/src/cascapplicationmanagerwrapper.h @@ -120,6 +120,7 @@ class CAscApplicationManagerWrapper : public QObject, public QAscApplicationMana CMainWindow * m_pMainWindow = nullptr; std::shared_ptr m_themes; + static bool m_rtlEnabled; public: CWindowsQueue& closeQueue(); @@ -201,6 +202,8 @@ private slots: static void closeAppWindows(); // TODO: combine with launchAppClose static void cancelClose(); + static void setRtlEnabled(bool); + static bool isRtlEnabled(); uint logoutCount(const std::wstring& portal) const; void Logout(const std::wstring& portal); diff --git a/win-linux/src/clangater.cpp b/win-linux/src/clangater.cpp index df22f9122..5af1d363b 100644 --- a/win-linux/src/clangater.cpp +++ b/win-linux/src/clangater.cpp @@ -305,3 +305,8 @@ void CLangater::addTranslation(const QString& dir) { addTranslation(dir, getInstance()->m_lang); } + +bool CLangater::isRtlLanguage(const QString &lang) { + QLocale loc = lang.isEmpty() ? QLocale::system() : QLocale(lang); + return loc.textDirection() == Qt::LayoutDirection::RightToLeft; +} diff --git a/win-linux/src/clangater.h b/win-linux/src/clangater.h index b44de8b66..5e7eea7cf 100644 --- a/win-linux/src/clangater.h +++ b/win-linux/src/clangater.h @@ -20,6 +20,7 @@ class CLangater : public QObject static QString getLangName(const QString& code = QString()); static void addTranslation(const QString& dir, const QString& name); static void addTranslation(const QString& dir); + static bool isRtlLanguage(const QString &lang = QString()); static QJsonObject availableLangsToJson(); diff --git a/win-linux/src/components/asctabwidget.cpp b/win-linux/src/components/asctabwidget.cpp index 19a41fdaa..fd7f7be6e 100644 --- a/win-linux/src/components/asctabwidget.cpp +++ b/win-linux/src/components/asctabwidget.cpp @@ -187,6 +187,23 @@ CAscTabWidget::CAscTabWidget(QWidget *parent, CTabBar *_pBar) removeWidget(wgt); insertWidget(to, wgt); }); + QObject::connect(m_pBar, &CTabBar::tabsSwapped, this, [=](int from, int to) { + if (from == to || !indexIsValid(from) || !indexIsValid(to)) + return; + auto wgt_from = widget(from); + auto wgt_to = widget(to); + blockSignals(true); + removeWidget(wgt_from); + removeWidget(wgt_to); + insertWidget(from < to ? from : to, from < to ? wgt_to : wgt_from); + insertWidget(from < to ? to : from, from < to ? wgt_from : wgt_to); + if (from == m_pBar->currentIndex()) + QStackedWidget::setCurrentIndex(to); + else + if (to == m_pBar->currentIndex()) + QStackedWidget::setCurrentIndex(from); + blockSignals(false); + }); } CTabPanel * CAscTabWidget::panel(int index) const @@ -220,7 +237,7 @@ int CAscTabWidget::addEditor(const COpenOptions& opts) pView->initAsEditor(); - int tab_index = -1; + int tab_index = AscAppManager::isRtlEnabled() ? 0 : -1; bool res_open = true; if (opts.srctype == etLocalFile) { pView->openLocalFile(opts.wurl, file_format, L""); @@ -247,8 +264,8 @@ int CAscTabWidget::addEditor(const COpenOptions& opts) data->setChanged(opts.srctype == etRecoveryFile); pView->setData(data); - tab_index = addWidget(panelwidget); - m_pBar->addTab(data->title()); + tab_index = insertWidget(tab_index, panelwidget); + m_pBar->insertTab(tab_index, data->title()); m_pBar->setTabToolTip(tab_index, data->title()); m_pBar->tabStartLoading(tab_index); @@ -367,7 +384,7 @@ int CAscTabWidget::addPortal(const QString& url, const QString& name, const QStr data->setUrl(_url); pView->setData(data); - int tab_index = -1; + int tab_index = AscAppManager::isRtlEnabled() ? 0 : -1; tab_index = insertWidget(tab_index, panelwidget); m_pBar->insertTab(tab_index, portal); @@ -408,7 +425,7 @@ int CAscTabWidget::addOAuthPortal(const QString& portal, const QString& type, co data->setUrl(portal); pView->setData(data); - int tab_index = -1; + int tab_index = AscAppManager::isRtlEnabled() ? 0 : -1; tab_index = insertWidget(tab_index, panelwidget); m_pBar->insertTab(tab_index, _portal); @@ -423,7 +440,7 @@ int CAscTabWidget::addOAuthPortal(const QString& portal, const QString& type, co int CAscTabWidget::insertPanel(QWidget * panel, int index) { - int tabindex = -1; + int tabindex = AscAppManager::isRtlEnabled() ? 0 : -1; CTabPanel * _panel = dynamic_cast(panel); Q_ASSERT(_panel != nullptr); @@ -432,6 +449,8 @@ int CAscTabWidget::insertPanel(QWidget * panel, int index) QWidget * panelwidget = createTabPanel(this, _panel); + if (index < 0 && AscAppManager::isRtlEnabled()) + index = 0; tabindex = insertWidget(index, panelwidget); m_pBar->insertTab(tabindex, tabdata->title()); m_pBar->setTabToolTip(tabindex, tabdata->title()); diff --git a/win-linux/src/components/cdownloadwidget.cpp b/win-linux/src/components/cdownloadwidget.cpp index 8a96dcde6..0825342e2 100644 --- a/win-linux/src/components/cdownloadwidget.cpp +++ b/win-linux/src/components/cdownloadwidget.cpp @@ -171,6 +171,7 @@ CDownloadWidget::CDownloadWidget(QWidget *parent) QLabel *labelTitle = new QLabel(m_titleFrame); labelTitle->setObjectName("labelTitle"); labelTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + labelTitle->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignAbsolute); labelTitle->setText(tr("Downloads")); m_titleFrame->layout()->addWidget(labelTitle); @@ -210,8 +211,10 @@ CDownloadWidget::CDownloadWidget(QWidget *parent) connect(m_pToolButton, &QPushButton::clicked, this, [=]() { polish(); show(); - QPoint offset(-1 * MAIN_WINDOW_BORDER_WIDTH * m_dpiRatio, (TITLE_HEIGHT + MAIN_WINDOW_BORDER_WIDTH) * m_dpiRatio); - QPoint pos = parent->geometry().topRight() - QPoint(WIDGET_MAX_WIDTH, 0) + offset + QPoint(qRound(SHADOW - MARGINS/3), qRound(-SHADOW + MARGINS/3)); + QPoint pos = AscAppManager::isRtlEnabled() ? parent->geometry().topLeft() : parent->geometry().topRight() - QPoint(WIDGET_MAX_WIDTH, 0); + QPoint brd_offset((AscAppManager::isRtlEnabled() ? 1 : -1) * MAIN_WINDOW_BORDER_WIDTH * m_dpiRatio, (TITLE_HEIGHT + MAIN_WINDOW_BORDER_WIDTH) * m_dpiRatio); + QPoint shd_offset((AscAppManager::isRtlEnabled() ? -1 : 1) * qRound(SHADOW - MARGINS/3), qRound(-SHADOW + MARGINS/3)); + pos += brd_offset + shd_offset; move(pos); int prefHeight = m_mapDownloads.size() * ITEM_MAX_HEIGHT + 74 * m_dpiRatio; setGeometry(QRect(pos, QSize(WIDGET_MAX_WIDTH, (prefHeight > WIDGET_MAX_HEIGHT) ? WIDGET_MAX_HEIGHT : prefHeight))); @@ -248,6 +251,7 @@ QWidget * CDownloadWidget::addFile(const QString& fn, int id) CElipsisLabel * name = new CElipsisLabel(fn); name->setObjectName("labelName"); name->setEllipsisMode(Qt::ElideRight); + name->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignAbsolute); name->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); grid->addWidget(name, 0, 0, 1, 1); @@ -273,6 +277,7 @@ QWidget * CDownloadWidget::addFile(const QString& fn, int id) CElipsisLabel * info = new CElipsisLabel(QString("0 %1").arg(tr("kBps"))); info->setObjectName("labelInfo"); info->setEllipsisMode(Qt::ElideRight); + info->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignAbsolute); info->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); grid->addWidget(info, 2, 0, 1, 2); @@ -325,6 +330,7 @@ void CDownloadWidget::downloadProcess(void * info) } QLabel *size_label = new QLabel; size_label->setObjectName("labelSize"); + size_label->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignAbsolute); size_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); size_label->setText(getFileSize(QString::fromStdWString(pData->get_FilePath()))); lut->addWidget(size_label, 1, 0, 1, 2); @@ -505,6 +511,22 @@ void CDownloadWidget::applyTheme(const QString &theme) polish(); } +void CDownloadWidget::onLayoutDirectionChanged() +{ + setLayoutDirection(AscAppManager::isRtlEnabled() ? Qt::RightToLeft : Qt::LeftToRight); + if (QLabel *labelTitle = m_titleFrame->findChild("labelTitle")) + labelTitle->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignAbsolute); + for (int i = 0; i < m_pContentArea->layout()->count(); ++i) { + auto item = m_pContentArea->layout()->itemAt(i); + if (item && item->widget()) { + const auto lb_list = item->widget()->findChildren(); + for (QLabel *lb : lb_list) { + lb->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignAbsolute); + } + } + } +} + void CDownloadWidget::onStart() { if (!m_pToolButton->isVisible()) diff --git a/win-linux/src/components/cdownloadwidget.h b/win-linux/src/components/cdownloadwidget.h index 97ce4ae2a..4737f8ce4 100644 --- a/win-linux/src/components/cdownloadwidget.h +++ b/win-linux/src/components/cdownloadwidget.h @@ -52,6 +52,7 @@ class CDownloadWidget : public QWidget QPushButton * toolButton(); void updateScalingFactor(double); void applyTheme(const QString&); + void onLayoutDirectionChanged(); protected: virtual void closeEvent(QCloseEvent *) final; diff --git a/win-linux/src/components/celipsislabel.cpp b/win-linux/src/components/celipsislabel.cpp index 05f31704c..1587aad29 100644 --- a/win-linux/src/components/celipsislabel.cpp +++ b/win-linux/src/components/celipsislabel.cpp @@ -85,6 +85,18 @@ auto CElipsisLabel::setEllipsisMode(Qt::TextElideMode mode) -> void elide_mode = mode; } +auto CElipsisLabel::textWidth() -> int +{ + QString elt = ellipsis_text_(this, orig_text, elide_mode); + QFontMetrics fm(font()); +#if (QT_VERSION < QT_VERSION_CHECK(5,11,0)) + int textWidth = fm.width(elt); +#else + int textWidth = fm.horizontalAdvance(elt); +#endif + return textWidth; +} + auto CElipsisLabel::updateText() -> void { QString elt = ellipsis_text_(this, orig_text, elide_mode); diff --git a/win-linux/src/components/celipsislabel.h b/win-linux/src/components/celipsislabel.h index a3ff8df8a..01483365d 100644 --- a/win-linux/src/components/celipsislabel.h +++ b/win-linux/src/components/celipsislabel.h @@ -46,6 +46,7 @@ class CElipsisLabel : public QLabel auto setText(const QString&) -> void; auto setEllipsisMode(Qt::TextElideMode) -> void; auto updateText() -> void; + auto textWidth() -> int; signals: void onResize(QSize size, int textWidth); diff --git a/win-linux/src/components/ctabbar.cpp b/win-linux/src/components/ctabbar.cpp index 40a0856c4..a987a3479 100644 --- a/win-linux/src/components/ctabbar.cpp +++ b/win-linux/src/components/ctabbar.cpp @@ -122,6 +122,7 @@ Tab::Tab(QWidget *parent) : text_label = new QLabel(this); text_label->setObjectName("tabText"); + text_label->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter | Qt::AlignAbsolute); text_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); lut->addWidget(text_label); @@ -472,6 +473,8 @@ void CTabBar::CTabBarPrivate::slide(int from, int to, int offset, int animation_ void CTabBar::CTabBarPrivate::scrollToDirection(int direction) { + if (AscAppManager::isRtlEnabled()) + direction = (direction == Direction::Left) ? Direction::Right : Direction::Left; while (animationInProgress) PROCESSEVENTS(); @@ -559,7 +562,10 @@ void CTabBar::CTabBarPrivate::changeScrollerState() break; } } - leftButton->setEnabled(allowScroll); + if (AscAppManager::isRtlEnabled()) + rightButton->setEnabled(allowScroll); + else + leftButton->setEnabled(allowScroll); allowScroll = false; for (int i = 0; i < tabList.size(); i++) { @@ -568,7 +574,10 @@ void CTabBar::CTabBarPrivate::changeScrollerState() break; } } - rightButton->setEnabled(allowScroll); + if (AscAppManager::isRtlEnabled()) + leftButton->setEnabled(allowScroll); + else + rightButton->setEnabled(allowScroll); } void CTabBar::CTabBarPrivate::reorderIndexes() @@ -624,8 +633,8 @@ CTabBar::CTabBar(QWidget *parent) : d->leftButton = new QToolButton(d->scrollFrame); d->rightButton = new QToolButton(d->scrollFrame); - d->leftButton->setObjectName("leftButton"); - d->rightButton->setObjectName("rightButton"); + d->leftButton->setObjectName(AscAppManager::isRtlEnabled() ? "rightButton" : "leftButton"); + d->rightButton->setObjectName(AscAppManager::isRtlEnabled() ? "leftButton" : "rightButton"); scrollLayout->addWidget(d->leftButton); scrollLayout->addWidget(d->rightButton); @@ -723,6 +732,27 @@ int CTabBar::insertTab(int index, const QIcon &icon, const QString &text) return actual_index; } +void CTabBar::swapTabs(int from, int to) +{ + while (d->animationInProgress) + PROCESSEVENTS(); + if (from == to || !d->indexIsValid(from) || !d->indexIsValid(to)) + return; + int posX = d->_tabRect(from).x(); + d->tabList[from]->move(d->_tabRect(to).x(), 0); + d->tabList[to]->move(posX, 0); + int from_index = d->tabIndex(from); + d->tabIndex(from) = d->tabIndex(to); + d->tabIndex(to) = from_index; + std::swap(d->tabList[from], d->tabList[to]); + emit tabsSwapped(from, to); + if (from == d->currentIndex) + d->onCurrentChanged(to); + else + if (to == d->currentIndex) + d->onCurrentChanged(from); +} + void CTabBar::removeTab(int index) { while (d->animationInProgress) @@ -1076,7 +1106,8 @@ bool CTabBar::eventFilter(QObject *watched, QEvent *event) } } } - if (!d->tabArea->rect().contains(me->pos()) && d->tabArea->rect().right() >= me->x()) { + bool undockDirectionIsValid = AscAppManager::isRtlEnabled() ? d->tabArea->rect().left() <= me->x() : d->tabArea->rect().right() >= me->x(); + if (!d->tabArea->rect().contains(me->pos()) && undockDirectionIsValid) { if (d->currentIndex != d->movedTabIndex) d->reorderIndexes(); bool accepted = false; @@ -1185,6 +1216,22 @@ bool CTabBar::eventFilter(QObject *watched, QEvent *event) case QEvent::Leave: QApplication::postEvent(d->tabArea, new QMouseEvent(QEvent::MouseButtonRelease, QCursor::pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)); break; + case QEvent::LayoutDirectionChange: { + SKIP_EVENTS_QUEUE([=]() { + for (int i = 0; i < d->tabList.size(); i++) { + d->tabList[i]->polish(); + d->tabList[i]->text_label->setAlignment((AscAppManager::isRtlEnabled() ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter | Qt::AlignAbsolute); + } + d->leftButton->setObjectName(AscAppManager::isRtlEnabled() ? "rightButton" : "leftButton"); + d->rightButton->setObjectName(AscAppManager::isRtlEnabled() ? "leftButton" : "rightButton"); + d->leftButton->style()->polish(d->leftButton); + d->rightButton->style()->polish(d->rightButton); + int n = count(); + for (int i = 0; i < n/2; i++) + swapTabs(i, n - i - 1); + }); + break; + } default: break; } diff --git a/win-linux/src/components/ctabbar.h b/win-linux/src/components/ctabbar.h index d2960feae..82e9e8347 100644 --- a/win-linux/src/components/ctabbar.h +++ b/win-linux/src/components/ctabbar.h @@ -56,7 +56,7 @@ class CTabBar : public QFrame QSize iconSize() const; int insertTab(int index, const QString &text); int insertTab(int index, const QIcon &icon, const QString &text); -// void moveTab(int from, int to); + void swapTabs(int from, int to); void removeTab(int index); void setElideMode(Qt::TextElideMode mode); void setIconSize(const QSize &size); @@ -92,6 +92,7 @@ class CTabBar : public QFrame // void tabBarDoubleClicked(int index); void tabCloseRequested(int index); void tabMoved(int from, int to); + void tabsSwapped(int from, int to); void tabUndock(int index, bool &accepted); protected: diff --git a/win-linux/src/platform_linux/gtkfilechooser.cpp b/win-linux/src/platform_linux/gtkfilechooser.cpp index f268233c0..39eef5e92 100755 --- a/win-linux/src/platform_linux/gtkfilechooser.cpp +++ b/win-linux/src/platform_linux/gtkfilechooser.cpp @@ -3,6 +3,7 @@ #include #include "gtkutils.h" #include "gtkfilechooser.h" +#include "cascapplicationmanagerwrapper.h" #include @@ -82,6 +83,9 @@ static void nativeFileDialog(const Window &parent_xid, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER }; + + if (AscAppManager::isRtlEnabled()) + gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); GtkWidget *dialog = NULL; dialog = gtk_file_chooser_dialog_new(title, NULL, diff --git a/win-linux/src/platform_linux/gtkmessage.cpp b/win-linux/src/platform_linux/gtkmessage.cpp index 65d1642ef..7af2bd360 100644 --- a/win-linux/src/platform_linux/gtkmessage.cpp +++ b/win-linux/src/platform_linux/gtkmessage.cpp @@ -36,6 +36,7 @@ #include #include #include "gtkmessage.h" +#include "cascapplicationmanagerwrapper.h" #include @@ -84,6 +85,8 @@ int GtkMsg::showMessage(QWidget *parent, GtkDialogFlags flags; flags = (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT); + if (AscAppManager::isRtlEnabled()) + gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); GtkWidget *dialog = NULL; dialog = gtk_message_dialog_new(NULL, flags, diff --git a/win-linux/src/platform_linux/gtkprintdialog.cpp b/win-linux/src/platform_linux/gtkprintdialog.cpp index 27bd99c1a..c58527d4a 100644 --- a/win-linux/src/platform_linux/gtkprintdialog.cpp +++ b/win-linux/src/platform_linux/gtkprintdialog.cpp @@ -3,6 +3,7 @@ #include "gtkutils.h" #include "gtkprintdialog.h" #include "components/cmessage.h" +#include "cascapplicationmanagerwrapper.h" #include #include #include @@ -369,6 +370,8 @@ QDialog::DialogCode GtkPrintDialog::exec() } // Init dialog + if (AscAppManager::isRtlEnabled()) + gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); GtkWidget *dialog; dialog = gtk_print_unix_dialog_new(m_title.toUtf8().data(), NULL); gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG); diff --git a/win-linux/src/platform_linux/updatedialog.cpp b/win-linux/src/platform_linux/updatedialog.cpp index 157d687da..ce06f3cfb 100644 --- a/win-linux/src/platform_linux/updatedialog.cpp +++ b/win-linux/src/platform_linux/updatedialog.cpp @@ -36,6 +36,7 @@ #include "utils.h" #include #include "updatedialog.h" +#include "cascapplicationmanagerwrapper.h" #include //extern "C" { //#include "gtk_resources.h" @@ -77,6 +78,9 @@ int WinDlg::showDialog(QWidget *parent, gtk_init(NULL, NULL); GtkDialogFlags flags; flags = (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT); + + if (AscAppManager::isRtlEnabled()) + gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); GtkWidget *dialog = NULL; dialog = gtk_message_dialog_new(NULL, flags, diff --git a/win-linux/src/platform_win/message.cpp b/win-linux/src/platform_win/message.cpp index 4099ecd99..c506d09c2 100644 --- a/win-linux/src/platform_win/message.cpp +++ b/win-linux/src/platform_win/message.cpp @@ -33,6 +33,7 @@ #include #include "message.h" #include "utils.h" +#include "cascapplicationmanagerwrapper.h" #include #include #include @@ -172,6 +173,8 @@ int WinMsg::showMessage(QWidget *parent, config.dwFlags = TDF_POSITION_RELATIVE_TO_WINDOW | TDF_ALLOW_DIALOG_CANCELLATION | TDF_SIZE_TO_CONTENT; + if (AscAppManager::isRtlEnabled()) + config.dwFlags |= TDF_RTL_LAYOUT; config.hwndParent = parent_hwnd; config.hInstance = GetModuleHandle(NULL); config.pfCallback = (PFTASKDIALOGCALLBACK)Pftaskdialogcallback; diff --git a/win-linux/src/platform_win/updatedialog.cpp b/win-linux/src/platform_win/updatedialog.cpp index 95cb34770..f1fd3d0db 100644 --- a/win-linux/src/platform_win/updatedialog.cpp +++ b/win-linux/src/platform_win/updatedialog.cpp @@ -33,6 +33,7 @@ #include #include "updatedialog.h" #include "platform_win/resource.h" +#include "cascapplicationmanagerwrapper.h" #include "defines.h" #include "utils.h" #include @@ -152,6 +153,8 @@ int WinDlg::showDialog(QWidget *parent, config.dwFlags = TDF_ENABLE_HYPERLINKS | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_ALLOW_DIALOG_CANCELLATION; + if (AscAppManager::isRtlEnabled()) + config.dwFlags |= TDF_RTL_LAYOUT; config.hwndParent = parent_hwnd; config.hInstance = GetModuleHandle(NULL); config.pfCallback = (PFTASKDIALOGCALLBACK)Pftaskdialogcallback; diff --git a/win-linux/src/prop/cmainwindowimpl.cpp b/win-linux/src/prop/cmainwindowimpl.cpp index 72be32811..a46dddb63 100644 --- a/win-linux/src/prop/cmainwindowimpl.cpp +++ b/win-linux/src/prop/cmainwindowimpl.cpp @@ -94,6 +94,8 @@ void CMainWindowImpl::refreshAboutVersion() GET_REGISTRY_USER(reg_user); _json_obj["editorwindowmode"] = reg_user.value("editorWindowMode",false).toBool(); + _json_obj["rtl"] = reg_user.contains("forcedRtl") ? reg_user.value("forcedRtl", false).toBool() : + CLangater::isRtlLanguage(CLangater::getCurrentLangCode()); // Read update settings #ifdef _UPDMODULE diff --git a/win-linux/src/windows/ceditorwindow.cpp b/win-linux/src/windows/ceditorwindow.cpp index dae313f86..21270b6b7 100644 --- a/win-linux/src/windows/ceditorwindow.cpp +++ b/win-linux/src/windows/ceditorwindow.cpp @@ -457,3 +457,8 @@ void CEditorWindow::closeEvent(QCloseEvent * e) AscAppManager::getInstance().closeQueue().enter(sWinTag{CLOSE_QUEUE_WIN_TYPE_EDITOR, size_t(this)}); e->ignore(); } + +void CEditorWindow::onLayoutDirectionChanged() +{ + d_ptr->onLayoutDirectionChanged(); +} diff --git a/win-linux/src/windows/ceditorwindow.h b/win-linux/src/windows/ceditorwindow.h index f1b7d93a9..8a5a883d2 100644 --- a/win-linux/src/windows/ceditorwindow.h +++ b/win-linux/src/windows/ceditorwindow.h @@ -67,6 +67,7 @@ class CEditorWindow : public CWindowPlatform protected: void closeEvent(QCloseEvent *) override; + virtual void onLayoutDirectionChanged() final; private: QWidget * createMainPanel(QWidget *, const QString&); diff --git a/win-linux/src/windows/ceditorwindow_p.h b/win-linux/src/windows/ceditorwindow_p.h index ee5be227f..c2e0026fc 100644 --- a/win-linux/src/windows/ceditorwindow_p.h +++ b/win-linux/src/windows/ceditorwindow_p.h @@ -66,6 +66,7 @@ #define TOP_PANEL_OFFSET 6*TOOLBTN_WIDTH #define ICON_SPACER_WIDTH 9 #define ICON_SIZE QSize(20,20) +#define MARGINS 6 using namespace NSEditorApi; @@ -219,10 +220,36 @@ class CEditorWindowPrivate : public CCefEventsGate } } QMargins mrg(0, 0, 0, 2*dpiRatio); - diffW > 0 ? mrg.setRight(diffW) : mrg.setLeft(-diffW); + if (AscAppManager::isRtlEnabled()) + diffW > 0 ? mrg.setLeft(diffW) : mrg.setRight(-diffW); + else + diffW > 0 ? mrg.setRight(diffW) : mrg.setLeft(-diffW); boxtitlelabel->setContentsMargins(mrg); } + auto onLayoutDirectionChanged()->void + { + if (boxtitlelabel) { + QMargins mrg = boxtitlelabel->contentsMargins(); + if (AscAppManager::isRtlEnabled()) { + mrg.setLeft(mrg.right()); + mrg.setRight(0); + } else { + mrg.setRight(mrg.left()); + mrg.setLeft(0); + } + boxtitlelabel->setContentsMargins(mrg); + } + if (iconcrypted) { + QSize size = window->m_labelTitle->size(); + int offset = window->m_labelTitle->textWidth()/2 + MARGINS * window->m_dpiRatio; + int x = size.width()/2; + x += AscAppManager::isRtlEnabled() ? offset : -offset - ICON_SIZE.width() * window->m_dpiRatio; + int y = (size.height() - ICON_SIZE.height() * window->m_dpiRatio)/2; + iconcrypted->move(x, y); + } + } + void onEditorConfig(int, std::wstring cfg) override { // if ( id == window->holdView(id) ) @@ -752,7 +779,9 @@ class CEditorWindowPrivate : public CCefEventsGate iconcrypted->move(0, y); connect(window->m_labelTitle, &CElipsisLabel::onResize, this, [=](QSize size, int textWidth) { if (iconcrypted) { - int x = (size.width() - textWidth)/2 - ((ICON_SIZE.width() + 6) * window->m_dpiRatio); + int offset = textWidth/2 + MARGINS * window->m_dpiRatio; + int x = size.width()/2; + x += AscAppManager::isRtlEnabled() ? offset : -offset - ICON_SIZE.width() * window->m_dpiRatio; int y = (size.height() - ICON_SIZE.height() * window->m_dpiRatio)/2; iconcrypted->move(x, y); } diff --git a/win-linux/src/windows/cmainwindow.cpp b/win-linux/src/windows/cmainwindow.cpp index c509c1b90..525c9ed02 100644 --- a/win-linux/src/windows/cmainwindow.cpp +++ b/win-linux/src/windows/cmainwindow.cpp @@ -147,6 +147,8 @@ int CMainWindow::attachEditor(QWidget * panel, int index) int CMainWindow::attachEditor(QWidget * panel, const QPoint& pt) { QPoint _pt_local = tabWidget()->tabBar()->mapFromGlobal(pt); + if (AscAppManager::isRtlEnabled()) + _pt_local -= QPoint(32 * m_dpiRatio, 0); // Minus tabScroll width #ifdef Q_OS_WIN # if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0)) QPoint _tl = windowRect().topLeft(); @@ -176,7 +178,9 @@ bool CMainWindow::pointInTabs(const QPoint& pt) { QRect _rc_title(m_pMainPanel->geometry()); _rc_title.setHeight(tabWidget()->tabBar()->height()); - _rc_title.adjust(m_pButtonMain->width(), 1, -3*int(TITLEBTN_WIDTH*m_dpiRatio), 0); + int dx1 = (AscAppManager::isRtlEnabled()) ? 3 * int(TITLEBTN_WIDTH * m_dpiRatio) : m_pButtonMain->width(); + int dx2 = (AscAppManager::isRtlEnabled()) ? -1 * m_pButtonMain->width() : -3 * int(TITLEBTN_WIDTH * m_dpiRatio); + _rc_title.adjust(dx1, 1, dx2, 0); return _rc_title.contains(mapFromGlobal(pt)); } @@ -367,6 +371,7 @@ QWidget* CMainWindow::createMainPanel(QWidget *parent) { QWidget *mainPanel = new QWidget(parent); mainPanel->setObjectName("mainPanel"); + mainPanel->setProperty("rtl", AscAppManager::isRtlEnabled()); QGridLayout *_pMainGridLayout = new QGridLayout(mainPanel); _pMainGridLayout->setSpacing(0); _pMainGridLayout->setObjectName(QString::fromUtf8("mainGridLayout")); @@ -999,6 +1004,7 @@ void CMainWindow::onDocumentDownload(void * info) }); QHBoxLayout * layoutBtns = qobject_cast(m_boxTitleBtns->layout()); layoutBtns->insertWidget(1, m_pWidgetDownload->toolButton()); + m_pWidgetDownload->setLayoutDirection(AscAppManager::isRtlEnabled() ? Qt::RightToLeft : Qt::LeftToRight); m_pWidgetDownload->setStyleSheet(Utils::readStylesheets(":/styles/download.qss")); m_pWidgetDownload->applyTheme(m_pMainPanel->property("uitheme").toString()); m_pWidgetDownload->updateScalingFactor(m_dpiRatio); @@ -1484,3 +1490,12 @@ void CMainWindow::cancelClose() { m_isCloseAll && (m_isCloseAll = false); } + +void CMainWindow::onLayoutDirectionChanged() +{ + m_pButtonMain->style()->polish(m_pButtonMain); + if (m_pWidgetDownload && m_pWidgetDownload->toolButton()) { + m_pWidgetDownload->onLayoutDirectionChanged(); + m_pWidgetDownload->toolButton()->style()->polish(m_pWidgetDownload->toolButton()); + } +} diff --git a/win-linux/src/windows/cmainwindow.h b/win-linux/src/windows/cmainwindow.h index 77e04e2c7..d528af6b2 100644 --- a/win-linux/src/windows/cmainwindow.h +++ b/win-linux/src/windows/cmainwindow.h @@ -106,6 +106,7 @@ class CMainWindow : public CWindowPlatform, public CScalingWrapper protected: virtual QString getSaveMessage() const; virtual void refreshAboutVersion() {}; + virtual void onLayoutDirectionChanged() final; void closeEvent(QCloseEvent *) override; void showEvent(QShowEvent *) override; diff --git a/win-linux/src/windows/cpresenterwindow.cpp b/win-linux/src/windows/cpresenterwindow.cpp index 449fbb640..d4d0e153e 100644 --- a/win-linux/src/windows/cpresenterwindow.cpp +++ b/win-linux/src/windows/cpresenterwindow.cpp @@ -99,6 +99,11 @@ void CPresenterWindow::closeEvent(QCloseEvent *e) e->ignore(); } +void CPresenterWindow::onLayoutDirectionChanged() +{ + +} + /** Private **/ QWidget * CPresenterWindow::createMainPanel(QWidget * parent, const QString& title, QWidget * view) diff --git a/win-linux/src/windows/cpresenterwindow.h b/win-linux/src/windows/cpresenterwindow.h index 62254bff8..b14a5a4a5 100644 --- a/win-linux/src/windows/cpresenterwindow.h +++ b/win-linux/src/windows/cpresenterwindow.h @@ -52,6 +52,7 @@ class CPresenterWindow : public CWindowPlatform protected: void closeEvent(QCloseEvent *) final; + virtual void onLayoutDirectionChanged() final; private: QWidget * createMainPanel(QWidget *, const QString&, QWidget * view = nullptr); diff --git a/win-linux/src/windows/platform_linux/cwindowplatform.cpp b/win-linux/src/windows/platform_linux/cwindowplatform.cpp index c8ba15ad1..32086a30b 100644 --- a/win-linux/src/windows/platform_linux/cwindowplatform.cpp +++ b/win-linux/src/windows/platform_linux/cwindowplatform.cpp @@ -49,6 +49,8 @@ CWindowPlatform::CWindowPlatform(const QRect &rect) : CWindowBase(rect), CX11Decoration(this) { + if (AscAppManager::isRtlEnabled()) + setLayoutDirection(Qt::RightToLeft); if (isCustomWindowStyle()) { if (QX11Info::isCompositingManagerRunning()) setAttribute(Qt::WA_TranslucentBackground); @@ -120,6 +122,12 @@ bool CWindowPlatform::event(QEvent * event) if (event->type() == QEvent::HoverLeave) { if (m_boxTitleBtns) m_boxTitleBtns->setCursor(QCursor(Qt::ArrowCursor)); + } else + if (event->type() == QEvent::LayoutDirectionChange) { + if (m_pMainPanel) { + m_pMainPanel->setProperty("rtl", AscAppManager::isRtlEnabled()); + onLayoutDirectionChanged(); + } } return CWindowBase::event(event); } diff --git a/win-linux/src/windows/platform_linux/cwindowplatform.h b/win-linux/src/windows/platform_linux/cwindowplatform.h index 02a194bc9..b64a55b5b 100644 --- a/win-linux/src/windows/platform_linux/cwindowplatform.h +++ b/win-linux/src/windows/platform_linux/cwindowplatform.h @@ -54,6 +54,7 @@ class CWindowPlatform : public CWindowBase, public CX11Decoration virtual bool nativeEvent(const QByteArray&, void*, long*) final; virtual void setScreenScalingFactor(double, bool resize = true) override; virtual void paintEvent(QPaintEvent *event) override; + virtual void onLayoutDirectionChanged() = 0; private: virtual void mouseMoveEvent(QMouseEvent *) final; diff --git a/win-linux/src/windows/platform_win/cwindowplatform.cpp b/win-linux/src/windows/platform_win/cwindowplatform.cpp index 7f80461b4..90452bb4c 100644 --- a/win-linux/src/windows/platform_win/cwindowplatform.cpp +++ b/win-linux/src/windows/platform_win/cwindowplatform.cpp @@ -55,6 +55,8 @@ CWindowPlatform::CWindowPlatform(const QRect &rect) : m_isResizeable(true), m_allowMaximize(true) { + if (AscAppManager::isRtlEnabled()) + setLayoutDirection(Qt::RightToLeft); setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMaximizeButtonHint |Qt::WindowMinimizeButtonHint | Qt::MSWindowsFixedSizeDialogHint); @@ -151,6 +153,17 @@ bool CWindowPlatform::isSessionInProgress() return m_isSessionInProgress; } +bool CWindowPlatform::event(QEvent * event) +{ + if (event->type() == QEvent::LayoutDirectionChange) { + if (m_pMainPanel) { + m_pMainPanel->setProperty("rtl", AscAppManager::isRtlEnabled()); + onLayoutDirectionChanged(); + } + } + return CWindowBase::event(event); +} + /** Private **/ bool CWindowPlatform::isTaskbarAutoHideOn() diff --git a/win-linux/src/windows/platform_win/cwindowplatform.h b/win-linux/src/windows/platform_win/cwindowplatform.h index fbe592305..0dfa13124 100644 --- a/win-linux/src/windows/platform_win/cwindowplatform.h +++ b/win-linux/src/windows/platform_win/cwindowplatform.h @@ -54,6 +54,8 @@ class CWindowPlatform : public CWindowBase protected: bool isSessionInProgress(); + virtual bool event(QEvent *event) override; + virtual void onLayoutDirectionChanged() = 0; private: bool isTaskbarAutoHideOn(); From dc6c31934b0a6105abb578ad5ddd02d27fe0f4f3 Mon Sep 17 00:00:00 2001 From: maxkadushkin Date: Fri, 1 Dec 2023 01:01:05 +0300 Subject: [PATCH 4/7] [win-nix] added option to turn on rtl mode --- common/loginpage/src/panelsettings.js | 22 ++++++++++++++++++++++ common/loginpage/src/styles.less | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/common/loginpage/src/panelsettings.js b/common/loginpage/src/panelsettings.js index 687516e3c..298a4d9ec 100644 --- a/common/loginpage/src/panelsettings.js +++ b/common/loginpage/src/panelsettings.js @@ -260,6 +260,12 @@ +
@@ -300,6 +306,7 @@ $optsSpellcheckMode, $optsLaunchMode, $optsAutoupdateMode; + let $chRtl; function _set_user_name(name) { let me = this; @@ -404,6 +411,10 @@ $optsSpellcheckMode.selectpicker('refresh'); } + if ( $chRtl ) { + _new_settings.rtl = $chRtl.prop("checked"); + } + sdk.command("settings:apply", JSON.stringify(_new_settings)); $btnApply.disable(true); @@ -587,6 +598,17 @@ } } + if ( opts.rtl !== undefined ) { + $chRtl = $('#sett-box-rtl-mode', $panel).parent().show().find('#sett-rtl-mode'); + $chRtl.prop('checked', !!opts.rtl) + .on('change', e => { + $btnApply.prop('disabled') && $btnApply.prop('disabled', false); + }); + + document.body.setAttribute('dir', 'rtl'); + document.body.classList.add('rtl'); + } + $('.settings-field:visible:last').css('margin-bottom','0'); } else if (/updates/.test(cmd)) { diff --git a/common/loginpage/src/styles.less b/common/loginpage/src/styles.less index f219c24aa..797ce3d72 100644 --- a/common/loginpage/src/styles.less +++ b/common/loginpage/src/styles.less @@ -1175,7 +1175,7 @@ li.menu-item { } } -#sett-preview-mode { +.checkbox { width: 12px; height: 18px; margin-right: 16px; From c54f7e1cc7b2ee7371e16b10eab3db5f87453fa7 Mon Sep 17 00:00:00 2001 From: maxkadushkin Date: Fri, 1 Dec 2023 01:10:31 +0300 Subject: [PATCH 5/7] [win-nix] debug --- common/loginpage/src/panelsettings.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/loginpage/src/panelsettings.js b/common/loginpage/src/panelsettings.js index 298a4d9ec..ffa9bf33a 100644 --- a/common/loginpage/src/panelsettings.js +++ b/common/loginpage/src/panelsettings.js @@ -605,8 +605,10 @@ $btnApply.prop('disabled') && $btnApply.prop('disabled', false); }); - document.body.setAttribute('dir', 'rtl'); - document.body.classList.add('rtl'); + if ( opts.rtl ) { + document.body.setAttribute('dir', 'rtl'); + document.body.classList.add('rtl'); + } } $('.settings-field:visible:last').css('margin-bottom','0'); From 83dd746076fdd478261b105fab5c0414be0fcc8b Mon Sep 17 00:00:00 2001 From: maxkadushkin Date: Mon, 4 Dec 2023 14:43:50 +0300 Subject: [PATCH 6/7] [start page] fix stylesheet for rtl --- common/loginpage/build/Gruntfile.js | 4 +--- common/loginpage/build/startpage.json | 7 +++++-- common/loginpage/src/index.html | 1 + common/loginpage/src/index.html.deploy | 1 + common/loginpage/src/panelsettings.js | 2 +- common/loginpage/src/styles.less | 5 +++++ 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/common/loginpage/build/Gruntfile.js b/common/loginpage/build/Gruntfile.js index 65211495a..0671ba270 100644 --- a/common/loginpage/build/Gruntfile.js +++ b/common/loginpage/build/Gruntfile.js @@ -52,9 +52,7 @@ module.exports = function(grunt) { compress: true, ieCompat: false }, - files: { - "<%= pkg.desktop.less.files.dest %>": packageFile['desktop']['less']['files']['src'] - } + files: packageFile.desktop.less.files } }, diff --git a/common/loginpage/build/startpage.json b/common/loginpage/build/startpage.json index 1da51033f..c2f37f6e8 100644 --- a/common/loginpage/build/startpage.json +++ b/common/loginpage/build/startpage.json @@ -54,10 +54,13 @@ ] }, "less": { - "files": { + "files": [{ "src": "../src/styles.less", "dest": "../deploy/styles.css" - } + },{ + "src": "../src/css/rtl.less", + "dest": "../deploy/rtl.css" + }] }, "concat": { "files": { diff --git a/common/loginpage/src/index.html b/common/loginpage/src/index.html index d52299efd..292fb5b7b 100644 --- a/common/loginpage/src/index.html +++ b/common/loginpage/src/index.html @@ -9,6 +9,7 @@ + diff --git a/common/loginpage/src/index.html.deploy b/common/loginpage/src/index.html.deploy index 369cf0621..80fd91336 100644 --- a/common/loginpage/src/index.html.deploy +++ b/common/loginpage/src/index.html.deploy @@ -5,6 +5,7 @@ +