feat: support horizontal scroll modifiers

This commit is contained in:
sithlord48 2026-02-13 17:29:35 -05:00 committed by Chris Rizzitello
parent f6b1546f8b
commit 042abd699d
11 changed files with 262 additions and 137 deletions

View file

@ -204,7 +204,7 @@ QVariant Settings::defaultValue(const QString &key)
if (key == Daemon::LogFile) if (key == Daemon::LogFile)
return QStringLiteral("%1/%2-daemon.log").arg(Settings::settingsPath(), kAppId); return QStringLiteral("%1/%2-daemon.log").arg(Settings::settingsPath(), kAppId);
if (key == Client::YScrollScale) if (key == Client::YScrollScale || key == Client::XScrollScale)
return 1.0; return 1.0;
return QVariant(); return QVariant();

View file

@ -35,7 +35,9 @@ public:
struct Client struct Client
{ {
inline static const auto InvertYScroll = QStringLiteral("client/invertYScroll"); inline static const auto InvertYScroll = QStringLiteral("client/invertYScroll");
inline static const auto InvertXScroll = QStringLiteral("client/invertXScroll");
inline static const auto YScrollScale = QStringLiteral("client/yScrollScale"); inline static const auto YScrollScale = QStringLiteral("client/yScrollScale");
inline static const auto XScrollScale = QStringLiteral("client/xScrollScale");
inline static const auto LanguageSync = QStringLiteral("client/languageSync"); inline static const auto LanguageSync = QStringLiteral("client/languageSync");
inline static const auto RemoteHost = QStringLiteral("client/remoteHost"); inline static const auto RemoteHost = QStringLiteral("client/remoteHost");
inline static const auto XdpRestoreToken = QStringLiteral("client/xdpRestoreToken"); inline static const auto XdpRestoreToken = QStringLiteral("client/xdpRestoreToken");
@ -192,9 +194,11 @@ private:
inline static const QStringList m_validKeys = { inline static const QStringList m_validKeys = {
Settings::Client::InvertYScroll Settings::Client::InvertYScroll
, Settings::Client::InvertXScroll
, Settings::Client::LanguageSync , Settings::Client::LanguageSync
, Settings::Client::RemoteHost , Settings::Client::RemoteHost
, Settings::Client::YScrollScale , Settings::Client::YScrollScale
, Settings::Client::XScrollScale
, Settings::Client::XdpRestoreToken , Settings::Client::XdpRestoreToken
, Settings::Core::CoreMode , Settings::Core::CoreMode
, Settings::Core::Interface , Settings::Core::Interface
@ -247,6 +251,7 @@ private:
, Settings::Core::UseWlClipboard , Settings::Core::UseWlClipboard
, Settings::Server::ExternalConfig , Settings::Server::ExternalConfig
, Settings::Client::InvertYScroll , Settings::Client::InvertYScroll
, Settings::Client::InvertXScroll
, Settings::Log::ToFile , Settings::Log::ToFile
, Settings::Log::GuiDebug , Settings::Log::GuiDebug
}; };

View file

@ -22,8 +22,10 @@ class ISecondaryScreen
public: public:
ISecondaryScreen() ISecondaryScreen()
{ {
m_invertScroll = Settings::value(Settings::Client::InvertYScroll).toBool(); m_invertYScroll = Settings::value(Settings::Client::InvertYScroll).toBool();
m_scrollScale = std::clamp(Settings::value(Settings::Client::YScrollScale).toDouble(), 0.1, 10.0); m_yScrollScale = std::clamp(Settings::value(Settings::Client::YScrollScale).toDouble(), 0.1, 10.0);
m_invertXScroll = Settings::value(Settings::Client::InvertXScroll).toBool();
m_xScrollScale = std::clamp(Settings::value(Settings::Client::XScrollScale).toDouble(), 0.1, 10.0);
} }
virtual ~ISecondaryScreen() = default; virtual ~ISecondaryScreen() = default;
@ -63,21 +65,34 @@ public:
*/ */
ScrollDelta applyScrollModifier(ScrollDelta delta) const ScrollDelta applyScrollModifier(ScrollDelta delta) const
{ {
delta.y = static_cast<int32_t>(m_invertScroll ? delta.y * -m_scrollScale : delta.y * m_scrollScale); delta.y = static_cast<int32_t>(m_invertYScroll ? delta.y * -m_yScrollScale : delta.y * m_yScrollScale);
delta.x = static_cast<int32_t>(m_invertXScroll ? delta.x * -m_xScrollScale : delta.x * m_xScrollScale);
return delta; return delta;
} }
private: private:
/** /**
* @brief this member is used to modify the scroll direction. * @brief this member is used to modify the verical scroll direction.
* It is used in the applyScrollModifier method * It is used in the applyScrollModifier method
*/ */
bool m_invertScroll = false; bool m_invertYScroll = false;
/** /**
* @brief this member is used to modify the scroll scale. * @brief this member is used to modify the vertical scroll scale.
* It is used in the applyScrollModifier method * It is used in the applyScrollModifier method
*/ */
double m_scrollScale = 1.0; double m_yScrollScale = 1.0;
/**
* @brief this member is used to modify the horizontal scroll direction.
* It is used in the applyScrollModifier method
*/
bool m_invertXScroll = false;
/**
* @brief this member is used to modify the horizontal scroll scale.
* It is used in the applyScrollModifier method
*/
double m_xScrollScale = 1.0;
//@} //@}
}; };

View file

@ -55,20 +55,26 @@ void ClientConfigDialog::initConnections() const
connect(ui->cbLanguageSync, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons); connect(ui->cbLanguageSync, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons);
connect(ui->cbYScrollInvert, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons); connect(ui->cbYScrollInvert, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons);
connect(ui->sbYScrollScale, &QDoubleSpinBox::valueChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons); connect(ui->sbYScrollScale, &QDoubleSpinBox::valueChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons);
connect(ui->cbXScrollInvert, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons);
connect(ui->sbXScrollScale, &QDoubleSpinBox::valueChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons);
} }
bool ClientConfigDialog::isModified() const bool ClientConfigDialog::isModified() const
{ {
return (ui->cbLanguageSync->isChecked() != Settings::value(Settings::Client::LanguageSync).toBool()) || return (ui->cbLanguageSync->isChecked() != Settings::value(Settings::Client::LanguageSync).toBool()) ||
(ui->cbYScrollInvert->isChecked() != Settings::value(Settings::Client::InvertYScroll).toBool()) || (ui->cbYScrollInvert->isChecked() != Settings::value(Settings::Client::InvertYScroll).toBool()) ||
(ui->sbYScrollScale->value() != Settings::value(Settings::Client::YScrollScale).toDouble()); (ui->sbYScrollScale->value() != Settings::value(Settings::Client::YScrollScale).toDouble()) ||
(ui->cbXScrollInvert->isChecked() != Settings::value(Settings::Client::InvertXScroll).toBool()) ||
(ui->sbXScrollScale->value() != Settings::value(Settings::Client::XScrollScale).toDouble());
} }
bool ClientConfigDialog::isDefault() const bool ClientConfigDialog::isDefault() const
{ {
return (ui->cbLanguageSync->isChecked() == Settings::defaultValue(Settings::Client::LanguageSync).toBool()) && return (ui->cbLanguageSync->isChecked() == Settings::defaultValue(Settings::Client::LanguageSync).toBool()) &&
(ui->cbYScrollInvert->isChecked() == Settings::defaultValue(Settings::Client::InvertYScroll).toBool()) && (ui->cbYScrollInvert->isChecked() == Settings::defaultValue(Settings::Client::InvertYScroll).toBool()) &&
(ui->sbYScrollScale->value() == Settings::defaultValue(Settings::Client::YScrollScale).toDouble()); (ui->sbYScrollScale->value() == Settings::defaultValue(Settings::Client::YScrollScale).toDouble()) &&
(ui->cbXScrollInvert->isChecked() == Settings::defaultValue(Settings::Client::InvertXScroll).toBool()) &&
(ui->sbXScrollScale->value() == Settings::defaultValue(Settings::Client::XScrollScale).toDouble());
} }
void ClientConfigDialog::setButtonBoxEnabledButtons() const void ClientConfigDialog::setButtonBoxEnabledButtons() const
@ -84,6 +90,8 @@ void ClientConfigDialog::load()
ui->cbLanguageSync->setChecked(Settings::value(Settings::Client::LanguageSync).toBool()); ui->cbLanguageSync->setChecked(Settings::value(Settings::Client::LanguageSync).toBool());
ui->cbYScrollInvert->setChecked(Settings::value(Settings::Client::InvertYScroll).toBool()); ui->cbYScrollInvert->setChecked(Settings::value(Settings::Client::InvertYScroll).toBool());
ui->sbYScrollScale->setValue(Settings::value(Settings::Client::YScrollScale).toDouble()); ui->sbYScrollScale->setValue(Settings::value(Settings::Client::YScrollScale).toDouble());
ui->cbXScrollInvert->setChecked(Settings::value(Settings::Client::InvertXScroll).toBool());
ui->sbXScrollScale->setValue(Settings::value(Settings::Client::XScrollScale).toDouble());
} }
void ClientConfigDialog::resetToDefault() void ClientConfigDialog::resetToDefault()
@ -91,6 +99,8 @@ void ClientConfigDialog::resetToDefault()
ui->cbLanguageSync->setChecked(Settings::defaultValue(Settings::Client::LanguageSync).toBool()); ui->cbLanguageSync->setChecked(Settings::defaultValue(Settings::Client::LanguageSync).toBool());
ui->cbYScrollInvert->setChecked(Settings::defaultValue(Settings::Client::InvertYScroll).toBool()); ui->cbYScrollInvert->setChecked(Settings::defaultValue(Settings::Client::InvertYScroll).toBool());
ui->sbYScrollScale->setValue(Settings::defaultValue(Settings::Client::YScrollScale).toDouble()); ui->sbYScrollScale->setValue(Settings::defaultValue(Settings::Client::YScrollScale).toDouble());
ui->cbXScrollInvert->setChecked(Settings::defaultValue(Settings::Client::InvertXScroll).toBool());
ui->sbXScrollScale->setValue(Settings::defaultValue(Settings::Client::XScrollScale).toDouble());
} }
void ClientConfigDialog::save() void ClientConfigDialog::save()
@ -98,5 +108,7 @@ void ClientConfigDialog::save()
Settings::setValue(Settings::Client::LanguageSync, ui->cbLanguageSync->isChecked()); Settings::setValue(Settings::Client::LanguageSync, ui->cbLanguageSync->isChecked());
Settings::setValue(Settings::Client::InvertYScroll, ui->cbYScrollInvert->isChecked()); Settings::setValue(Settings::Client::InvertYScroll, ui->cbYScrollInvert->isChecked());
Settings::setValue(Settings::Client::YScrollScale, ui->sbYScrollScale->value()); Settings::setValue(Settings::Client::YScrollScale, ui->sbYScrollScale->value());
Settings::setValue(Settings::Client::InvertXScroll, ui->cbXScrollInvert->isChecked());
Settings::setValue(Settings::Client::XScrollScale, ui->sbXScrollScale->value());
QDialog::accept(); QDialog::accept();
} }

View file

@ -2,14 +2,6 @@
<ui version="4.0"> <ui version="4.0">
<class>ClientConfigDialog</class> <class>ClientConfigDialog</class>
<widget class="QDialog" name="ClientConfigDialog"> <widget class="QDialog" name="ClientConfigDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>425</width>
<height>148</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum"> <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -28,70 +20,132 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="cbYScrollInvert"> <widget class="QGroupBox" name="groupBox">
<property name="text"> <property name="title">
<string>Invert vertical scroll direction on this computer</string> <string>Scroll Modifiers</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="2">
<widget class="QCheckBox" name="cbYScrollInvert">
<property name="text">
<string>Invert</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="cbXScrollInvert">
<property name="text">
<string>Invert</string>
</property>
</widget>
</item>
<item row="5" column="4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="lblScrollSpeed">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Scale</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="sbYScrollScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="4">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="lblXScrollSpeed">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Scale</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="sbXScrollScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="lblHScroll">
<property name="text">
<string>Horizontal Scroll</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="lblVScroll">
<property name="text">
<string>Vertical Scroll</string>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="lblScrollSpeed">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Vertical Scroll Scale</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="sbYScrollScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
@ -105,38 +159,5 @@
</layout> </layout>
</widget> </widget>
<resources/> <resources/>
<connections> <connections/>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ClientConfigDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ClientConfigDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui> </ui>

View file

@ -150,12 +150,24 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">Utilice el idioma del teclado del servidor en esta computadora</translation> <translation type="unfinished">Utilice el idioma del teclado del servidor en esta computadora</translation>
</message> </message>
<message> <message>
<source>Invert vertical scroll direction on this computer</source> <source>Scroll Modifiers</source>
<translation type="unfinished">Invertir la dirección del desplazamiento vertical en este ordenador</translation> <translation type="unfinished">Modificadores de desplazamiento</translation>
</message> </message>
<message> <message>
<source>Vertical Scroll Scale</source> <source>Invert</source>
<translation type="unfinished">Escala de desplazamiento vertical</translation> <translation type="unfinished">Invertir</translation>
</message>
<message>
<source>Horizontal Scroll</source>
<translation type="unfinished">Desplazamiento horizontal</translation>
</message>
<message>
<source>Vertical Scroll</source>
<translation type="unfinished">Desplazamiento vertical</translation>
</message>
<message>
<source>Scale</source>
<translation type="unfinished">Escala</translation>
</message> </message>
<message> <message>
<source>Close and save changes</source> <source>Close and save changes</source>

View file

@ -150,12 +150,24 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">Usa la lingua della tastiera del server su questo computer</translation> <translation type="unfinished">Usa la lingua della tastiera del server su questo computer</translation>
</message> </message>
<message> <message>
<source>Invert vertical scroll direction on this computer</source> <source>Scroll Modifiers</source>
<translation type="unfinished">Inverti la direzione dello scorrimento verticale su questo computer</translation> <translation type="unfinished">Modificatori di scorrimento</translation>
</message> </message>
<message> <message>
<source>Vertical Scroll Scale</source> <source>Invert</source>
<translation type="unfinished">Scala di scorrimento verticale</translation> <translation type="unfinished">Invertire</translation>
</message>
<message>
<source>Horizontal Scroll</source>
<translation type="unfinished">Scorrimento orizzontale</translation>
</message>
<message>
<source>Vertical Scroll</source>
<translation type="unfinished">Scorrimento verticale</translation>
</message>
<message>
<source>Scale</source>
<translation type="unfinished">Scala</translation>
</message> </message>
<message> <message>
<source>Close and save changes</source> <source>Close and save changes</source>

View file

@ -150,12 +150,24 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">サーバー側のキーボード言語をこのコンピューターで使用する</translation> <translation type="unfinished">サーバー側のキーボード言語をこのコンピューターで使用する</translation>
</message> </message>
<message> <message>
<source>Invert vertical scroll direction on this computer</source> <source>Scroll Modifiers</source>
<translation type="unfinished">このコンピューターで垂直スクロールの方向を反転させる</translation> <translation type="unfinished">スクロール修飾子</translation>
</message> </message>
<message> <message>
<source>Vertical Scroll Scale</source> <source>Invert</source>
<translation type="unfinished">垂直スクロールスケール</translation> <translation type="unfinished">反転</translation>
</message>
<message>
<source>Horizontal Scroll</source>
<translation type="unfinished">水平スクロール</translation>
</message>
<message>
<source>Vertical Scroll</source>
<translation type="unfinished">垂直スクロール</translation>
</message>
<message>
<source>Scale</source>
<translation type="unfinished">規模</translation>
</message> </message>
<message> <message>
<source>Close and save changes</source> <source>Close and save changes</source>

View file

@ -150,12 +150,24 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">이 컴퓨터에서 서버의 키보드 언어 사용</translation> <translation type="unfinished">이 컴퓨터에서 서버의 키보드 언어 사용</translation>
</message> </message>
<message> <message>
<source>Invert vertical scroll direction on this computer</source> <source>Scroll Modifiers</source>
<translation type="unfinished">이 컴퓨터에서 세로 스크롤 방향을 반전합니다</translation> <translation type="unfinished">스크롤 수정자</translation>
</message> </message>
<message> <message>
<source>Vertical Scroll Scale</source> <source>Invert</source>
<translation type="unfinished">수직 스크롤 스케일</translation> <translation type="unfinished">거꾸로 하다</translation>
</message>
<message>
<source>Horizontal Scroll</source>
<translation type="unfinished">가로 스크롤</translation>
</message>
<message>
<source>Vertical Scroll</source>
<translation type="unfinished">세로 스크롤</translation>
</message>
<message>
<source>Scale</source>
<translation type="unfinished">규모</translation>
</message> </message>
<message> <message>
<source>Close and save changes</source> <source>Close and save changes</source>

View file

@ -150,12 +150,24 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">Использовать язык клавиатуры сервера на этом компьютере</translation> <translation type="unfinished">Использовать язык клавиатуры сервера на этом компьютере</translation>
</message> </message>
<message> <message>
<source>Invert vertical scroll direction on this computer</source> <source>Scroll Modifiers</source>
<translation type="unfinished">Инвертировать направление вертикальной прокрутки на этом компьютере</translation> <translation type="unfinished">Модификаторы прокрутки</translation>
</message> </message>
<message> <message>
<source>Vertical Scroll Scale</source> <source>Invert</source>
<translation type="unfinished">Вертикальная шкала прокрутки</translation> <translation type="unfinished">Инвертировать</translation>
</message>
<message>
<source>Horizontal Scroll</source>
<translation type="unfinished">Горизонтальная прокрутка</translation>
</message>
<message>
<source>Vertical Scroll</source>
<translation type="unfinished">Вертикальная прокрутка</translation>
</message>
<message>
<source>Scale</source>
<translation type="unfinished">Шкала</translation>
</message> </message>
<message> <message>
<source>Close and save changes</source> <source>Close and save changes</source>

View file

@ -150,12 +150,24 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished">在此计算机上使用服务器的键盘语言</translation> <translation type="unfinished">在此计算机上使用服务器的键盘语言</translation>
</message> </message>
<message> <message>
<source>Invert vertical scroll direction on this computer</source> <source>Scroll Modifiers</source>
<translation type="unfinished">在此计算机上反转垂直滚动方向</translation> <translation type="unfinished">滚动修饰符</translation>
</message> </message>
<message> <message>
<source>Vertical Scroll Scale</source> <source>Invert</source>
<translation type="unfinished">垂直滚动比例</translation> <translation type="unfinished">倒置</translation>
</message>
<message>
<source>Horizontal Scroll</source>
<translation type="unfinished">水平滚动</translation>
</message>
<message>
<source>Vertical Scroll</source>
<translation type="unfinished">垂直滚动</translation>
</message>
<message>
<source>Scale</source>
<translation type="unfinished">规模</translation>
</message> </message>
<message> <message>
<source>Close and save changes</source> <source>Close and save changes</source>