Compare commits

..
8 Commits
Author SHA1 Message Date
yyc12345 72644c465c doc: update README
- update README to notice the development of SarasaCW Picture.
- temporarily remove the most of old README by HTML comment syntax. these contents will be restored and fixed once I finish refactoring.
2026-07-02 11:03:35 +08:00
yyc12345 7bea6e11cd refactor: remove appveyor config file
- all build work are passing by github. there is no need to keep appvoyer config file.
2026-07-02 10:38:30 +08:00
yyc12345 787ea75865 refactor: remove QMake project file
- remove QMake project file. it is already deprecated in original repository. all build should be run as CMake project.
2026-07-02 10:33:43 +08:00
blumia 46cc2e0dbe fix: show empty url list doesn't reset window title 2026-06-30 21:08:35 +08:00
blumia 9662079b9d fix(CI): Windows build FTBFS 2026-06-29 19:40:44 +08:00
blumia bc88fea667 feat(Windows): open window will be able to use system animation 2026-06-29 19:32:26 +08:00
blumia 2d9d214cea i18n: update ts files
Related: https://github.com/BLumia/pineapple-pictures/issues/147
2026-06-29 19:29:44 +08:00
blumia bbe5e485f4 feat: add option to provide a titlebar (default on) 2026-06-29 19:22:33 +08:00
75 changed files with 3852 additions and 3225 deletions
+35
View File
@@ -0,0 +1,35 @@
name: deepin 25 CI
on: [push, pull_request, workflow_dispatch]
jobs:
build-deepin-25-deb:
runs-on: ubuntu-latest
container:
image: linuxdeepin/deepin:crimson
options: --user root
steps:
- name: Update package lists and install basic tools
run: |
apt update
apt install -y git ca-certificates curl file
- uses: actions/checkout@v6
- name: Get build dept.
run: |
apt install -y cmake qt6-base-dev qt6-svg-dev qt6-tools-dev libexiv2-dev
- name: Build it
run: |
git config --global --add safe.directory '*' # to avoid "fatal: detected dubious ownership in repository at xxx"
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr .
cmake --build build -j
cd build
cpack -G DEB
- name: Try install it
run: |
cd build
apt install -y ./*.deb
- uses: actions/upload-artifact@v6
with:
name: deepin-25-deb-package
path: build/*.deb
+4
View File
@@ -125,6 +125,10 @@ jobs:
cmake --build build --config Release
cmake --install build --config Release --prefix "%PWD%\build"
echo ::endgroup::
echo ::group::===== passoc stuff =====
curl -fsSL -o passoc-standalone.zip https://github.com/BLumia/pineapple-assoc-manager/releases/latest/download/pineapple-assoc-manager-qt${{ matrix.qt_ver }}-standalone.zip
7z x passoc-standalone.zip passoc.exe -y -o"build/bin"
echo ::endgroup::
:: ------ pkg ------
windeployqt --verbose=2 --no-compiler-runtime --no-quick-import --no-translations --no-network --no-opengl-sw --no-system-d3d-compiler --no-system-dxc-compiler --skip-plugin-types tls,networkinformation build\bin\ppic.exe
robocopy ./dependencies_bin/bin build/bin *.dll
+18 -22
View File
@@ -4,7 +4,7 @@
cmake_minimum_required(VERSION 3.16)
project(pineapple-pictures VERSION 1.5.0) # don't forget to update NEWS file and AppStream metadata.
project(pineapple-pictures VERSION 1.4.1) # don't forget to update NEWS file and AppStream metadata.
include(GNUInstallDirs)
include(FeatureSummary)
@@ -16,11 +16,10 @@ set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD_REQUIRED ON)
set (CMAKE_AUTOMOC ON)
set (CMAKE_AUTORCC ON)
set (CMAKE_AUTOUIC ON)
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Core)
set (QT_MINIMUM_VERSION "6.5")
set (QT_MINIMUM_VERSION "6.4")
find_package(Qt${QT_VERSION_MAJOR} ${QT_MINIMUM_VERSION} REQUIRED
COMPONENTS Widgets Svg SvgWidgets LinguistTools
@@ -39,12 +38,16 @@ endif ()
set (PPIC_CPP_FILES
app/main.cpp
app/framelesswindow.cpp
app/mainwindow.cpp
app/actionmanager.cpp
app/graphicsview.cpp
app/graphicsscene.cpp
app/bottombuttongroup.cpp
app/titlebar.cpp
app/navigatorview.cpp
app/opacityhelper.cpp
app/toolbutton.cpp
app/settings.cpp
app/settingsdialog.cpp
app/aboutdialog.cpp
@@ -52,19 +55,21 @@ set (PPIC_CPP_FILES
app/metadatadialog.cpp
app/exiv2wrapper.cpp
app/playlistmanager.cpp
app/shortcutedit.cpp
app/fileopeneventhandler.cpp
app/playlistscout.cpp
app/playlistscouts/qtscout.cpp
app/playlistscouts/explorerscout.cpp
)
set (PPIC_HEADER_FILES
app/framelesswindow.h
app/mainwindow.h
app/actionmanager.h
app/graphicsview.h
app/graphicsscene.h
app/bottombuttongroup.h
app/titlebar.h
app/navigatorview.h
app/opacityhelper.h
app/toolbutton.h
app/settings.h
app/settingsdialog.h
app/aboutdialog.h
@@ -72,17 +77,8 @@ set (PPIC_HEADER_FILES
app/metadatadialog.h
app/exiv2wrapper.h
app/playlistmanager.h
app/shortcutedit.h
app/fileopeneventhandler.h
app/playlistscout.h
app/playlistscouts/qtscout.h
app/playlistscouts/explorerscout.h
)
set (PPIC_UI_FILES
app/settingsdialog.ui
app/aboutdialog.ui
app/metadatadialog.ui
app/mainwindow.ui
)
set (PPIC_QRC_FILES
@@ -107,7 +103,6 @@ endif ()
add_executable (${EXE_NAME}
${PPIC_HEADER_FILES}
${PPIC_CPP_FILES}
${PPIC_UI_FILES}
${PPIC_QRC_FILES}
${PPIC_RC_FILES}
)
@@ -124,11 +119,6 @@ else()
qt_add_translations(${EXE_NAME} ${ADD_TRANSLATIONS_ADDITIONAL_ARGS} TS_FILES ${PPIC_TS_FILES} QM_FILES_OUTPUT_VARIABLE PPIC_QM_FILES)
endif()
# YYC MARK:
# This is essential, otherwise Qt UIC generated UI header file
# can not find our header files if there are custom widgets inside UI file.
target_include_directories(${EXE_NAME} PRIVATE app/)
target_sources(${EXE_NAME} PRIVATE ${PPIC_QM_FILES})
target_link_libraries (${EXE_NAME} Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::SvgWidgets)
@@ -283,6 +273,12 @@ if (DEFINED QM_FILE_INSTALL_DIR)
endif()
if (WIN32)
install(
FILES dist/passoc/ppic.pacfg
DESTINATION ${CMAKE_INSTALL_BINDIR}
RENAME default-assoc.pacfg
)
install(
FILES
dist/passoc/generic.ico
-18
View File
@@ -1,21 +1,3 @@
Version 1.5.0
~~~~~~~~~~~~~
Released: 2026-07-04
Features:
* Introduced an optional titlebar that display file name and allows drag and double-click to move and toggle maximize state
* Windows: Now the application will use the system's built-in animation for open window animation
Bugfixes:
* Show empty url list should also reset window title to blank
Miscellaneous:
* Update translations
* Add vcs-browser link to AppStream metadata
Contributors:
Heimen Stoffels (vistaus), VenusGirl (VenusGirl)
Version 1.4.1
~~~~~~~~~~~~~
Released: 2026-04-05
+144 -62
View File
@@ -3,94 +3,176 @@
// SPDX-License-Identifier: MIT
#include "aboutdialog.h"
#include "ui_aboutdialog.h"
#include <QAbstractButton>
#include <QDialogButtonBox>
#include <QTextBrowser>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QFile>
using namespace Qt::Literals::StringLiterals;
static QString loadEmbeddedHtml(QString&& path) {
QFile htmlFile(path);
bool canOpenFile = htmlFile.open(QIODevice::ReadOnly);
QByteArray htmlRawContent = canOpenFile ? htmlFile.readAll() : QByteArrayLiteral("");
return QString::fromUtf8(htmlRawContent);
}
AboutDialog::AboutDialog(QWidget *parent)
: QDialog(parent), ui(new QT_PREPEND_NAMESPACE(Ui::AboutDialog))
: QDialog(parent)
, m_tabWidget(new QTabWidget)
, m_buttonBox(new QDialogButtonBox)
, m_helpTextEdit(new QTextBrowser)
, m_aboutTextEdit(new QTextBrowser)
, m_specialThanksTextEdit(new QTextBrowser)
, m_licenseTextEdit(new QTextBrowser)
, m_3rdPartyLibsTextEdit(new QTextBrowser)
{
ui->setupUi(this);
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
this->setWindowTitle(tr("About"));
// blumia: Chain two arg() here since it seems lupdate will remove one of them if we use
// the old `arg(QCoreApp::translate(), tr())` way, but it's worth to mention
// `arg(QCoreApp::translate(), this->tr())` works, but lupdate will complain about the usage.
const QString HELP_HTML = loadEmbeddedHtml(u":/plain/help.html"_s)
.arg(tr("General Help"))
.arg(tr("Launch application with image file path as argument to load the file."))
.arg(tr("Passing in a single image file will load all the images in that directory and start viewing from that image."))
.arg(tr("Passing in multiple image files lets you view them one by one."))
.arg(tr("Drag and drop image file onto the window is also supported."))
.arg(tr("None of the operations in this application will alter the pictures on disk."))
.arg(tr("Context Menu Help"))
.arg(tr("Keep transformation", "The same meaning of MainWindow's Keep transformation."))
.arg(tr("Avoid resetting the zoom/rotation/flip state that was applied to the image view when switching between images."))
.arg(tr("Checkerboard", "The same meaning of MainWindow's Checkerboard."))
.arg(tr("Checkerboard light and dark theme can be adjusted in the configuration window, or easily switch it by holding Shift and clicking the button."));
const QStringList helpStr {
u"<p>%1</p>"_s.arg(tr("Launch application with image file path as argument to load the file.")),
u"<p>%1</p>"_s.arg(tr("Drag and drop image file onto the window is also supported.")),
u"<p>%1</p>"_s.arg(tr("None of the operations in this application will alter the pictures on disk.")),
u"<p>%1</p>"_s.arg(tr("Context menu option explanation:")),
u"<ul>"_s,
// blumia: Chain two arg() here since it seems lupdate will remove one of them if we use
// the old `arg(QCoreApp::translate(), tr())` way, but it's worth to mention
// `arg(QCoreApp::translate(), this->tr())` works, but lupdate will complain about the usage.
u"<li><b>%1</b>:<br/>%2</li>"_s
.arg(QCoreApplication::translate("MainWindow", "Stay on top"))
.arg(tr("Make window stay on top of all other windows.")),
u"<li><b>%1</b>:<br/>%2</li>"_s
.arg(QCoreApplication::translate("MainWindow", "Protected mode"))
.arg(tr("Avoid close window accidentally. (eg. by double clicking the window)")),
u"<li><b>%1</b>:<br/>%2</li>"_s
.arg(QCoreApplication::translate("MainWindow", "Keep transformation", "The 'transformation' means the flip/rotation status that currently applied to the image view"))
.arg(tr("Avoid resetting the zoom/rotation/flip state that was applied to the image view when switching between images.")),
u"</ul>"_s
};
const QString APP_NAME_ARG = qApp->applicationDisplayName();
const QString APP_VERSION_ARG =
const QStringList aboutStr {
u"<center><img width='128' height='128' src=':/icons/app-icon.svg'/><br/>"_s,
qApp->applicationDisplayName(),
(u"<br/>"_s + tr("Version: %1").arg(
#ifdef GIT_DESCRIBE_VERSION_STRING
GIT_DESCRIBE_VERSION_STRING;
GIT_DESCRIBE_VERSION_STRING
#else
qApp->applicationVersion();
qApp->applicationVersion()
#endif // GIT_DESCRIBE_VERSION_STRING
const QString QT_VERSION_ARG = QT_VERSION_STR;
const QString QT_ARCH_ARG = QSysInfo::buildCpuArchitecture();
const QString ABOUT_HTML = loadEmbeddedHtml(u":/plain/about.html"_s)
.arg(APP_NAME_ARG)
.arg(tr("Version: %1").arg(APP_VERSION_ARG))
.arg(tr("Upstream author"))
.arg(tr("Hard fork author"))
.arg(tr("Logo designer"))
.arg(tr("Built with Qt %1 (%2)").arg(QT_VERSION_ARG).arg(QT_ARCH_ARG))
.arg(tr("Source code"));
)),
u"<hr/>"_s,
tr("Copyright (c) %1 %2", "%1 is year, %2 is the name of copyright holder(s)")
.arg(u"2026"_s, u"<a href='https://github.com/BLumia'>@BLumia</a>"_s),
u"<br/>"_s,
tr("Logo designed by %1").arg(u"<a href='https://github.com/Lovelyblack'>@Lovelyblack</a>"_s),
u"<hr/>"_s,
tr("Built with Qt %1 (%2)").arg(QT_VERSION_STR, QSysInfo::buildCpuArchitecture()),
QStringLiteral("<br/><a href='%1'>%2</a>").arg("https://github.com/BLumia/pineapple-pictures", tr("Source code")),
u"</center>"_s
};
const QString SPECIAL_THANKS_HTML = loadEmbeddedHtml(u":/plain/special-thanks.html"_s)
.arg(tr("Contributors"))
.arg(tr("List of contributors on GitHub"))
.arg(tr("Thanks to all people who contributed to this project."))
.arg(tr("Translators"))
.arg(tr("I would like to thank the following people who volunteered to translate this application."));
QFile translaterHtml(u":/plain/translators.html"_s);
bool canOpenFile = translaterHtml.open(QIODevice::ReadOnly);
const QByteArray & translatorList = canOpenFile ? translaterHtml.readAll() : QByteArrayLiteral("");
const QString LICENSE_HTML = loadEmbeddedHtml(u":/plain/license.html"_s)
.arg(tr("License"))
.arg(tr("This application is released under the MIT License."))
.arg(tr("License Verbatim Copy"));
const QStringList specialThanksStr {
u"<h1 align='center'>%1</h1><a href='%2'>%3</a><p>%4</p>"_s.arg(
tr("Contributors"),
u"https://github.com/BLumia/pineapple-pictures/graphs/contributors"_s,
tr("List of contributors on GitHub"),
tr("Thanks to all people who contributed to this project.")
),
const QString THIRD_PARTY_LIBS_HTML = loadEmbeddedHtml(u":/plain/third-party-libs.html"_s)
.arg(tr("Third-party Libraries"))
.arg(tr("This application is built on the following free software libraries.", "Free as in freedom"))
.arg(tr("Some of them are optional and might not be included with this distribution depending on the build environment."));
u"<h1 align='center'>%1</h1><p>%2</p>%3"_s.arg(
tr("Translators"),
tr("I would like to thank the following people who volunteered to translate this application."),
translatorList
)
};
ui->m_helpTextEdit->setHtml(HELP_HTML);
ui->m_aboutTextEdit->setHtml(ABOUT_HTML);
ui->m_specialThanksTextEdit->setHtml(SPECIAL_THANKS_HTML);
ui->m_licenseTextEdit->setHtml(LICENSE_HTML);
ui->m_3rdPartyLibsTextEdit->setHtml(THIRD_PARTY_LIBS_HTML);
const QStringList licenseStr {
u"<h1 align='center'><b>%1</b></h1>"_s.arg(tr("Your Rights")),
u"<p>%1</p><p>%2</p><ul><li>%3</li><li>%4</li><li>%5</li><li>%6</li></ul>"_s.arg(
tr("%1 is released under the MIT License."), // %1
tr("This license grants people a number of freedoms:"), // %2
tr("You are free to use %1, for any purpose"), // %3
tr("You are free to distribute %1"), // %4
tr("You can study how %1 works and change it"), // %5
tr("You can distribute changed versions of %1") // %6
).arg(u"<i>%1</i>"_s),
u"<p>%1</p>"_s.arg(tr("The MIT license guarantees you this freedom. Nobody is ever permitted to take it away.")),
u"<hr/><pre>%2</pre>"_s
};
connect(ui->m_buttonBox, QOverload<QAbstractButton *>::of(&QDialogButtonBox::clicked), this, [this](QAbstractButton * btn){
Q_UNUSED(btn)
const QString mitLicense(QStringLiteral(R"(Expat/MIT License
Copyright &copy; 2026 BLumia
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
)"));
const QStringList thirdPartyLibsStr {
u"<h1 align='center'><b>%1</b></h1>"_s.arg(tr("Third-party Libraries used by %1")),
tr("%1 is built on the following free software libraries:", "Free as in freedom"),
u"<ul>"_s,
#ifdef HAVE_EXIV2_VERSION
u"<li><a href='%1'>%2</a>: %3</li>"_s.arg("https://www.exiv2.org/", "Exiv2", "GPLv2"),
#endif // EXIV2_VERSION
u"<li><a href='%1'>%2</a>: %3</li>"_s.arg("https://www.qt.io/", "Qt", "GPLv2 + GPLv3 + LGPLv2.1 + LGPLv3"),
u"</ul>"_s
};
m_helpTextEdit->setText(helpStr.join('\n'));
m_aboutTextEdit->setText(aboutStr.join('\n'));
m_aboutTextEdit->setOpenExternalLinks(true);
m_specialThanksTextEdit->setText(specialThanksStr.join('\n'));
m_specialThanksTextEdit->setOpenExternalLinks(true);
m_licenseTextEdit->setText(licenseStr.join('\n').arg(qApp->applicationDisplayName(), mitLicense));
m_3rdPartyLibsTextEdit->setText(thirdPartyLibsStr.join('\n').arg(u"<i>%1</i>"_s).arg(qApp->applicationDisplayName()));
m_3rdPartyLibsTextEdit->setOpenExternalLinks(true);
m_tabWidget->addTab(m_helpTextEdit, tr("&Help"));
m_tabWidget->addTab(m_aboutTextEdit, tr("&About"));
m_tabWidget->addTab(m_specialThanksTextEdit, tr("&Special Thanks"));
m_tabWidget->addTab(m_licenseTextEdit, tr("&License"));
m_tabWidget->addTab(m_3rdPartyLibsTextEdit, tr("&Third-party Libraries"));
m_buttonBox->setStandardButtons(QDialogButtonBox::Close);
connect(m_buttonBox, QOverload<QAbstractButton *>::of(&QDialogButtonBox::clicked), this, [this](){
this->close();
});
setLayout(new QVBoxLayout);
layout()->addWidget(m_tabWidget);
layout()->addWidget(m_buttonBox);
setMinimumSize(361, 161); // not sure why it complain "Unable to set geometry"
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
}
AboutDialog::~AboutDialog()
{
delete ui;
}
QSize AboutDialog::sizeHint() const
+11 -4
View File
@@ -8,9 +8,9 @@
#include <QDialog>
QT_BEGIN_NAMESPACE
namespace Ui {
class AboutDialog;
}
class QTextBrowser;
class QTabWidget;
class QDialogButtonBox;
QT_END_NAMESPACE
class AboutDialog : public QDialog
@@ -23,7 +23,14 @@ public:
QSize sizeHint() const override;
private:
QT_PREPEND_NAMESPACE(Ui::AboutDialog) *ui;
QTabWidget * m_tabWidget = nullptr;
QDialogButtonBox * m_buttonBox = nullptr;
QTextBrowser * m_helpTextEdit = nullptr;
QTextBrowser * m_aboutTextEdit = nullptr;
QTextBrowser * m_specialThanksTextEdit = nullptr;
QTextBrowser * m_licenseTextEdit = nullptr;
QTextBrowser * m_3rdPartyLibsTextEdit = nullptr;
};
#endif // ABOUTDIALOG_H
-106
View File
@@ -1,106 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="windowTitle">
<string>About</string>
</property>
<property name="minimumSize">
<size>
<width>361</width>
<height>161</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="m_tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="helpTab">
<attribute name="title">
<string>&amp;Help</string>
</attribute>
<layout class="QVBoxLayout" name="helpTabLayout">
<item>
<widget class="QTextBrowser" name="m_helpTextEdit">
<property name="openExternalLinks">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="aboutTab">
<attribute name="title">
<string>&amp;About</string>
</attribute>
<layout class="QVBoxLayout" name="aboutTabLayout">
<item>
<widget class="QTextBrowser" name="m_aboutTextEdit">
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="specialThanksTab">
<attribute name="title">
<string>&amp;Special Thanks</string>
</attribute>
<layout class="QVBoxLayout" name="specialThanksTabLayout">
<item>
<widget class="QTextBrowser" name="m_specialThanksTextEdit">
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="licenseTab">
<attribute name="title">
<string>&amp;License</string>
</attribute>
<layout class="QVBoxLayout" name="licenseTabLayout">
<item>
<widget class="QTextBrowser" name="m_licenseTextEdit">
<property name="openExternalLinks">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="thirdPartyLibsTab">
<attribute name="title">
<string>&amp;Third-party Libraries</string>
</attribute>
<layout class="QVBoxLayout" name="thirdPartyLibsTabLayout">
<item>
<widget class="QTextBrowser" name="m_3rdPartyLibsTextEdit">
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="m_buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+83 -139
View File
@@ -4,17 +4,19 @@
#include "actionmanager.h"
#include "settings.h"
#include "mainwindow.h"
#include "playlistmanager.h"
#include "graphicsview.h"
#include "graphicsscene.h"
#include <QGuiApplication>
#include <QSvgRenderer>
#include <QPainter>
static QIcon loadHidpiIcon(const QString &resp, QSize sz = QSize(32, 32))
#define ICON_NAME(name)\
QStringLiteral(":/icons/" #name ".svg")
#define ACTION_NAME(s) QStringLiteral(STRIFY(s))
#define STRIFY(s) #s
QIcon ActionManager::loadHidpiIcon(const QString &resp, QSize sz)
{
QSvgRenderer r(resp);
QPixmap pm = QPixmap(sz * qApp->devicePixelRatio());
@@ -27,188 +29,130 @@ static QIcon loadHidpiIcon(const QString &resp, QSize sz = QSize(32, 32))
void ActionManager::setupAction(MainWindow *mainWindow)
{
// region: Action and Its Icon Creation
// Declare some convenient macros and lambdas.
#define ICON_NAME(name)\
QStringLiteral(":/icons/" #name ".svg")
#define ACTION_NAME(s) QStringLiteral(STRIFY(s))
#define STRIFY(s) #s
auto create_action = [] (QWidget *w, QAction **a, QString i, QString an, bool iconFromTheme = false) {
*a = new QAction(w);
if (!i.isNull())
(*a)->setIcon(iconFromTheme ? QIcon::fromTheme(i) : loadHidpiIcon(i));
(*a)->setIcon(iconFromTheme ? QIcon::fromTheme(i) : ActionManager::loadHidpiIcon(i));
(*a)->setObjectName(an);
w->addAction(*a);
};
/// This macro for register normal action.
#define CREATE_NEW_ACTION(w, a) create_action(w, &a, QString(), ACTION_NAME(a))
/// This macro for register Qt theme action.
#define CREATE_NEW_THEMEICON_ACTION(w, a, i) create_action(w, &a, QLatin1String(STRIFY(i)), ACTION_NAME(a), true)
/// This macro for register action with our custom icon.
#define CREATE_NEW_ICON_ACTION(w, a, i) create_action(w, &a, ICON_NAME(i), ACTION_NAME(a), false)
// TODO: We may replace all Qt theme icons to our custom icon for visual consistency.
// TODO: Some icons are invalid.
CREATE_NEW_ACTION(mainWindow, actionCopyPixmap);
CREATE_NEW_ACTION(mainWindow, actionCopyFilePath);
CREATE_NEW_ICON_ACTION(mainWindow, actionPrevPicture, go-previous);
CREATE_NEW_ICON_ACTION(mainWindow, actionNextPicture, go-next);
#define CREATE_NEW_ICON_ACTION(w, a, i) create_action(w, &a, ICON_NAME(i), ACTION_NAME(a))
CREATE_NEW_ICON_ACTION(mainWindow, actionActualSize, zoom-original);
CREATE_NEW_ICON_ACTION(mainWindow, actionFitToScreen, app-icon);
CREATE_NEW_ICON_ACTION(mainWindow, actionFitByWidth, app-icon);
CREATE_NEW_ICON_ACTION(mainWindow, actionFitByHeight, app-icon);
CREATE_NEW_ICON_ACTION(mainWindow, actionToggleMaximize, view-fullscreen);
CREATE_NEW_ICON_ACTION(mainWindow, actionZoomIn, zoom-in);
CREATE_NEW_ICON_ACTION(mainWindow, actionZoomOut, zoom-out);
CREATE_NEW_ICON_ACTION(mainWindow, actionFlipHorizontal, app-icon);
CREATE_NEW_ICON_ACTION(mainWindow, actionFlipVertical, app-icon);
CREATE_NEW_ICON_ACTION(mainWindow, actionToggleCheckerboard, view-background-checkerboard);
CREATE_NEW_ICON_ACTION(mainWindow, actionRotateClockwise, object-rotate-right);
CREATE_NEW_ICON_ACTION(mainWindow, actionRotateCounterClockwise, app-icon);
#undef CREATE_NEW_ICON_ACTION
#define CREATE_NEW_ACTION(w, a) create_action(w, &a, QString(), ACTION_NAME(a))
#define CREATE_NEW_THEMEICON_ACTION(w, a, i) create_action(w, &a, QLatin1String(STRIFY(i)), ACTION_NAME(a), true)
CREATE_NEW_ACTION(mainWindow, actionRotateCounterClockwise);
CREATE_NEW_ACTION(mainWindow, actionPrevPicture);
CREATE_NEW_ACTION(mainWindow, actionNextPicture);
CREATE_NEW_ACTION(mainWindow, actionToggleAvoidResetTransform);
CREATE_NEW_ACTION(mainWindow, actionToggleCheckerboard);
CREATE_NEW_ACTION(mainWindow, actionTogglePauseAnimation);
CREATE_NEW_ACTION(mainWindow, actionAnimationNextFrame);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionOpen, document-open);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionSaveAs, document-save-as);
CREATE_NEW_ACTION(mainWindow, actionHorizontalFlip);
CREATE_NEW_ACTION(mainWindow, actionFitInView);
CREATE_NEW_ACTION(mainWindow, actionFitByWidth);
CREATE_NEW_ACTION(mainWindow, actionFitLongImage);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionCopyPixmap, edit-copy);
CREATE_NEW_ACTION(mainWindow, actionCopyFilePath);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionPaste, edit-paste);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionTrash, edit-delete);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionLocateInFileManager, system-file-manager);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionProperties, document-properties);
CREATE_NEW_ACTION(mainWindow, actionToggleStayOnTop);
CREATE_NEW_ACTION(mainWindow, actionToggleProtectMode);
CREATE_NEW_ACTION(mainWindow, actionToggleAvoidResetTransform);
CREATE_NEW_ACTION(mainWindow, actionSettings);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionHelp, system-help);
// Remove convenient macros
#undef CREATE_NEW_ICON_ACTION
#undef CREATE_NEW_THEMEICON_ACTION
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionLocateInFileManager, system-file-manager);
CREATE_NEW_THEMEICON_ACTION(mainWindow, actionProperties, document-properties);
CREATE_NEW_ACTION(mainWindow, actionQuitApp);
#undef CREATE_NEW_ACTION
#undef CREATE_NEW_THEMEICON_ACTION
#undef STRIFY
#undef ACTION_NAME
#undef ICON_NAME
retranslateUi(mainWindow);
// endregion
QMetaObject::connectSlotsByName(mainWindow);
}
// region: Setup Checkable Action
void ActionManager::retranslateUi(MainWindow *mainWindow)
{
Q_UNUSED(mainWindow);
actionToggleAvoidResetTransform->setCheckable(true);
actionToggleCheckerboard->setCheckable(true);
actionTogglePauseAnimation->setCheckable(true);
actionOpen->setText(QCoreApplication::translate("MainWindow", "&Open...", nullptr));
actionSaveAs->setText(QCoreApplication::translate("MainWindow", "Save &As...", nullptr));
// endregion
// region: Action Translatable Text Setup
actionCopyPixmap->setText(QCoreApplication::translate("MainWindow", "Copy P&ixmap", nullptr));
actionCopyFilePath->setText(QCoreApplication::translate("MainWindow", "Copy &File Path", nullptr));
actionActualSize->setText(QCoreApplication::translate("MainWindow", "Actual size", nullptr));
actionToggleMaximize->setText(QCoreApplication::translate("MainWindow", "Toggle maximize", nullptr));
actionZoomIn->setText(QCoreApplication::translate("MainWindow", "Zoom in", nullptr));
actionZoomOut->setText(QCoreApplication::translate("MainWindow", "Zoom out", nullptr));
actionToggleCheckerboard->setText(QCoreApplication::translate("MainWindow", "Toggle Checkerboard", nullptr));
actionRotateClockwise->setText(QCoreApplication::translate("MainWindow", "Rotate right", nullptr));
actionRotateCounterClockwise->setText(QCoreApplication::translate("MainWindow", "Rotate left", nullptr));
actionPrevPicture->setText(QCoreApplication::translate("MainWindow", "Previous image", nullptr));
actionNextPicture->setText(QCoreApplication::translate("MainWindow", "Next image", nullptr));
actionActualSize->setText(QCoreApplication::translate("MainWindow", "Actual size", nullptr));
actionFitToScreen->setText(QCoreApplication::translate("MainWindow", "Fit to screen", nullptr));
actionFitByWidth->setText(QCoreApplication::translate("MainWindow", "Fit by width", nullptr));
actionFitByHeight->setText(QCoreApplication::translate("MainWindow", "Fit by height", nullptr));
actionZoomIn->setText(QCoreApplication::translate("MainWindow", "Zoom in", nullptr));
actionZoomOut->setText(QCoreApplication::translate("MainWindow", "Zoom out", nullptr));
actionFlipHorizontal->setText(QCoreApplication::translate("MainWindow", "Flip &Horizontally", nullptr));
actionFlipVertical->setText(QCoreApplication::translate("MainWindow", "Flip &Vertically", nullptr));
actionRotateClockwise->setText(QCoreApplication::translate("MainWindow", "Rotate right", nullptr));
actionRotateCounterClockwise->setText(QCoreApplication::translate("MainWindow", "Rotate left", nullptr));
actionToggleAvoidResetTransform->setText(QCoreApplication::translate("MainWindow", "Keep transformation", "The 'transformation' means the flip/rotation status that currently applied to the image view"));
actionToggleCheckerboard->setText(QCoreApplication::translate("MainWindow", "Toggle Checkerboard", nullptr));
actionTogglePauseAnimation->setText(QCoreApplication::translate("MainWindow", "Pause/Resume Animation", nullptr));
actionAnimationNextFrame->setText(QCoreApplication::translate("MainWindow", "Animation Go to Next Frame", nullptr));
actionHorizontalFlip->setText(QCoreApplication::translate("MainWindow", "Flip &Horizontally", nullptr));
actionFitInView->setText(QCoreApplication::translate("MainWindow", "Fit to view", nullptr));
actionFitByWidth->setText(QCoreApplication::translate("MainWindow", "Fit to width", nullptr));
actionFitLongImage->setText(QCoreApplication::translate("MainWindow", "Fit long image", nullptr));
actionCopyPixmap->setText(QCoreApplication::translate("MainWindow", "Copy P&ixmap", nullptr));
actionCopyFilePath->setText(QCoreApplication::translate("MainWindow", "Copy &File Path", nullptr));
actionPaste->setText(QCoreApplication::translate("MainWindow", "&Paste", nullptr));
actionTrash->setText(QCoreApplication::translate("MainWindow", "Move to Trash", nullptr));
actionToggleStayOnTop->setText(QCoreApplication::translate("MainWindow", "Stay on top", nullptr));
actionToggleProtectMode->setText(QCoreApplication::translate("MainWindow", "Protected mode", nullptr));
actionToggleAvoidResetTransform->setText(QCoreApplication::translate("MainWindow", "Keep transformation", "The 'transformation' means the flip/rotation status that currently applied to the image view"));
actionSettings->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr));
actionHelp->setText(QCoreApplication::translate("MainWindow", "Help", nullptr));
#ifdef Q_OS_WIN
actionLocateInFileManager->setText(
QCoreApplication::translate(
"MainWindow", "Show in File Explorer",
"File Explorer is the name of explorer.exe under Windows"
)
);
)
);
#else
actionLocateInFileManager->setText(QCoreApplication::translate("MainWindow", "Show in directory", nullptr));
#endif // Q_OS_WIN
actionProperties->setText(QCoreApplication::translate("MainWindow", "Properties", nullptr));
actionSettings->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr));
actionHelp->setText(QCoreApplication::translate("MainWindow", "Help", nullptr));
// endregion
QMetaObject::connectSlotsByName(mainWindow);
actionQuitApp->setText(QCoreApplication::translate("MainWindow", "Quit", nullptr));
}
void ActionManager::setupShortcuts()
{
actionCopyPixmap->setShortcut(QKeySequence::Copy);
actionPrevPicture->setShortcuts({
QKeySequence(Qt::Key_Left),
QKeySequence(Qt::Key_PageUp),
});
actionNextPicture->setShortcuts({
QKeySequence(Qt::Key_Right),
QKeySequence(Qt::Key_PageDown),
});
actionOpen->setShortcut(QKeySequence::Open);
actionSaveAs->setShortcut(QKeySequence::SaveAs);
actionActualSize->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
actionZoomIn->setShortcut(QKeySequence::ZoomIn);
actionZoomOut->setShortcut(QKeySequence::ZoomOut);
actionPrevPicture->setShortcuts({
QKeySequence(Qt::Key_PageUp),
QKeySequence(Qt::Key_Left),
});
actionNextPicture->setShortcuts({
QKeySequence(Qt::Key_PageDown),
QKeySequence(Qt::Key_Right),
});
actionHorizontalFlip->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_R));
actionCopyPixmap->setShortcut(QKeySequence::Copy);
actionPaste->setShortcut(QKeySequence::Paste);
actionTrash->setShortcut(QKeySequence::Delete);
actionProperties->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_I));
actionSettings->setShortcut(QKeySequence::Preferences);
actionHelp->setShortcut(QKeySequence::HelpContents);
}
void ActionManager::updateActionState(PlaylistManager* pm, GraphicsView* gv)
{
const auto* gs = gv->scene();
const auto* settings = Settings::instance();
// Update copy actions
bool canCopy = pm->currentIndex().has_value();
actionCopyPixmap->setEnabled(canCopy);
actionCopyFilePath->setEnabled(canCopy);
// Update Prev/Next Picture State
const int galleryFileCount = pm->totalCount();
const bool loopGallery = settings->loopGallery();
actionPrevPicture->setEnabled(galleryFileCount > 1 && (loopGallery || !pm->isFirstIndex()));
actionNextPicture->setEnabled(galleryFileCount > 1 && (loopGallery || !pm->isLastIndex()));
// Update Avoid Reset Transform
actionToggleAvoidResetTransform->setChecked(gv->isAvoidResetTransform());
// Update Checkerboard
actionToggleCheckerboard->setChecked(gv->isCheckerboard());
// Update Animation Graphics Action
bool canPauseAnimation = gs->canPauseAnimation();
actionTogglePauseAnimation->setEnabled(canPauseAnimation);
if (canPauseAnimation) {
actionTogglePauseAnimation->setChecked(gs->isPauseAnimation());
} else {
actionTogglePauseAnimation->setChecked(false);
}
bool canSkipAnimation = gs->canSkipAnimationFrame();
actionAnimationNextFrame->setEnabled(canSkipAnimation);
// Update trash, located in explorer and properties.
bool hasLoadedFile = pm->currentIndex().has_value();
actionTrash->setEnabled(hasLoadedFile);
actionLocateInFileManager->setEnabled(hasLoadedFile);
actionProperties->setEnabled(hasLoadedFile);
actionSettings->setShortcut(QKeySequence::Preferences);
actionProperties->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_I));
actionQuitApp->setShortcuts({
QKeySequence(Qt::Key_Space),
QKeySequence(Qt::Key_Escape)
});
}
+25 -25
View File
@@ -8,11 +8,7 @@
#include <QAction>
class MainWindow;
class PlaylistManager;
class GraphicsView;
/// Action Manager is separated from Main Window
/// to manage all actions specifically.
class ActionManager
{
public:
@@ -20,41 +16,45 @@ public:
~ActionManager() = default;
void setupAction(MainWindow * mainWindow);
void retranslateUi(MainWindow *MainWindow);
void setupShortcuts();
public slots:
void updateActionState(PlaylistManager* pm, GraphicsView* gv);
static QIcon loadHidpiIcon(const QString &resp, QSize sz = QSize(32, 32));
public:
QAction *actionCopyPixmap;
QAction *actionCopyFilePath;
QAction *actionOpen;
QAction *actionSaveAs;
QAction *actionActualSize;
QAction *actionToggleMaximize;
QAction *actionZoomIn;
QAction *actionZoomOut;
QAction *actionToggleCheckerboard;
QAction *actionRotateClockwise;
QAction *actionRotateCounterClockwise;
QAction *actionPrevPicture;
QAction *actionNextPicture;
QAction *actionActualSize;
QAction *actionFitToScreen;
QAction *actionFitByWidth;
QAction *actionFitByHeight;
QAction *actionZoomIn;
QAction *actionZoomOut;
QAction *actionFlipHorizontal;
QAction *actionFlipVertical;
QAction *actionRotateClockwise;
QAction *actionRotateCounterClockwise;
QAction *actionToggleAvoidResetTransform;
QAction *actionToggleCheckerboard;
QAction *actionTogglePauseAnimation;
QAction *actionAnimationNextFrame;
QAction *actionHorizontalFlip;
QAction *actionFitInView;
QAction *actionFitByWidth;
QAction *actionFitLongImage;
QAction *actionCopyPixmap;
QAction *actionCopyFilePath;
QAction *actionPaste;
QAction *actionTrash;
QAction *actionLocateInFileManager;
QAction *actionProperties;
QAction *actionToggleStayOnTop;
QAction *actionToggleProtectMode;
QAction *actionToggleAvoidResetTransform;
QAction *actionSettings;
QAction *actionHelp;
QAction *actionLocateInFileManager;
QAction *actionProperties;
QAction *actionQuitApp;
};
#endif // ACTIONMANAGER_H
+32 -20
View File
@@ -4,42 +4,54 @@
#include "bottombuttongroup.h"
#include "opacityhelper.h"
#include <QToolButton>
#include <QVBoxLayout>
#include <QDebug>
BottomButtonGroup::BottomButtonGroup(QWidget *parent)
BottomButtonGroup::BottomButtonGroup(const std::vector<QAction *> &actionList, QWidget *parent)
: QGroupBox (parent)
, m_opacityHelper(new OpacityHelper(this))
{
QHBoxLayout * mainLayout = new QHBoxLayout(this);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
this->setLayout(mainLayout);
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
this->setStyleSheet(R"#(
BottomButtonGroup {
border-style: none;
background: transparent;
}
QToolButton {
background: transparent;
border-style: none;
}
)#");
}
this->setStyleSheet("BottomButtonGroup {"
"border: 1px solid gray;"
"border-top-left-radius: 10px;"
"border-top-right-radius: 10px;"
"border-style: none;"
"background-color:rgba(0,0,0,120)"
"}"
"QToolButton {"
"background:transparent;"
"}"
"QToolButton:!focus {"
"border-style: none;"
"}");
void BottomButtonGroup::addActions(const std::vector<QAction *> & actionList) {
for (QAction * action : actionList) {
// Create button
auto newActionBtn = [this](QAction * action) -> QToolButton * {
QToolButton * btn = new QToolButton(this);
btn->setDefaultAction(action);
btn->setIconSize(QSize(32, 32));
btn->setFixedSize(40, 40);
// Add button
layout()->addWidget(btn);
return btn;
};
for (QAction * action : actionList) {
addButton(newActionBtn(action));
}
updateGeometry();
}
void BottomButtonGroup::addAction(QAction* action) {
addActions({action});
void BottomButtonGroup::setOpacity(qreal opacity, bool animated)
{
m_opacityHelper->setOpacity(opacity, animated);
}
void BottomButtonGroup::addButton(QAbstractButton *button)
{
layout()->addWidget(button);
updateGeometry();
}
+7 -3
View File
@@ -10,14 +10,18 @@
#include <QAbstractButton>
#include <QGroupBox>
class OpacityHelper;
class BottomButtonGroup : public QGroupBox
{
Q_OBJECT
public:
explicit BottomButtonGroup(QWidget *parent = nullptr);
explicit BottomButtonGroup(const std::vector<QAction *> & actionList, QWidget *parent = nullptr);
void addActions(const std::vector<QAction *> & actionList);
void addAction(QAction* action);
void setOpacity(qreal opacity, bool animated = true);
void addButton(QAbstractButton *button);
private:
OpacityHelper * m_opacityHelper;
};
#endif // BOTTOMBUTTONGROUP_H
+160
View File
@@ -0,0 +1,160 @@
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
// SPDX-FileCopyrightText: 2023 Tad Young <yyc12321@outlook.com>
//
// SPDX-License-Identifier: MIT
#include "framelesswindow.h"
#include <QMouseEvent>
#include <QHoverEvent>
#include <QApplication>
#include <QVBoxLayout>
#include <QWindow>
#ifdef Q_OS_WIN
#include "windows.h"
void fixWindowStyle(QWidget * that)
{
HWND hwnd = (HWND)that->winId();
LONG style = GetWindowLong(hwnd, GWL_STYLE);
style |= WS_THICKFRAME | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU;
SetWindowLong(hwnd, GWL_STYLE, style);
SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE |
SWP_NOZORDER | SWP_NOACTIVATE);
}
#endif
FramelessWindow::FramelessWindow(QWidget *parent)
: QWidget(parent)
, m_centralLayout(new QVBoxLayout(this))
, m_oldCursorShape(Qt::ArrowCursor)
, m_oldEdges()
{
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
this->setMouseTracking(true);
this->setAttribute(Qt::WA_Hover, true);
this->installEventFilter(this);
m_centralLayout->setContentsMargins(QMargins());
}
void FramelessWindow::setCentralWidget(QWidget *widget)
{
if (m_centralWidget) {
m_centralLayout->removeWidget(m_centralWidget);
m_centralWidget->deleteLater();
}
m_centralLayout->addWidget(widget);
m_centralWidget = widget;
}
void FramelessWindow::installResizeCapture(QObject* widget)
{
widget->installEventFilter(this);
}
void FramelessWindow::showEvent(QShowEvent *event)
{
#ifdef Q_OS_WIN
fixWindowStyle(this);
#endif // Q_OS_WIN
return QWidget::showEvent(event);
}
bool FramelessWindow::eventFilter(QObject* o, QEvent* e)
{
switch (e->type()) {
case QEvent::HoverMove:
{
QWidget* wg = qobject_cast<QWidget*>(o);
if (wg != nullptr)
return mouseHover(static_cast<QHoverEvent*>(e), wg);
break;
}
case QEvent::MouseButtonPress:
return mousePress(static_cast<QMouseEvent*>(e));
}
return QWidget::eventFilter(o, e);
}
bool FramelessWindow::mouseHover(QHoverEvent* event, QWidget* wg)
{
if (!isMaximized() && !isFullScreen()) {
QWindow* win = window()->windowHandle();
Qt::Edges edges = this->getEdgesByPos(wg->mapToGlobal(event->oldPos()), win->frameGeometry());
// backup & restore cursor shape
if (edges && !m_oldEdges)
// entering the edge. backup cursor shape
m_oldCursorShape = win->cursor().shape();
if (!edges && m_oldEdges)
// leaving the edge. restore cursor shape
win->setCursor(m_oldCursorShape);
// save the latest edges status
m_oldEdges = edges;
// show resize cursor shape if cursor is within border
if (edges) {
win->setCursor(this->getCursorByEdge(edges, Qt::ArrowCursor));
return true;
}
}
return false;
}
bool FramelessWindow::mousePress(QMouseEvent* event)
{
if (event->buttons() & Qt::LeftButton && !isMaximized() && !isFullScreen()) {
QWindow* win = window()->windowHandle();
Qt::Edges edges = this->getEdgesByPos(event->globalPosition().toPoint(), win->frameGeometry());
if (edges) {
win->startSystemResize(edges);
return true;
}
}
return false;
}
Qt::CursorShape FramelessWindow::getCursorByEdge(const Qt::Edges& edges, Qt::CursorShape default_cursor)
{
if ((edges == (Qt::TopEdge | Qt::LeftEdge)) || (edges == (Qt::RightEdge | Qt::BottomEdge)))
return Qt::SizeFDiagCursor;
else if ((edges == (Qt::TopEdge | Qt::RightEdge)) || (edges == (Qt::LeftEdge | Qt::BottomEdge)))
return Qt::SizeBDiagCursor;
else if (edges & (Qt::TopEdge | Qt::BottomEdge))
return Qt::SizeVerCursor;
else if (edges & (Qt::LeftEdge | Qt::RightEdge))
return Qt::SizeHorCursor;
else
return default_cursor;
}
Qt::Edges FramelessWindow::getEdgesByPos(const QPoint gpos, const QRect& winrect)
{
const int borderWidth = 8;
Qt::Edges edges;
int x = gpos.x() - winrect.x();
int y = gpos.y() - winrect.y();
if (x < borderWidth)
edges |= Qt::LeftEdge;
if (x > (winrect.width() - borderWidth))
edges |= Qt::RightEdge;
if (y < borderWidth)
edges |= Qt::TopEdge;
if (y > (winrect.height() - borderWidth))
edges |= Qt::BottomEdge;
return edges;
}
+42
View File
@@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
//
// SPDX-License-Identifier: MIT
#ifndef FRAMELESSWINDOW_H
#define FRAMELESSWINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QVBoxLayout;
QT_END_NAMESPACE
class FramelessWindow : public QWidget
{
Q_OBJECT
public:
explicit FramelessWindow(QWidget *parent = nullptr);
void setCentralWidget(QWidget * widget);
void installResizeCapture(QObject* widget);
protected slots:
void showEvent(QShowEvent *event) override;
protected:
bool eventFilter(QObject *o, QEvent *e) override;
bool mouseHover(QHoverEvent* event, QWidget* wg);
bool mousePress(QMouseEvent* event);
private:
Qt::Edges m_oldEdges;
Qt::CursorShape m_oldCursorShape;
Qt::CursorShape getCursorByEdge(const Qt::Edges& edges, Qt::CursorShape default_cursor);
Qt::Edges getEdgesByPos(const QPoint pos, const QRect& winrect);
QVBoxLayout * m_centralLayout = nullptr;
QWidget * m_centralWidget = nullptr; // just a pointer, doesn't take the ownership.
};
#endif // FRAMELESSWINDOW_H
+13 -85
View File
@@ -6,9 +6,6 @@
#include "settings.h"
#include <QStyleHints>
#include <QOperatingSystemVersion>
#include <QGuiApplication>
#include <QGraphicsSceneMouseEvent>
#include <QMimeData>
#include <QDebug>
@@ -19,33 +16,6 @@
#include <QMovie>
#include <QPainter>
static const QColor& ColorSchemaToTextForeground(Qt::ColorScheme colorScheme) {
// YYC MARK:
// If we are using Windows 10 and lower system or Qt which do not support "Windows 11"
// theme (lower than Qt 6.7), we should only support light mode.
// Because Qt's dark-mode-aware "Windows 11" theme is only well-supported on Windows 11.
#if defined(Q_OS_WIN)
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
colorScheme = Qt::ColorScheme::Light;
#else
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows11) {
colorScheme = Qt::ColorScheme::Light;
}
#endif // QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
#endif // defined(Q_OS_WIN)
switch (colorScheme) {
case Qt::ColorScheme::Dark:
static QColor WHITE = QColor("White");
return WHITE;
case Qt::ColorScheme::Light:
case Qt::ColorScheme::Unknown:
default:
static QColor BLACK = QColor("Black");
return BLACK;
}
}
class PGraphicsPixmapItem : public QGraphicsPixmapItem
{
public:
@@ -129,8 +99,7 @@ private:
GraphicsScene::GraphicsScene(QObject *parent)
: QGraphicsScene(parent)
{
showText(tr("Drag image here", "The same meaning of MainWindow's hint."));
connect(qGuiApp->styleHints(), &QStyleHints::colorSchemeChanged, this, &GraphicsScene::updateStyle);
showText(tr("Drag image here"));
}
GraphicsScene::~GraphicsScene()
@@ -152,7 +121,7 @@ void GraphicsScene::showText(const QString &text)
{
this->clear();
QGraphicsTextItem * textItem = this->addText(text);
textItem->setDefaultTextColor(ColorSchemaToTextForeground(qGuiApp->styleHints()->colorScheme()));
textItem->setDefaultTextColor(QColor("White"));
m_theThing = textItem;
this->setSceneRect(m_theThing->boundingRect());
}
@@ -200,57 +169,27 @@ bool GraphicsScene::trySetTransformationMode(Qt::TransformationMode mode, float
return false;
}
/// Fetch graphics item as our custom animated item.
/// Return nullptr means this item is not animated item.
static PGraphicsMovieItem* fetchAnimatedItem(QGraphicsItem *item) {
return qgraphicsitem_cast<PGraphicsMovieItem *>(item);
}
bool GraphicsScene::canPauseAnimation() const {
return fetchAnimatedItem(m_theThing) != nullptr;
}
bool GraphicsScene::isPauseAnimation() const {
auto* animatedItem = fetchAnimatedItem(m_theThing);
if (animatedItem != nullptr) {
return animatedItem->movie()->state() == QMovie::Paused;
} else {
return false;
}
}
bool GraphicsScene::togglePauseAnimation()
{
auto* animatedItem = fetchAnimatedItem(m_theThing);
if (animatedItem != nullptr) {
PGraphicsMovieItem * animatedItem = qgraphicsitem_cast<PGraphicsMovieItem *>(m_theThing);
if (animatedItem) {
animatedItem->movie()->setPaused(animatedItem->movie()->state() != QMovie::Paused);
return true;
} else {
return false;
}
}
bool GraphicsScene::canSkipAnimationFrame() const {
return isPauseAnimation();
return false;
}
bool GraphicsScene::skipAnimationFrame(int delta)
{
auto* animatedItem = fetchAnimatedItem(m_theThing);
// Only paused animated item can skip frame
if (animatedItem == nullptr) {
return false;
PGraphicsMovieItem * animatedItem = qgraphicsitem_cast<PGraphicsMovieItem *>(m_theThing);
if (animatedItem) {
const int frameCount = animatedItem->movie()->frameCount();
const int currentFrame = animatedItem->movie()->currentFrameNumber();
const int targetFrame = (currentFrame + delta) % frameCount;
animatedItem->movie()->setPaused(true);
return animatedItem->movie()->jumpToFrame(targetFrame);
}
if (animatedItem->movie()->state() != QMovie::Paused) {
return false;
}
// Perform skip
const int frameCount = animatedItem->movie()->frameCount();
const int currentFrame = animatedItem->movie()->currentFrameNumber();
const int targetFrame = (currentFrame + delta) % frameCount;
return animatedItem->movie()->jumpToFrame(targetFrame);
return false;
}
QPixmap GraphicsScene::renderToPixmap()
@@ -267,14 +206,3 @@ QPixmap GraphicsScene::renderToPixmap()
return pixmap;
}
void GraphicsScene::updateStyle(Qt::ColorScheme colorScheme) {
Q_UNUSED(colorScheme)
QGraphicsItem * item = this->m_theThing;
if (item == nullptr) return;
QGraphicsTextItem * textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
if (textItem == nullptr) return;
textItem->setDefaultTextColor(ColorSchemaToTextForeground(colorScheme));
}
-15
View File
@@ -21,26 +21,11 @@ public:
bool trySetTransformationMode(Qt::TransformationMode mode, float scaleHint);
/// Check whether current thing is animation.
/// Only animation thing can be paused.
bool canPauseAnimation() const;
/// Check whether we are pasuing an animation graphics.
bool isPauseAnimation() const;
/// Toggle animation graphics pause state.
/// Return true for successfully toggle, otherwise false.
bool togglePauseAnimation();
/// Check whether we can skip animation frame.
/// Only paused animation graphics can skip frame.
bool canSkipAnimationFrame() const;
/// Skip paused animation graphics with given frame.
/// Return true for successfully skip, otherwise false.
bool skipAnimationFrame(int delta = 1);
QPixmap renderToPixmap();
private slots:
void updateStyle(Qt::ColorScheme colorScheme);
private:
QGraphicsItem * m_theThing = nullptr;
};
+58 -66
View File
@@ -7,8 +7,6 @@
#include "graphicsscene.h"
#include "settings.h"
#include <QStyleHints>
#include <QOperatingSystemVersion>
#include <QDebug>
#include <QColorSpace>
#include <QMouseEvent>
@@ -25,12 +23,11 @@ GraphicsView::GraphicsView(QWidget *parent)
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setStyleSheet("background-color: rgba(0, 0, 0, 220);"
"border-radius: 3px;");
setAcceptDrops(false);
setCheckerboardEnabled(false);
updateStyle(qGuiApp->styleHints()->colorScheme());
connect(qGuiApp->styleHints(), &QStyleHints::colorSchemeChanged, this, &GraphicsView::updateStyle);
connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &GraphicsView::viewportRectChanged);
connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &GraphicsView::viewportRectChanged);
}
@@ -140,7 +137,8 @@ void GraphicsView::resetTransform()
void GraphicsView::zoomView(qreal scaleFactor)
{
m_enableFitToScreen = false;
m_enableFitInView = false;
m_longImageMode = false;
scale(scaleFactor, scaleFactor);
applyTransformationModeByScaleFactor();
emit navigatorViewRequired(!isThingSmallerThanWindowWith(transform()), transform());
@@ -223,19 +221,6 @@ void GraphicsView::fitByOrientation(Qt::Orientation ori, bool scaleDownOnly)
// Position the image correctly based on orientation with rotation consideration
QRectF originalScene = sceneRect();
QTransform currentTransform = transform();
// TODO:
// I guess following code may be optimized by matrix arithmetic operation.
// There is an AI given solution. But I didn't use it.
// Because I want to keep the same behavior of upstream.
// // Horizontal fit: Let the position of top center of viewport, (cx, 0), be inversely mapped to scene.
// // And compensate the behavior of `centerOn` which put given point to the center of viewport.
// QTransform inv = currentTransform.inverted();
// QPointF viewCx = viewport()->rect().center().x();
// QPointF viewCy = viewport()->rect().center().y();
// // The target is viewport top center. Its y=0, so `centerOn` required scene point is (viewCx, -viewCy).
// centerOn(inv.map(QPointF(viewCx, -viewCy)));
if (ori == Qt::Horizontal) {
// For horizontal fit (fit by width), position at top (for tall images)
@@ -289,12 +274,37 @@ void GraphicsView::fitByOrientation(Qt::Orientation ori, bool scaleDownOnly)
centerOn(sceneLeftCenter);
}
m_enableFitToScreen = false;
m_enableFitInView = false;
applyTransformationModeByScaleFactor();
emit navigatorViewRequired(!isThingSmallerThanWindowWith(transform()), transform());
}
bool GraphicsView::isLongImage() const
{
// Get the transformed image size (considering rotation and other transforms)
QRectF transformedRect = transform().mapRect(sceneRect());
QSizeF imageSize = transformedRect.size();
if (imageSize.isEmpty()) return false;
qreal aspectRatio = imageSize.width() / imageSize.height();
// Check if aspect ratio exceeds 5:2 (wide) or 2:5 (tall)
return aspectRatio > 2.5 || aspectRatio < 0.4;
}
void GraphicsView::fitLongImage()
{
QRectF transformedRect = transform().mapRect(sceneRect());
if (transformedRect.width() < transformedRect.height()) {
fitByOrientation(Qt::Horizontal, true);
} else {
fitByOrientation(Qt::Vertical, true);
}
}
void GraphicsView::displayScene()
{
if (shouldAvoidTransform()) {
@@ -302,6 +312,14 @@ void GraphicsView::displayScene()
return;
}
// Check if should apply long image mode
if (Settings::instance()->autoLongImageMode() && isLongImage()) {
m_longImageMode = true;
m_firstUserMediaLoaded = true;
if (isSceneBiggerThanView()) fitLongImage();
return;
}
if (isSceneBiggerThanView()) {
// Do fit-in-view
fitInView(sceneRect(), Qt::KeepAspectRatio);
@@ -312,7 +330,8 @@ void GraphicsView::displayScene()
emit navigatorViewRequired(false, transform());
}
m_enableFitToScreen = true;
m_longImageMode = false;
m_enableFitInView = true;
m_firstUserMediaLoaded = true;
}
@@ -326,12 +345,17 @@ bool GraphicsView::isSceneBiggerThanView() const
}
// Automately do fit in view when viewport(window) smaller than image original size.
void GraphicsView::setEnableAutoFitToScreen(bool enable)
void GraphicsView::setEnableAutoFitInView(bool enable)
{
m_enableFitToScreen = enable;
m_enableFitInView = enable;
}
bool GraphicsView::isAvoidResetTransform() const
void GraphicsView::setLongImageMode(bool enable)
{
m_longImageMode = enable;
}
bool GraphicsView::avoidResetTransform() const
{
return m_avoidResetTransform;
}
@@ -341,15 +365,6 @@ void GraphicsView::setAvoidResetTransform(bool avoidReset)
m_avoidResetTransform = avoidReset;
}
bool GraphicsView::isCheckerboard() const {
return m_checkerboardEnabled;
}
void GraphicsView::toggleCheckerboard(bool invertCheckerboardColor)
{
setCheckerboardEnabled(!m_checkerboardEnabled, invertCheckerboardColor);
}
inline double zeroOrOne(double number)
{
return qFuzzyIsNull(number) ? 0 : (number > 0 ? 1 : -1);
@@ -364,37 +379,9 @@ QTransform GraphicsView::resetScale(const QTransform & orig)
orig.dx(), orig.dy());
}
void GraphicsView::updateStyle(Qt::ColorScheme colorScheme) {
// YYC MARK:
// If we are using Windows 10 and lower system or Qt which do not support "Windows 11"
// theme (lower than Qt 6.7), we should only support light mode.
// Because Qt's dark-mode-aware "Windows 11" theme is only well-supported on Windows 11.
#if defined(Q_OS_WIN)
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
colorScheme = Qt::ColorScheme::Light;
#else
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows11) {
colorScheme = Qt::ColorScheme::Light;
}
#endif // QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
#endif // defined(Q_OS_WIN)
switch (colorScheme) {
case Qt::ColorScheme::Dark:
setStyleSheet(R"#(
border-style: none;
background-color: black;
)#");
break;
case Qt::ColorScheme::Light:
case Qt::ColorScheme::Unknown:
default:
setStyleSheet(R"#(
border-style: none;
background-color: white;
)#");
break;
}
void GraphicsView::toggleCheckerboard(bool invertCheckerboardColor)
{
setCheckerboardEnabled(!m_checkerboardEnabled, invertCheckerboardColor);
}
void GraphicsView::mousePressEvent(QMouseEvent *event)
@@ -440,11 +427,16 @@ void GraphicsView::wheelEvent(QWheelEvent *event)
void GraphicsView::resizeEvent(QResizeEvent *event)
{
if (m_enableFitToScreen) {
if (m_longImageMode) {
// In long image mode, reapply long image logic on resize
// We directly apply the long image mode logic without rechecking
// if we should enter long image mode, as the mode is already active
fitLongImage();
} else if (m_enableFitInView) {
bool originalSizeSmallerThanWindow = isThingSmallerThanWindowWith(resetScale(transform()));
if (originalSizeSmallerThanWindow && scaleFactor() >= 1) {
// no longer need to do fitInView()
// but we leave the m_enableToScreen value unchanged in case
// but we leave the m_enableFitInView value unchanged in case
// user resize down the window again.
} else if (originalSizeSmallerThanWindow && scaleFactor() < 1) {
resetScale();
+11 -8
View File
@@ -38,22 +38,24 @@ public:
void displayScene();
bool isSceneBiggerThanView() const;
void setEnableAutoFitToScreen(bool enable = true);
void setEnableAutoFitInView(bool enable = true);
void setLongImageMode(bool enable = true);
bool isAvoidResetTransform() const;
bool avoidResetTransform() const;
void setAvoidResetTransform(bool avoidReset);
bool isCheckerboard() const;
void toggleCheckerboard(bool invertCheckerboardColor = false);
static QTransform resetScale(const QTransform & orig);
// Long image mode support
bool isLongImage() const;
void fitLongImage();
signals:
void navigatorViewRequired(bool required, QTransform transform);
void viewportRectChanged();
private slots:
void updateStyle(Qt::ColorScheme colorScheme);
public slots:
void toggleCheckerboard(bool invertCheckerboardColor = false);
private:
void mousePressEvent(QMouseEvent * event) override;
@@ -72,7 +74,8 @@ private:
// Consider switch to 3 state for "no fit", "always fit" and "fit when view is smaller"?
// ... or even more? e.g. "fit/snap width" things...
// Currently it's "no fit" when it's false and "fit when view is smaller" when it's true.
bool m_enableFitToScreen = false;
bool m_enableFitInView = false;
bool m_longImageMode = false;
bool m_avoidResetTransform = false;
bool m_checkerboardEnabled = false;
bool m_useLightCheckerboard = false;
+12 -5
View File
@@ -4,6 +4,7 @@
#include "mainwindow.h"
#include "playlistmanager.h"
#include "settings.h"
#ifdef Q_OS_MACOS
@@ -67,19 +68,21 @@ int main(int argc, char *argv[])
a.installEventFilter(fileOpenEventHandler);
a.connect(fileOpenEventHandler, &FileOpenEventHandler::fileOpen, [&w](const QUrl & url){
if (w.isHidden()) {
w.setWindowOpacity(1);
w.showNormal();
} else {
w.activateWindow();
}
w.showFiles({url});
w.showUrls({url});
w.initWindowSize();
});
// Handle dock icon clicks to show hidden window
a.connect(&a, &QApplication::applicationStateChanged, [&w](Qt::ApplicationState state) {
if (state == Qt::ApplicationActive && w.isHidden()) {
w.showFiles({});
w.galleryCurrent(false);
w.showUrls({});
w.galleryCurrent(true, true);
w.setWindowOpacity(1);
w.showNormal();
w.raise();
w.activateWindow();
@@ -87,8 +90,12 @@ int main(int argc, char *argv[])
});
#endif // Q_OS_MACOS
QStringList fileList = parser.positionalArguments();
w.showFiles(fileList);
QStringList urlStrList = parser.positionalArguments();
QList<QUrl> && urlList = PlaylistManager::convertToUrlList(urlStrList);
if (!urlList.isEmpty()) {
w.showUrls(urlList);
}
w.initWindowSize();
+700 -242
View File
File diff suppressed because it is too large Load Diff
+71 -31
View File
@@ -5,19 +5,26 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include "framelesswindow.h"
#include <QParallelAnimationGroup>
#include <QPropertyAnimation>
#include <QPushButton>
QT_BEGIN_NAMESPACE
class QGraphicsOpacityEffect;
class QGraphicsView;
class QFileSystemWatcher;
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class ActionManager;
class PlaylistManager;
class MainWindow : public QWidget
class ToolButton;
class TitleBar;
class GraphicsView;
class NavigatorView;
class BottomButtonGroup;
class MainWindow : public FramelessWindow
{
Q_OBJECT
@@ -25,26 +32,42 @@ public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
void showFiles(const QStringList& files);
void showFiles(const QList<QUrl>& urls);
void showUrls(const QList<QUrl> &urls);
void initWindowSize();
void adjustWindowSizeBySceneRect();
QUrl currentImageFileUrl() const;
void clearGallery();
void galleryPrev();
void galleryNext();
void galleryCurrent(bool fromFileWatcher);
void galleryCurrent(bool showLoadImageHintWhenEmpty, bool reloadImage);
static QStringList supportedImageFormats();
protected slots:
void showEvent(QShowEvent *event) override;
void enterEvent(QEnterEvent *event) override;
void leaveEvent(QEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void contextMenuEvent(QContextMenuEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void centerWindow();
void closeWindow();
void updateWidgetsPosition();
void toggleProtectedMode();
void toggleStayOnTop();
void toggleAvoidResetTransform();
bool stayOnTop() const;
bool canPaste() const;
void quitAppAction(bool force = false);
void toggleFullscreen();
void toggleMaximize();
@@ -52,46 +75,63 @@ protected:
QSize sizeHint() const override;
private slots:
void on_actionCopyPixmap_triggered();
void on_actionCopyFilePath_triggered();
void on_actionOpen_triggered();
void on_actionSaveAs_triggered();
void on_actionActualSize_triggered();
void on_actionToggleMaximize_triggered();
void on_actionZoomIn_triggered();
void on_actionZoomOut_triggered();
void on_actionToggleCheckerboard_triggered();
void on_actionRotateClockwise_triggered();
void on_actionRotateCounterClockwise_triggered();
void on_actionPrevPicture_triggered();
void on_actionNextPicture_triggered();
void on_actionActualSize_triggered();
void on_actionFitToScreen_triggered();
void on_actionFitByWidth_triggered();
void on_actionFitByHeight_triggered();
void on_actionZoomIn_triggered();
void on_actionZoomOut_triggered();
void on_actionFlipHorizontal_triggered();
void on_actionFlipVertical_triggered();
void on_actionRotateClockwise_triggered();
void on_actionRotateCounterClockwise_triggered();
void on_actionToggleAvoidResetTransform_triggered();
void on_actionToggleCheckerboard_triggered();
void on_actionTogglePauseAnimation_triggered();
void on_actionAnimationNextFrame_triggered();
void on_actionHorizontalFlip_triggered();
void on_actionFitInView_triggered();
void on_actionFitByWidth_triggered();
void on_actionFitLongImage_triggered();
void on_actionCopyPixmap_triggered();
void on_actionCopyFilePath_triggered();
void on_actionPaste_triggered();
void on_actionTrash_triggered();
void on_actionLocateInFileManager_triggered();
void on_actionProperties_triggered();
void on_actionToggleStayOnTop_triggered();
void on_actionToggleProtectMode_triggered();
void on_actionToggleAvoidResetTransform_triggered();
void on_actionSettings_triggered();
void on_actionHelp_triggered();
void on_actionProperties_triggered();
void on_actionLocateInFileManager_triggered();
void on_actionQuitApp_triggered();
void doCloseWindow();
private:
bool updateFileWatcher(const QString & basePath = QString());
void updateActionState();
void updateGalleryButtonsVisibility();
private:
QT_PREPEND_NAMESPACE(Ui::MainWindow) *ui;
ActionManager *m_am;
PlaylistManager *m_pm;
QPoint m_oldMousePos;
QPropertyAnimation *m_fadeOutAnimation;
QPropertyAnimation *m_floatUpAnimation;
QParallelAnimationGroup *m_exitAnimationGroup;
QFileSystemWatcher *m_fileSystemWatcher;
ToolButton *m_prevButton;
ToolButton *m_nextButton;
TitleBar *m_titleBar;
GraphicsView *m_graphicsView;
NavigatorView *m_gv;
BottomButtonGroup *m_bottomButtonGroup;
bool m_protectedMode = false;
bool m_clickedOnWindow = false;
};
#endif // MAINWINDOW_H
-172
View File
@@ -1,172 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QWidget" name="MainWindow">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="minimumSize">
<size>
<width>640</width>
<height>480</height>
</size>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="m_centralLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="GraphicsView" name="m_gv">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="bottomBar" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>72</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>72</height>
</size>
</property>
<layout class="QHBoxLayout" name="bottomBarLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="m_navPH" native="true">
<property name="minimumSize">
<size>
<width>99</width>
<height>72</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>99</width>
<height>72</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="leftSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</spacer>
</item>
<item>
<widget class="BottomButtonGroup" name="m_bottomButtonGroup"/>
</item>
<item>
<spacer name="rightSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</spacer>
</item>
<item>
<widget class="NavigatorView" name="m_nav">
<property name="minimumSize">
<size>
<width>99</width>
<height>72</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>99</width>
<height>72</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
<widget class="QMenu" name="m_subMenuCopy">
<property name="title">
<string>&amp;Copy</string>
</property>
<property name="icon">
<iconset theme="edit-copy"/>
</property>
</widget>
<widget class="QMenu" name="m_subMenuTransform">
<property name="title">
<string>&amp;Transform</string>
</property>
</widget>
<widget class="QMenu" name="m_menu"/>
</widget>
<customwidgets>
<customwidget>
<class>GraphicsView</class>
<extends>QGraphicsView</extends>
<header>graphicsview.h</header>
</customwidget>
<customwidget>
<class>NavigatorView</class>
<extends>QGraphicsView</extends>
<header>navigatorview.h</header>
</customwidget>
<customwidget>
<class>BottomButtonGroup</class>
<extends>QGroupBox</extends>
<header>bottombuttongroup.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+15 -18
View File
@@ -3,12 +3,12 @@
// SPDX-License-Identifier: MIT
#include "metadatadialog.h"
#include "ui_metadatadialog.h"
#include <QDialogButtonBox>
#include <QPainter>
#include <QStyledItemDelegate>
#include <QTreeView>
#include <QVBoxLayout>
#include <QHeaderView>
#include "metadatamodel.h"
@@ -73,33 +73,30 @@ protected:
};
MetadataDialog::MetadataDialog(QWidget *parent)
: QDialog(parent), ui(new QT_PREPEND_NAMESPACE(Ui::MetadataDialog))
: QDialog(parent)
, m_treeView(new PropertyTreeView(this))
{
ui->setupUi(this);
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
// YYC MARK:
// Because we use custom QTreeView and we do not want to expose it to public domain.
// So I have to use this way as the compromise.
// Create our custom QTreeView and insert them
m_treeView = new PropertyTreeView(this);
auto* layout = ui->verticalLayout;
const int index = layout->indexOf(ui->m_buttonBox);
layout->insertWidget(index, m_treeView);
// Setup our custom QTreeView
m_treeView->setRootIsDecorated(false);
m_treeView->setIndentation(0);
m_treeView->setItemDelegate(new PropertyTreeItemDelegate(m_treeView));
m_treeView->header()->resizeSection(0, sizeHint().width() / 2);
connect(ui->m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::close);
setWindowTitle(tr("Image Metadata"));
QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
setLayout(new QVBoxLayout);
layout()->addWidget(m_treeView);
layout()->addWidget(buttonBox);
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::close);
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
}
MetadataDialog::~MetadataDialog()
{
delete ui;
}
void MetadataDialog::setMetadataModel(MetadataModel * model)
-7
View File
@@ -11,12 +11,6 @@ QT_BEGIN_NAMESPACE
class QTreeView;
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
namespace Ui {
class MetadataDialog;
}
QT_END_NAMESPACE
class MetadataModel;
class MetadataDialog : public QDialog
{
@@ -31,7 +25,6 @@ public:
private:
QTreeView * m_treeView = nullptr;
QT_PREPEND_NAMESPACE(Ui::MetadataDialog) *ui;
};
#endif // METADATADIALOG_H
-23
View File
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MetadataDialog</class>
<widget class="QDialog" name="MetadataDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="windowTitle">
<string>Image Metadata</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QDialogButtonBox" name="m_buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+9 -38
View File
@@ -5,9 +5,8 @@
#include "navigatorview.h"
#include "graphicsview.h"
#include "opacityhelper.h"
#include <QStyleHints>
#include <QOperatingSystemVersion>
#include <QMouseEvent>
#include <QDebug>
#include <QTimer>
@@ -15,12 +14,12 @@
NavigatorView::NavigatorView(QWidget *parent)
: QGraphicsView (parent)
, m_viewportRegion(this->rect())
, m_opacityHelper(new OpacityHelper(this))
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
updateStyle(qGuiApp->styleHints()->colorScheme());
connect(qGuiApp->styleHints(), &QStyleHints::colorSchemeChanged, this, &NavigatorView::updateStyle);
setStyleSheet("background-color: rgba(0, 0, 0, 120);"
"border-radius: 3px;");
}
// doesn't take or manage its ownership
@@ -29,6 +28,11 @@ void NavigatorView::setMainView(GraphicsView *mainView)
m_mainView = mainView;
}
void NavigatorView::setOpacity(qreal opacity, bool animated)
{
m_opacityHelper->setOpacity(opacity, animated);
}
void NavigatorView::updateMainViewportRegion()
{
// Use QTimer::singleShot with lambda to delay the update
@@ -41,39 +45,6 @@ void NavigatorView::updateMainViewportRegion()
});
}
void NavigatorView::updateStyle(Qt::ColorScheme colorScheme) {
// YYC MARK:
// If we are using Windows 10 and lower system or Qt which do not support "Windows 11"
// theme (lower than Qt 6.7), we should only support light mode.
// Because Qt's dark-mode-aware "Windows 11" theme is only well-supported on Windows 11.
#if defined(Q_OS_WIN)
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
colorScheme = Qt::ColorScheme::Light;
#else
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows11) {
colorScheme = Qt::ColorScheme::Light;
}
#endif // QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
#endif // defined(Q_OS_WIN)
switch (colorScheme) {
case Qt::ColorScheme::Dark:
setStyleSheet(R"#(
border-style: none;
background-color: rgba(255, 255, 255, 70);
)#");
break;
case Qt::ColorScheme::Light:
case Qt::ColorScheme::Unknown:
default:
setStyleSheet(R"#(
border-style: none;
background-color: rgba(0, 0, 0, 70);
)#");
break;
}
}
void NavigatorView::mousePressEvent(QMouseEvent *event)
{
m_mouseDown = true;
+3 -3
View File
@@ -7,6 +7,7 @@
#include <QGraphicsView>
class OpacityHelper;
class GraphicsView;
class NavigatorView : public QGraphicsView
{
@@ -15,13 +16,11 @@ public:
NavigatorView(QWidget *parent = nullptr);
void setMainView(GraphicsView *mainView);
void setOpacity(qreal opacity, bool animated = true);
public slots:
void updateMainViewportRegion();
private slots:
void updateStyle(Qt::ColorScheme colorScheme);
private:
void mousePressEvent(QMouseEvent * event) override;
void mouseMoveEvent(QMouseEvent * event) override;
@@ -33,6 +32,7 @@ private:
bool m_mouseDown = false;
QPolygon m_viewportRegion;
QGraphicsView *m_mainView = nullptr;
OpacityHelper *m_opacityHelper = nullptr;
};
#endif // NAVIGATORVIEW_H
+31
View File
@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
//
// SPDX-License-Identifier: MIT
#include "opacityhelper.h"
#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>
OpacityHelper::OpacityHelper(QWidget *parent)
: QObject(parent)
, m_opacityFx(new QGraphicsOpacityEffect(parent))
, m_opacityAnimation(new QPropertyAnimation(m_opacityFx, "opacity"))
{
parent->setGraphicsEffect(m_opacityFx);
m_opacityAnimation->setDuration(300);
}
void OpacityHelper::setOpacity(qreal opacity, bool animated)
{
if (!animated) {
m_opacityFx->setOpacity(opacity);
return;
}
m_opacityAnimation->stop();
m_opacityAnimation->setStartValue(m_opacityFx->opacity());
m_opacityAnimation->setEndValue(opacity);
m_opacityAnimation->start();
}
+27
View File
@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
//
// SPDX-License-Identifier: MIT
#ifndef OPACITYHELPER_H
#define OPACITYHELPER_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QGraphicsOpacityEffect;
class QPropertyAnimation;
QT_END_NAMESPACE
class OpacityHelper : QObject
{
public:
OpacityHelper(QWidget * parent);
void setOpacity(qreal opacity, bool animated = true);
protected:
QGraphicsOpacityEffect * m_opacityFx;
QPropertyAnimation * m_opacityAnimation;
};
#endif // OPACITYHELPER_H
+205 -217
View File
@@ -3,107 +3,194 @@
// SPDX-License-Identifier: MIT
#include "playlistmanager.h"
#include "playlistscout.h"
#include <QCollator>
#include <QDir>
#include <QFileInfo>
#include <QUrl>
PlaylistManager::PlaylistManager(QObject *parent)
: QObject(parent)
, m_currentIndex(std::nullopt)
, m_playlist()
, m_allowedSuffixes()
PlaylistModel::PlaylistModel(QObject *parent)
: QAbstractListModel(parent)
{
}
PlaylistModel::~PlaylistModel()
= default;
void PlaylistModel::setPlaylist(const QList<QUrl> &urls)
{
beginResetModel();
m_playlist = urls;
endResetModel();
}
QModelIndex PlaylistModel::loadPlaylist(const QList<QUrl> & urls)
{
if (urls.isEmpty()) return {};
if (urls.count() == 1) {
return loadPlaylist(urls.constFirst());
} else {
setPlaylist(urls);
return index(0);
}
}
QModelIndex PlaylistModel::loadPlaylist(const QUrl &url)
{
QFileInfo info(url.toLocalFile());
QDir dir(info.path());
QString && currentFileName = info.fileName();
if (dir.path() == m_currentDir) {
int idx = indexOf(url);
return idx == -1 ? appendToPlaylist(url) : index(idx);
}
QStringList entryList = dir.entryList(
m_autoLoadSuffixes,
QDir::Files | QDir::NoSymLinks, QDir::NoSort);
QCollator collator;
collator.setNumericMode(true);
std::sort(entryList.begin(), entryList.end(), collator);
QList<QUrl> playlist;
int idx = -1;
for (int i = 0; i < entryList.count(); i++) {
const QString & fileName = entryList.at(i);
const QString & oneEntry = dir.absoluteFilePath(fileName);
const QUrl & url = QUrl::fromLocalFile(oneEntry);
playlist.append(url);
if (fileName == currentFileName) {
idx = i;
}
}
if (idx == -1) {
idx = playlist.count();
playlist.append(url);
}
m_currentDir = dir.path();
setPlaylist(playlist);
return index(idx);
}
QModelIndex PlaylistModel::appendToPlaylist(const QUrl &url)
{
const int lastIndex = rowCount();
beginInsertRows(QModelIndex(), lastIndex, lastIndex);
m_playlist.append(url);
endInsertRows();
return index(lastIndex);
}
bool PlaylistModel::removeAt(int index)
{
if (index < 0 || index >= rowCount()) return false;
beginRemoveRows(QModelIndex(), index, index);
m_playlist.removeAt(index);
endRemoveRows();
return true;
}
int PlaylistModel::indexOf(const QUrl &url) const
{
return m_playlist.indexOf(url);
}
QUrl PlaylistModel::urlByIndex(int index) const
{
return m_playlist.value(index);
}
QStringList PlaylistModel::autoLoadFilterSuffixes() const
{
return m_autoLoadSuffixes;
}
QHash<int, QByteArray> PlaylistModel::roleNames() const
{
QHash<int, QByteArray> result = QAbstractListModel::roleNames();
result.insert(UrlRole, "url");
return result;
}
int PlaylistModel::rowCount(const QModelIndex &parent) const
{
return m_playlist.count();
}
QVariant PlaylistModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) return {};
switch (role) {
case Qt::DisplayRole:
return m_playlist.at(index.row()).fileName();
case UrlRole:
return m_playlist.at(index.row());
}
return {};
}
PlaylistManager::PlaylistManager(QObject *parent)
: QObject(parent)
{
connect(&m_model, &PlaylistModel::rowsRemoved, this,
[this](const QModelIndex &, int, int) {
if (m_model.rowCount() <= m_currentIndex) {
setProperty("currentIndex", m_currentIndex - 1);
}
});
auto onRowCountChanged = [this](){
emit totalCountChanged(m_model.rowCount());
};
connect(&m_model, &PlaylistModel::rowsInserted, this, onRowCountChanged);
connect(&m_model, &PlaylistModel::rowsRemoved, this, onRowCountChanged);
connect(&m_model, &PlaylistModel::modelReset, this, onRowCountChanged);
}
PlaylistManager::~PlaylistManager()
{
}
// region: Allowed Suffixes Operations
const QStringList& PlaylistManager::allowedSuffixes() const {
return m_allowedSuffixes;
PlaylistModel *PlaylistManager::model()
{
return &m_model;
}
void PlaylistManager::setAllowedSuffixes(const QStringList& nameFilters) {
m_allowedSuffixes = nameFilters;
emit allowedSuffixesChanged(m_allowedSuffixes);
void PlaylistManager::setPlaylist(const QList<QUrl> &urls)
{
m_model.setPlaylist(urls);
}
// endregion
// region: Playlist Loader and Reset
bool PlaylistManager::loadPlaylist(const QStringList& files) {
// Convert string list to url list first
QList<QUrl> urls;
for (const QString & file : std::as_const(files)) {
urls.append(urlFromString(file));
}
return loadPlaylist(urls);
QModelIndex PlaylistManager::loadPlaylist(const QList<QUrl> &urls)
{
QModelIndex idx = m_model.loadPlaylist(urls);
setProperty("currentIndex", idx.row());
return idx;
}
bool PlaylistManager::loadPlaylist(const QList<QUrl>& urls) {
// Check its count, and check M3U8 playlist for single file case.
if (urls.isEmpty()) {
clearPlaylist();
return true;
} else if (urls.count() == 1) {
const QUrl& firstUrl = urls.first();
const QString lowerCaseUrlPath(firstUrl.path().toLower());
if (lowerCaseUrlPath.endsWith(".m3u8") || lowerCaseUrlPath.endsWith(".m3u")) {
return loadM3U8Playlist(firstUrl);
} else {
return loadSingleFilePlaylist(firstUrl);
}
} else {
return loadMultipleFilesPlaylist(std::move(urls));
}
QModelIndex PlaylistManager::loadPlaylist(const QUrl &url)
{
QModelIndex idx = m_model.loadPlaylist(url);
setProperty("currentIndex", idx.row());
return idx;
}
bool PlaylistManager::loadSingleFilePlaylist(const QUrl& url) {
// Check URL at first
if (!checkUrl(url))
return false;
// Scout playlist by given file
auto scoutResult = PlaylistScout::scout(url, m_allowedSuffixes);
if (!scoutResult.has_value()) {
return false;
}
// Setup playlist with index
setPlaylist(std::move(scoutResult->playlist), scoutResult->indexHint);
return true;
}
bool PlaylistManager::loadMultipleFilesPlaylist(const QList<QUrl>&& urls) {
// Check all of them are valid
for (const auto& url : std::as_const(urls)) {
if (!checkUrl(url)) {
return false;
}
}
// Set playlist and return
setPlaylist(std::move(urls));
return true;
}
bool PlaylistManager::loadM3U8Playlist(const QUrl& url) {
// Check URL at first
if (!checkUrl(url))
return false;
QList<QUrl> urls;
QModelIndex PlaylistManager::loadM3U8Playlist(const QUrl &url)
{
QFile file(url.toLocalFile());
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QList<QUrl> urls;
while (!file.atEnd()) {
QString line = file.readLine();
if (line.startsWith('#')) {
@@ -111,185 +198,86 @@ bool PlaylistManager::loadM3U8Playlist(const QUrl& url) {
}
QFileInfo fileInfo(file);
QUrl item = QUrl::fromUserInput(line, fileInfo.absolutePath());
if (!checkUrl(item)) {
return false;
}
urls.append(item);
}
return loadPlaylist(urls);
} else {
return false;
}
setPlaylist(std::move(urls));
return true;
}
void PlaylistManager::setPlaylist(const QList<QUrl>&& urls, std::optional<qsizetype> indexHint) {
// Setup playlist
m_playlist = std::move(urls);
// Set index with hint
if (indexHint.has_value()) {
m_currentIndex = *indexHint;
}
sanitizeIndex();
// Raise signal
emit playlistChanged(totalCount());
}
void PlaylistManager::clearPlaylist() {
m_playlist.clear();
sanitizeIndex();
emit playlistChanged(this->totalCount());
}
// endregion
// region: Playlist Operations
void PlaylistManager::appendToPlaylist(const QString &file)
{
return appendToPlaylist(urlFromString(file));
}
void PlaylistManager::appendToPlaylist(const QUrl &url)
{
m_playlist.append(url);
sanitizeIndex();
emit playlistChanged(totalCount());
}
bool PlaylistManager::insertIntoPlaylist(qsizetype index, const QString &file)
{
return insertIntoPlaylist(index, urlFromString(file));
}
bool PlaylistManager::insertIntoPlaylist(qsizetype index, const QUrl &url)
{
if (index < 0 || index > totalCount()) {
return false;
} else {
m_playlist.insert(index, url);
sanitizeIndex();
emit playlistChanged(totalCount());
return true;
return {};
}
}
bool PlaylistManager::removeFromPlaylist(qsizetype index)
int PlaylistManager::totalCount() const
{
if (index < 0 || index >= totalCount()) {
return false;
} else {
m_playlist.removeAt(index);
sanitizeIndex();
emit playlistChanged(totalCount());
return true;
}
return m_model.rowCount();
}
// endregion
// region: Index Operations
qsizetype PlaylistManager::totalCount() const
QModelIndex PlaylistManager::previousIndex() const
{
return m_playlist.count();
int count = totalCount();
if (count == 0) return {};
return m_model.index(isFirstIndex() ? count - 1 : m_currentIndex - 1);
}
std::optional<qsizetype> PlaylistManager::previousIndex() const
QModelIndex PlaylistManager::nextIndex() const
{
if (!m_currentIndex.has_value() || totalCount() <= 0) return std::nullopt;
return (isFirstIndex() ? totalCount() - 1 : *m_currentIndex - 1);
int count = totalCount();
if (count == 0) return {};
return m_model.index(isLastIndex() ? 0 : m_currentIndex + 1);
}
std::optional<qsizetype> PlaylistManager::nextIndex() const
QModelIndex PlaylistManager::curIndex() const
{
if (!m_currentIndex.has_value() || totalCount() <= 0) return std::nullopt;
return (isLastIndex() ? 0 : *m_currentIndex + 1);
return m_model.index(m_currentIndex);
}
bool PlaylistManager::isFirstIndex() const
{
return m_currentIndex.has_value() && *m_currentIndex == 0;
return m_currentIndex == 0;
}
bool PlaylistManager::isLastIndex() const
{
return m_currentIndex.has_value() && *m_currentIndex + 1 == totalCount();
return m_currentIndex + 1 == totalCount();
}
std::optional<qsizetype> PlaylistManager::currentIndex() const
void PlaylistManager::setCurrentIndex(const QModelIndex &index)
{
return m_currentIndex;
if (index.isValid() && index.row() >= 0 && index.row() < totalCount()) {
setProperty("currentIndex", index.row());
}
}
bool PlaylistManager::setCurrentIndex(qsizetype index)
QUrl PlaylistManager::urlByIndex(const QModelIndex &index)
{
if (!m_currentIndex.has_value()) {
return false;
}
if (index < 0 || index >= totalCount()) {
return false;
}
if (*m_currentIndex == index) {
return true;
}
m_currentIndex = index;
emit currentIndexChanged(index);
return true;
return m_model.urlByIndex(index.row());
}
QUrl PlaylistManager::urlByIndex(qsizetype index) const
{
return m_playlist.value(index);
}
QString PlaylistManager::localFileByIndex(qsizetype index) const
QString PlaylistManager::localFileByIndex(const QModelIndex &index)
{
return urlByIndex(index).toLocalFile();
}
// endregion
// region: Misc
void PlaylistManager::sanitizeIndex()
bool PlaylistManager::removeAt(const QModelIndex &index)
{
auto cnt = totalCount();
if (cnt == 0) {
// If playlist is empty, current index should be invalid.
m_currentIndex = std::nullopt;
} else {
if (m_currentIndex.has_value()) {
// Clamp current index in playlist range.
// If it is already in range, not change was done.
auto currentIndex = *m_currentIndex;
if (currentIndex < 0) {
m_currentIndex = 0;
} else if (currentIndex >= cnt) {
m_currentIndex = cnt - 1;
} else {
; // No change.
}
} else {
// If there is no set value for current index,
// set it at the beginning of playlist.
m_currentIndex = 0;
return m_model.removeAt(index.row());
}
void PlaylistManager::setAutoLoadFilterSuffixes(const QStringList &nameFilters)
{
m_model.setProperty("autoLoadFilterSuffixes", nameFilters);
}
QList<QUrl> PlaylistManager::convertToUrlList(const QStringList &files)
{
QList<QUrl> urlList;
for (const QString & str : std::as_const(files)) {
QUrl url = QUrl::fromLocalFile(str);
if (url.isValid()) {
urlList.append(url);
}
}
}
bool PlaylistManager::checkUrl(const QUrl& url)
{
return url.isValid() && url.isLocalFile();
return urlList;
}
QUrl PlaylistManager::urlFromString(const QString& file)
{
return QUrl::fromLocalFile(file);
}
// endregion
+65 -107
View File
@@ -5,126 +5,84 @@
#pragma once
#include <QUrl>
#include <QObject>
#include <optional>
#include <QAbstractListModel>
class PlaylistModel : public QAbstractListModel
{
Q_OBJECT
public:
enum PlaylistRole {
UrlRole = Qt::UserRole
};
Q_ENUM(PlaylistRole)
Q_PROPERTY(QStringList autoLoadFilterSuffixes MEMBER m_autoLoadSuffixes NOTIFY autoLoadFilterSuffixesChanged)
explicit PlaylistModel(QObject *parent = nullptr);
~PlaylistModel() override;
void setPlaylist(const QList<QUrl> & urls);
QModelIndex loadPlaylist(const QList<QUrl> & urls);
QModelIndex loadPlaylist(const QUrl & url);
QModelIndex appendToPlaylist(const QUrl & url);
bool removeAt(int index);
int indexOf(const QUrl & url) const;
QUrl urlByIndex(int index) const;
QStringList autoLoadFilterSuffixes() const;
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
signals:
void autoLoadFilterSuffixesChanged(QStringList suffixes);
private:
// model data
QList<QUrl> m_playlist;
// properties
QStringList m_autoLoadSuffixes = {};
// internal
QString m_currentDir;
};
/// The manager of playlist.
class PlaylistManager : public QObject
{
Q_OBJECT
public:
/// Constructs a PlaylistManager with an optional parent QObject.
explicit PlaylistManager(QObject* parent = nullptr);
/// Destructor.
Q_PROPERTY(int currentIndex MEMBER m_currentIndex NOTIFY currentIndexChanged)
Q_PROPERTY(QStringList autoLoadFilterSuffixes WRITE setAutoLoadFilterSuffixes)
Q_PROPERTY(PlaylistModel * model READ model CONSTANT)
explicit PlaylistManager(QObject *parent = nullptr);
~PlaylistManager();
/// Get the allowed file suffixes of this playlist.
/// @return The current list of allowed suffixes.
const QStringList& allowedSuffixes() const;
/// Set the allowed file suffixes of this playlist.
/// @remark This only works for "load the whole directory by one file" case.
/// @param[in] nameFilters The new list of allowed suffixes.
void setAllowedSuffixes(const QStringList& nameFilters);
PlaylistModel * model();
/// Load user specified files as playlist.
/// @remark The wrapper for another overload.
/// @return True for successful load, otherwise false.
bool loadPlaylist(const QStringList& files);
/// Load user specified URLs as playlist.
/// @remark This function automatically dispatch these files into correct sub-load functions.
/// @return True for successful load, otherwise false.
bool loadPlaylist(const QList<QUrl>& urls);
/// Clear the entire playlist and reset current index.
void clearPlaylist();
void setPlaylist(const QList<QUrl> & url);
Q_INVOKABLE QModelIndex loadPlaylist(const QList<QUrl> & urls);
Q_INVOKABLE QModelIndex loadPlaylist(const QUrl & url);
Q_INVOKABLE QModelIndex loadM3U8Playlist(const QUrl & url);
/// Append a local file path to the playlist.
void appendToPlaylist(const QString& file);
/// Append a URL to the playlist.
void appendToPlaylist(const QUrl& url);
/// Insert a local file path at the given index.
/// @return True if inserted successfully, false if index is out of range.
bool insertIntoPlaylist(qsizetype index, const QString& file);
/// Insert a URL at the given index.
/// @return True if inserted successfully, false if index is out of range.
bool insertIntoPlaylist(qsizetype index, const QUrl& url);
/// Remove the entry at the given index.
/// @return True if removed successfully, false if index is out of range.
bool removeFromPlaylist(qsizetype index);
/// Returns the total number of items in the playlist.
/// @return Total count of entries in the playlist.
qsizetype totalCount() const;
/// Try fetching previous index.
/// @details This previous index is gallery-loop-aware.
/// @return std::nullopt if playlist is empty, otherwise the previous index considering gallery loop.
std::optional<qsizetype> previousIndex() const;
/// Try fetching next index.
/// @details This next index is gallery-loop-aware.
/// @return std::nullopt if playlist is empty, otherwise the next index considering gallery loop.
std::optional<qsizetype> nextIndex() const;
/// Check whether current index is the first index.
/// @return False if current index is not the first index or playlist is empty, otherwise true.
int totalCount() const;
QModelIndex previousIndex() const;
QModelIndex nextIndex() const;
QModelIndex curIndex() const;
bool isFirstIndex() const;
/// Check whether current index is the last index.
/// @return False if current index is not the last index or playlist is empty, otherwise true.
bool isLastIndex() const;
/// Returns the current index.
/// @return std::nullopt if the playlist is empty, otherwise the current index.
std::optional<qsizetype> currentIndex() const;
/// Set the current index.
/// @remark Index only can be set when playlist is not empty.
/// @return True if successful set, including "not changed" set, otherwise false.
/// This return value only indicates whether we can set index and given index is valid for setting.
/// If "no changed" set occurs, this function returns true, but doesn't raise current index changed signal.
bool setCurrentIndex(qsizetype index);
/// Returns the URL at the given index.
/// @return The URL if index is valid.
/// This class guarantee that this QUrl is pointing to a local file.
QUrl urlByIndex(qsizetype index) const;
/// Returns the local file path at the given index.
/// @return The local file path if index is valid.
/// This class guarantee that local file path always is valid.
QString localFileByIndex(qsizetype index) const;
void setCurrentIndex(const QModelIndex & index);
QUrl urlByIndex(const QModelIndex & index);
QString localFileByIndex(const QModelIndex & index);
bool removeAt(const QModelIndex & index);
void setAutoLoadFilterSuffixes(const QStringList &nameFilters);
static QList<QUrl> convertToUrlList(const QStringList & files);
signals:
void allowedSuffixesChanged(const QStringList& suffixes);
/// Raised when index was changed bu setter.
/// The argument holds the new current index.
/// Please note that this signal will NOT be raised by the whole playlist change caused index change.
void currentIndexChanged(qsizetype index);
/// The whole playlist was changed, involving loading, editing and deleting some or full entries.
/// The argument holds the total count of new play list.
void playlistChanged(qsizetype count);
void currentIndexChanged(int index);
void totalCountChanged(int count);
private:
/// The fundamental playlist setter.
/// @details All playlist load functions will call this function to set playlist at last.
/// @param[in] urls ALl urls in this list should be checked by checkUrl() function.
/// @param[in] indexHint Try to set current index to this index if possible.
void setPlaylist(const QList<QUrl>&& urls, std::optional<qsizetype> indexHint = std::nullopt);
/// Load playlist from a single file.
/// @details This function scans the same directory for siblings matching allowed suffixes, sorted naturally.
/// @return True if the playlist was loaded successfully, false otherwise.
bool loadSingleFilePlaylist(const QUrl& url);
/// Load playlist from multiple URLs directly.
/// @return True if all URLs are valid, false otherwise.
bool loadMultipleFilesPlaylist(const QList<QUrl>&& urls);
/// Load playlist from an M3U/M3U8 playlist file.
/// @return True if loaded successfully, false otherwise.
bool loadM3U8Playlist(const QUrl& url);
/// Make sure that current index is valid.
/// @details This function usually is used by those functions manipulating playlist.
void sanitizeIndex();
/// Check whether given QUrl is proper to be put into playlist.
/// @details Only the url pointing to local file can be put into playlist.
static bool checkUrl(const QUrl& url);
/// Convert a string to local file into a QUrl.
/// @param[in] file The string pointing to local file.
static QUrl urlFromString(const QString& file);
std::optional<qsizetype> m_currentIndex;
QList<QUrl> m_playlist;
QStringList m_allowedSuffixes;
int m_currentIndex = -1;
PlaylistModel m_model;
};
-25
View File
@@ -1,25 +0,0 @@
// SPDX-FileCopyrightText: 2026 yyc12345 <yyc12321@outlook.com>
//
// SPDX-License-Identifier: MIT
#include "playlistscout.h"
#include "playlistscouts/qtscout.h"
#include "playlistscouts/explorerscout.h"
std::optional<PlaylistScout::ScoutResult> PlaylistScout::scout(
const QUrl &url, const QStringList &allowedSuffixes) {
#ifdef Q_OS_WIN
// In Windows, Qt approach can not aware Windows Explorer custom sort order.
// So we need to try using Win32 functions for fetching it at first.
if (auto rv = PlaylistScout::Explorer::scout(url, allowedSuffixes); rv.has_value()) {
return rv;
}
#endif // Q_OS_WIN
// TODO: We may add macOS Finder, KDE Dolphin and etc supports in future.
// Qt way is the last fallback.
return PlaylistScout::Qt::scout(url, allowedSuffixes);
}
-31
View File
@@ -1,31 +0,0 @@
// SPDX-FileCopyrightText: 2026 yyc12345 <yyc12321@outlook.com>
//
// SPDX-License-Identifier: MIT
#pragma once
#include <QUrl>
#include <QStringList>
#include <QList>
#include <optional>
namespace PlaylistScout {
/// The result of scout
struct ScoutResult {
/// The final fetched playlist (it can be empty).
/// Each item must be a QUrl pointing to a local file.
QList<QUrl> playlist;
/// The index of given file located in playlist.
/// Nullopt if it is not presented in playlist.
std::optional<qsizetype> indexHint;
};
/// @brief Scout available image files in given file's parent dir with given allowed suffixes.
/// @param[in] url The path to file whose parent dir is our target dir for finding image files.
/// @param[in] allowedSuffixes
/// Each items in this list is a wildcard pattern for matching allowed file name, like \c *.png .
/// The fetched item will be preserved if its name matching any of them.
/// If this list is empty, there is no restrictions for finding files.
/// @return Scout result if success, otherwise nullopt.
std::optional<ScoutResult> scout(const QUrl &url, const QStringList &allowedSuffixes);
}
-332
View File
@@ -1,332 +0,0 @@
// SPDX-FileCopyrightText: 2026 yyc12345 <yyc12321@outlook.com>
//
// SPDX-License-Identifier: MIT
#include "explorerscout.h"
#ifdef Q_OS_WIN
#include <QDir>
#include <QDebug>
#include <QFileInfo>
#include <QRegularExpression>
#include <optional>
#include <exdisp.h> // IShellWindows, CLSID_ShellWindows
#include <servprov.h> // IServiceProvider
#include <shlguid.h> // SID_STopLevelBrowser
#include <shlobj.h>
// YYC MARK:
// We use custom RAII wrappers instead of existing COM smart pointers because the
// project may be built with MinGW, which does not have good compatibility with
// CComPtr and Microsoft's WRL ComPtr (<wrl/client.h>).
// Furthermore, PIDLs are not COM objects (they are freed via ILFree, not Release),
// so no standard smart pointer covers them regardless of compiler.
/// RAII wrapper for COM initialization (CoInitialize / CoUninitialize).
/// Must be declared before any COM objects (e.g., ComPtr, UniquePidl) so that
/// CoUninitialize runs after all COM objects are released during scope exit.
class ComGuard {
public:
ComGuard() : m_hr(CoInitialize(nullptr)) {}
~ComGuard() { if (SUCCEEDED(m_hr)) CoUninitialize(); }
ComGuard(const ComGuard&) = delete;
ComGuard& operator=(const ComGuard&) = delete;
bool IsInitialized() const { return SUCCEEDED(m_hr); }
private:
HRESULT m_hr;
};
/// RAII wrapper for COM interface pointers.
template <typename T>
class ComPtr {
public:
ComPtr() = default;
ComPtr(std::nullptr_t) {}
~ComPtr() { Reset(); }
ComPtr(const ComPtr&) = delete;
ComPtr& operator=(const ComPtr&) = delete;
ComPtr(ComPtr&& other) noexcept : m_ptr(other.m_ptr) { other.m_ptr = nullptr; }
ComPtr& operator=(ComPtr&& other) noexcept {
if (this != &other) {
Reset();
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
}
return *this;
}
T* operator->() const { return m_ptr; }
T* Get() const { return m_ptr; }
T** GetAddressOf() { return &m_ptr; }
explicit operator bool() const { return m_ptr != nullptr; }
void Reset() { if (m_ptr) { m_ptr->Release(); m_ptr = nullptr; } }
private:
T* m_ptr = nullptr;
};
/// RAII wrapper for PIDL (Item ID List).
class UniquePidl {
public:
UniquePidl() = default;
explicit UniquePidl(LPITEMIDLIST pidl) : m_pidl(pidl) {}
~UniquePidl() { Reset(); }
UniquePidl(const UniquePidl&) = delete;
UniquePidl& operator=(const UniquePidl&) = delete;
UniquePidl(UniquePidl&& other) noexcept : m_pidl(other.m_pidl) { other.m_pidl = nullptr; }
UniquePidl& operator=(UniquePidl&& other) noexcept {
if (this != &other) {
Reset();
m_pidl = other.m_pidl;
other.m_pidl = nullptr;
}
return *this;
}
LPCITEMIDLIST Get() const { return m_pidl; }
LPITEMIDLIST* GetAddressOf() { return &m_pidl; }
explicit operator bool() const { return m_pidl != nullptr; }
void Reset() { if (m_pidl) { ILFree(m_pidl); m_pidl = nullptr; } }
private:
LPITEMIDLIST m_pidl = nullptr;
};
/// Outputs a diagnostic warning for debugging Windows Explorer integration failures.
static void ReportError(const QString& detail)
{
qWarning("Windows Explorer file list fetch error: %s",
qPrintable(detail));
}
/// Normalizes a Windows directory path for case-insensitive comparison:
/// converts to native separators, lowercases, and ensures a trailing backslash.
static QString NormalizePath(const QString& path)
{
QString result = QDir::toNativeSeparators(path).toLower();
if (!result.endsWith(QChar('\\'))) {
result += QChar('\\');
}
return result;
}
/// Checks whether the Explorer window represented by the given IDispatch is
/// displaying the target folder. Returns its IFolderView2 on match, or null.
static ComPtr<IFolderView2> TryMatchWindow(IDispatch* dispatch, const QString& normalizedTarget)
{
// Navigate: IDispatch -> IServiceProvider -> IShellBrowser.
ComPtr<IServiceProvider> serviceProvider;
if (FAILED(dispatch->QueryInterface(IID_PPV_ARGS(serviceProvider.GetAddressOf())))) {
return nullptr;
}
ComPtr<IShellBrowser> shellBrowser;
if (FAILED(serviceProvider->QueryService(SID_STopLevelBrowser,
IID_PPV_ARGS(shellBrowser.GetAddressOf())))) {
return nullptr;
}
// IShellBrowser -> active IShellView.
ComPtr<IShellView> shellView;
if (FAILED(shellBrowser->QueryActiveShellView(shellView.GetAddressOf()))) {
return nullptr;
}
// Retrieve the folder's path via IPersistIDList.
ComPtr<IPersistIDList> persistIdList;
if (FAILED(shellView->QueryInterface(IID_PPV_ARGS(persistIdList.GetAddressOf())))) {
return nullptr;
}
UniquePidl folderPidl;
if (FAILED(persistIdList->GetIDList(folderPidl.GetAddressOf()))) {
return nullptr;
}
PWSTR pathStr = nullptr;
if (FAILED(SHGetNameFromIDList(folderPidl.Get(), SIGDN_DESKTOPABSOLUTEPARSING, &pathStr))) {
return nullptr;
}
QString windowPath = NormalizePath(QString::fromWCharArray(pathStr));
CoTaskMemFree(pathStr);
if (windowPath != normalizedTarget) {
return nullptr;
}
// Path matches — query IFolderView2 from the ShellView.
ComPtr<IFolderView2> folderView2;
if (FAILED(shellView->QueryInterface(IID_PPV_ARGS(folderView2.GetAddressOf())))) {
return nullptr;
}
return folderView2;
}
/// Tries to find a live Explorer window that is currently displaying the given
/// folder path. Returns the IFolderView2 from that window, or an empty ComPtr.
///
/// Explorer's sort order is stored only in the running Explorer process's memory.
/// Creating a new shell view via IShellFolder::CreateViewObject yields a default
/// sort (always by name), so we must find the actual live IFolderView2 instead.
///
/// Reference:
/// - https://www.stephenli.ca/getting-windows-explorers-current-directory-sort-order
/// - https://github.com/d2phap/ImageGlass/blob/75a296287f338edcf409eee3917531b25ff5d927/v9/Components/ImageGlass.Base/FileSystem/FileFinder.cs
/// - NuGet Package: D2Phap.EggShell
static ComPtr<IFolderView2> FindLiveFolderView(const QString& targetFolderPath)
{
// Create the Shell windows collection (all open Explorer windows).
ComPtr<IShellWindows> shellWindows;
if (FAILED(CoCreateInstance(CLSID_ShellWindows, nullptr, CLSCTX_ALL,
IID_PPV_ARGS(shellWindows.GetAddressOf())))) {
ReportError("Failed to create IShellWindows instance");
return nullptr;
}
QString normalizedTarget = NormalizePath(targetFolderPath);
// 1. Try the Desktop window first — it may contain the file the user opened.
{
VARIANT varLoc;
VariantInit(&varLoc);
varLoc.vt = VT_I4;
varLoc.lVal = 0;
VARIANT varLocRoot;
VariantInit(&varLocRoot);
long desktopHwnd = 0;
ComPtr<IDispatch> desktopDispatch;
HRESULT findHr = shellWindows->FindWindowSW(
&varLoc, &varLocRoot, SWC_DESKTOP,
&desktopHwnd, SWFO_NEEDDISPATCH,
desktopDispatch.GetAddressOf());
VariantClear(&varLoc);
VariantClear(&varLocRoot);
if (SUCCEEDED(findHr) && desktopDispatch) {
ComPtr<IFolderView2> result = TryMatchWindow(desktopDispatch.Get(), normalizedTarget);
if (result) return result;
}
}
// 2. Iterate regular Explorer windows.
LONG count = 0;
shellWindows->get_Count(&count);
for (LONG i = 0; i < count; i++) {
VARIANT varIndex;
VariantInit(&varIndex);
varIndex.vt = VT_I4;
varIndex.lVal = i;
ComPtr<IDispatch> dispatch;
HRESULT itemHr = shellWindows->Item(varIndex, dispatch.GetAddressOf());
VariantClear(&varIndex);
if (FAILED(itemHr) || !dispatch) {
continue;
}
ComPtr<IFolderView2> result = TryMatchWindow(dispatch.Get(), normalizedTarget);
if (result) return result;
}
return nullptr;
}
std::optional<PlaylistScout::ScoutResult> PlaylistScout::Explorer::scout(
const QUrl &url, const QStringList &allowedSuffixes) {
PlaylistScout::ScoutResult rv;
QFileInfo info(url.toLocalFile());
QString folderPath = info.path();
QString currentFileName = info.fileName();
// Pre-compile wildcard suffix filters into regular expressions for performance.
QList<QRegularExpression> nameRegexps;
for (const QString &pattern : allowedSuffixes) {
nameRegexps.append(QRegularExpression(
QRegularExpression::wildcardToRegularExpression(pattern),
QRegularExpression::CaseInsensitiveOption));
}
// Initialize COM. The ComGuard must be declared before any COM objects
// below so that CoUninitialize runs after all of them are released.
ComGuard comGuard;
if (!comGuard.IsInitialized()) {
ReportError("COM initialization failed");
return std::nullopt;
}
// Find a live Explorer window that is currently displaying the target folder.
ComPtr<IFolderView2> folderView2 = FindLiveFolderView(folderPath);
if (!folderView2) {
ReportError("No open Explorer window matches the folder: " + folderPath);
return std::nullopt;
}
// Get items already sorted in Explorer's view order, as an IShellItemArray.
// SVGIO_ALLVIEW returns all items; SVGIO_FLAG_VIEWORDER respects the view's sort.
ComPtr<IShellItemArray> itemArray;
if (FAILED(folderView2->Items(SVGIO_ALLVIEW | SVGIO_FLAG_VIEWORDER,
IID_PPV_ARGS(itemArray.GetAddressOf())))) {
ReportError("IFolderView2::Items(SVGIO_ALLVIEW | SVGIO_FLAG_VIEWORDER) failed");
return std::nullopt;
}
DWORD itemCount = 0;
itemArray->GetCount(&itemCount);
// Enumerate sorted items, filter by pattern, and build the playlist.
for (DWORD i = 0; i < itemCount; i++) {
ComPtr<IShellItem> shellItem;
if (FAILED(itemArray->GetItemAt(i, shellItem.GetAddressOf()))) {
continue;
}
// Get the full parsing path of the item.
PWSTR pathStr = nullptr;
if (FAILED(shellItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pathStr)) || !pathStr) {
continue;
}
QString filePath = QString::fromWCharArray(pathStr);
CoTaskMemFree(pathStr);
// Skip directories — the view may include folders alongside files.
QFileInfo fileInfo(filePath);
if (!fileInfo.isFile()) {
continue;
}
QString fileName = fileInfo.fileName();
// Match against compiled wildcard patterns.
bool matches = nameRegexps.isEmpty();
for (const QRegularExpression &re : std::as_const(nameRegexps)) {
if (re.match(fileName).hasMatch()) {
matches = true;
break;
}
}
if (!matches) {
continue;
}
rv.playlist.append(QUrl::fromLocalFile(filePath));
if (fileName == currentFileName) {
rv.indexHint = rv.playlist.size() - 1;
}
}
return rv;
}
#endif // Q_OS_WIN
-16
View File
@@ -1,16 +0,0 @@
// SPDX-FileCopyrightText: 2026 yyc12345 <yyc12321@outlook.com>
//
// SPDX-License-Identifier: MIT
#pragma once
#include "../playlistscout.h"
#include <QtSystemDetection>
#ifdef Q_OS_WIN
namespace PlaylistScout::Explorer {
std::optional<ScoutResult> scout(const QUrl &url, const QStringList &allowedSuffixes);
}
#endif // Q_OS_WIN
-40
View File
@@ -1,40 +0,0 @@
// SPDX-FileCopyrightText: 2025 Gary Wang <git@blumia.net>
// SPDX-FileCopyrightText: 2026 yyc12345 <yyc12321@outlook.com>
//
// SPDX-License-Identifier: MIT
#include "qtscout.h"
#include <QFileInfo>
#include <QDir>
#include <QCollator>
std::optional<PlaylistScout::ScoutResult> PlaylistScout::Qt::scout(
const QUrl &url, const QStringList &allowedSuffixes) {
PlaylistScout::ScoutResult rv;
QFileInfo info(url.toLocalFile());
QDir dir(info.path());
QString currentFileName = info.fileName();
QStringList entryList = dir.entryList(
allowedSuffixes, QDir::Files | QDir::NoSymLinks, QDir::NoSort);
QCollator collator;
collator.setNumericMode(true);
std::sort(entryList.begin(), entryList.end(), collator);
for (qsizetype i = 0; i < entryList.count(); i++) {
const QString &fileName = entryList.at(i);
const QString &oneEntry = dir.absoluteFilePath(fileName);
const QUrl &url = QUrl::fromLocalFile(oneEntry);
rv.playlist.append(url);
if (fileName == currentFileName) {
rv.indexHint = i;
}
}
return rv;
}
-11
View File
@@ -1,11 +0,0 @@
// SPDX-FileCopyrightText: 2026 yyc12345 <yyc12321@outlook.com>
//
// SPDX-License-Identifier: MIT
#pragma once
#include "../playlistscout.h"
namespace PlaylistScout::Qt {
std::optional<ScoutResult> scout(const QUrl &url, const QStringList &allowedSuffixes);
}
+118 -14
View File
@@ -13,14 +13,6 @@
#include <QKeySequence>
#include <QMetaEnum>
Settings *Settings::instance()
{
// SAFETY:
// This is a global singleton and it is leaked by design.
static Settings* INSTANCE = new Settings(nullptr);
return INSTANCE;
}
namespace QEnumHelper
{
template <typename E>
@@ -42,6 +34,32 @@ namespace QEnumHelper
}
}
Settings *Settings::m_settings_instance = nullptr;
Settings *Settings::instance()
{
if (!m_settings_instance) {
m_settings_instance = new Settings;
}
return m_settings_instance;
}
bool Settings::stayOnTop() const
{
return m_qsettings->value("stay_on_top", true).toBool();
}
bool Settings::useBuiltInCloseAnimation() const
{
return m_qsettings->value("use_built_in_close_animation", true).toBool();
}
bool Settings::showTitleBar() const
{
return m_qsettings->value("show_title_bar", true).toBool();
}
bool Settings::useLightCheckerboard() const
{
return m_qsettings->value("use_light_checkerboard", false).toBool();
@@ -52,6 +70,11 @@ bool Settings::loopGallery() const
return m_qsettings->value("loop_gallery", true).toBool();
}
bool Settings::autoLongImageMode() const
{
return m_qsettings->value("auto_long_image_mode", true).toBool();
}
bool Settings::svgTiny12Only() const
{
// Qt 6.7.0's SVG support is terrible caused by huge memory usage, see QTBUG-124287
@@ -65,24 +88,52 @@ bool Settings::svgTiny12Only() const
#endif // QT_VERSION < QT_VERSION_CHECK(6, 9, 3)
}
Settings::DoubleClickBehavior Settings::doubleClickBehavior() const
{
QString result = m_qsettings->value("double_click_behavior", "Close").toString();
return QEnumHelper::fromString<DoubleClickBehavior>(result, DoubleClickBehavior::Close);
}
Settings::MouseWheelBehavior Settings::mouseWheelBehavior() const
{
QString result = m_qsettings->value("mouse_wheel_behavior", "").toString();
QString result = m_qsettings->value("mouse_wheel_behavior", "Zoom").toString();
return QEnumHelper::fromString<MouseWheelBehavior>(result, MouseWheelBehavior::Zoom);
}
Settings::WindowSizeBehavior Settings::initWindowSizeBehavior() const
{
QString result = m_qsettings->value("init_window_size_behavior", "").toString();
return QEnumHelper::fromString<WindowSizeBehavior>(result, WindowSizeBehavior::Windowed);
QString result = m_qsettings->value("init_window_size_behavior", "Auto").toString();
return QEnumHelper::fromString<WindowSizeBehavior>(result, WindowSizeBehavior::Auto);
}
Qt::HighDpiScaleFactorRoundingPolicy Settings::hiDpiScaleFactorBehavior() const
{
QString result = m_qsettings->value("hidpi_scale_factor_behavior", "").toString();
QString result = m_qsettings->value("hidpi_scale_factor_behavior", "PassThrough").toString();
return QEnumHelper::fromString<Qt::HighDpiScaleFactorRoundingPolicy>(result, Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
}
void Settings::setStayOnTop(bool on)
{
m_qsettings->setValue("stay_on_top", on);
m_qsettings->sync();
}
void Settings::setUseBuiltInCloseAnimation(bool on)
{
m_qsettings->setValue("use_built_in_close_animation", on);
m_qsettings->sync();
}
void Settings::setShowTitleBar(bool on)
{
m_qsettings->setValue("show_title_bar", on);
m_qsettings->sync();
}
void Settings::setUseLightCheckerboard(bool light)
{
m_qsettings->setValue("use_light_checkerboard", light);
@@ -95,12 +146,24 @@ void Settings::setLoopGallery(bool on)
m_qsettings->sync();
}
void Settings::setAutoLongImageMode(bool on)
{
m_qsettings->setValue("auto_long_image_mode", on);
m_qsettings->sync();
}
void Settings::setSvgTiny12Only(bool on)
{
m_qsettings->setValue("svg_tiny12_only", on);
m_qsettings->sync();
}
void Settings::setDoubleClickBehavior(DoubleClickBehavior dcb)
{
m_qsettings->setValue("double_click_behavior", QEnumHelper::toString(dcb));
m_qsettings->sync();
}
void Settings::setMouseWheelBehavior(MouseWheelBehavior mwb)
{
m_qsettings->setValue("mouse_wheel_behavior", QEnumHelper::toString(mwb));
@@ -119,6 +182,47 @@ void Settings::setHiDpiScaleFactorBehavior(Qt::HighDpiScaleFactorRoundingPolicy
m_qsettings->sync();
}
void Settings::applyUserShortcuts(QWidget *widget)
{
m_qsettings->beginGroup("shortcuts");
const QStringList shortcutNames = m_qsettings->allKeys();
for (const QString & name : shortcutNames) {
QList<QKeySequence> shortcuts = m_qsettings->value(name).value<QList<QKeySequence>>();
setShortcutsForAction(widget, name, shortcuts, false);
}
m_qsettings->endGroup();
}
bool Settings::setShortcutsForAction(QWidget *widget, const QString &objectName,
QList<QKeySequence> shortcuts, bool writeConfig)
{
QAction * targetAction = nullptr;
for (QAction * action : widget->actions()) {
if (action->objectName() == objectName) {
targetAction = action;
} else {
for (const QKeySequence & shortcut : std::as_const(shortcuts)) {
if (action->shortcuts().contains(shortcut)) {
return false;
}
}
}
}
if (targetAction) {
targetAction->setShortcuts(shortcuts);
}
if (targetAction && writeConfig) {
m_qsettings->beginGroup("shortcuts");
m_qsettings->setValue(objectName, QVariant::fromValue(shortcuts));
m_qsettings->endGroup();
m_qsettings->sync();
}
return true;
}
#if defined(FLAG_PORTABLE_MODE_SUPPORT) && defined(Q_OS_WIN)
#include <windows.h>
// QCoreApplication::applicationDirPath() parses the "applicationDirPath" from arg0, which...
@@ -137,8 +241,8 @@ QString getApplicationDirPath()
}
#endif // defined(FLAG_PORTABLE_MODE_SUPPORT) && defined(Q_OS_WIN)
Settings::Settings(QObject *parent)
: QObject(parent)
Settings::Settings()
: QObject(qApp)
{
QString configPath;
+26 -1
View File
@@ -11,6 +11,14 @@ class Settings : public QObject
{
Q_OBJECT
public:
enum DoubleClickBehavior {
Ignore,
Close,
Maximize,
FullScreen,
};
Q_ENUM(DoubleClickBehavior)
enum MouseWheelBehavior {
Zoom,
Switch,
@@ -18,6 +26,7 @@ public:
Q_ENUM(MouseWheelBehavior)
enum WindowSizeBehavior {
Auto,
Maximized,
Windowed,
};
@@ -25,22 +34,38 @@ public:
static Settings *instance();
bool stayOnTop() const;
bool useBuiltInCloseAnimation() const;
bool showTitleBar() const;
bool useLightCheckerboard() const;
bool loopGallery() const;
bool autoLongImageMode() const;
bool svgTiny12Only() const;
DoubleClickBehavior doubleClickBehavior() const;
MouseWheelBehavior mouseWheelBehavior() const;
WindowSizeBehavior initWindowSizeBehavior() const;
Qt::HighDpiScaleFactorRoundingPolicy hiDpiScaleFactorBehavior() const;
void setStayOnTop(bool on);
void setUseBuiltInCloseAnimation(bool on);
void setShowTitleBar(bool on);
void setUseLightCheckerboard(bool light);
void setLoopGallery(bool on);
void setAutoLongImageMode(bool on);
void setSvgTiny12Only(bool on);
void setDoubleClickBehavior(DoubleClickBehavior dcb);
void setMouseWheelBehavior(MouseWheelBehavior mwb);
void setInitWindowSizeBehavior(WindowSizeBehavior wsb);
void setHiDpiScaleFactorBehavior(Qt::HighDpiScaleFactorRoundingPolicy hidpi);
void applyUserShortcuts(QWidget * widget);
bool setShortcutsForAction(QWidget * widget, const QString & objectName,
QList<QKeySequence> shortcuts, bool writeConfig = true);
private:
Settings(QObject *parent = nullptr);
Settings();
static Settings *m_settings_instance;
QSettings *m_qsettings;
+178 -97
View File
@@ -3,94 +3,161 @@
// SPDX-License-Identifier: MIT
#include "settingsdialog.h"
#include "ui_settingsdialog.h"
#include "settings.h"
#include "shortcutedit.h"
#include <QApplication>
#include <QTimer>
#include <QAction>
#include <QCheckBox>
#include <QComboBox>
#include <QFormLayout>
#include <QKeySequenceEdit>
#include <QScrollArea>
#include <QSplitter>
#include <QStringListModel>
#include <type_traits>
template <typename E, typename = std::enable_if_t<std::is_enum_v<E>>>
class EnumComboBoxTransformer {
public:
using Pair = QPair<E, QString>;
using Pairs = QList<QPair<E, QString>>;
EnumComboBoxTransformer(Pairs &&pairs) : pairs(std::move(pairs)) {}
~EnumComboBoxTransformer() = default;
Q_DISABLE_COPY_MOVE(EnumComboBoxTransformer)
/// Build Qt model used for QComboBox
QStringListModel* buildComboBoxModel(QObject *parent = nullptr) const {
QStringList dropDownEntries;
for (const auto& pair : std::as_const(this->pairs)) {
dropDownEntries.append(pair.second);
}
return new QStringListModel(dropDownEntries, parent);
}
/// Convert QComboBox index to enum value.
E to_value(int index) const {
return this->pairs.at(static_cast<qsizetype>(index)).first;
}
/// Convert enum value to QComboBox index.
int to_index(E value) const {
for (qsizetype i = 0; i < pairs.size(); ++i) {
if (pairs.at(i).first == value) {
return static_cast<int>(i);
}
}
// Value not found
throw std::invalid_argument("invalid enum value for finding index");
}
private:
Pairs pairs;
};
static EnumComboBoxTransformer<Settings::MouseWheelBehavior, QString> MW_OPTIONS {
{
{ Settings::MouseWheelBehavior::Zoom, QCoreApplication::translate("SettingsDialog", "Zoom in and out") },
{ Settings::MouseWheelBehavior::Switch, QCoreApplication::translate("SettingsDialog", "View next or previous item") }
}
};
static EnumComboBoxTransformer<Settings::WindowSizeBehavior, QString> IWS_OPTIONS {
{
{ Settings::WindowSizeBehavior::Maximized, QCoreApplication::translate("SettingsDialog", "Maximized") },
{ Settings::WindowSizeBehavior::Windowed, QCoreApplication::translate("SettingsDialog", "Windowed") }
}
};
static EnumComboBoxTransformer<Qt::HighDpiScaleFactorRoundingPolicy, QString> HIDPI_OPTIONS {
{
{ Qt::HighDpiScaleFactorRoundingPolicy::Round, QCoreApplication::translate("SettingsDialog", "Round (Integer scaling)", "This option means round up for .5 and above") },
{ Qt::HighDpiScaleFactorRoundingPolicy::Ceil, QCoreApplication::translate("SettingsDialog", "Ceil (Integer scaling)", "This option means always round up") },
{ Qt::HighDpiScaleFactorRoundingPolicy::Floor, QCoreApplication::translate("SettingsDialog", "Floor (Integer scaling)", "This option means always round down") },
{ Qt::HighDpiScaleFactorRoundingPolicy::PassThrough, QCoreApplication::translate("SettingsDialog", "Follow system (Fractional scaling)", "This option means don't round") }
}
};
#include <QMessageBox>
SettingsDialog::SettingsDialog(QWidget *parent)
: QDialog(parent), ui(new QT_PREPEND_NAMESPACE(Ui::SettingsDialog))
: QDialog(parent)
, m_stayOnTop(new QCheckBox)
, m_useBuiltInCloseAnimation(new QCheckBox)
, m_showTitleBar(new QCheckBox)
, m_useLightCheckerboard(new QCheckBox)
, m_loopGallery(new QCheckBox)
, m_autoLongImageMode(new QCheckBox)
, m_svgTiny12Only(new QCheckBox)
, m_doubleClickBehavior(new QComboBox)
, m_mouseWheelBehavior(new QComboBox)
, m_initWindowSizeBehavior(new QComboBox)
, m_hiDpiRoundingPolicyBehavior(new QComboBox)
{
ui->setupUi(this);
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
this->setWindowTitle(tr("Settings"));
auto* settings = Settings::instance();
ui->m_useLightCheckerboard->setChecked(settings->useLightCheckerboard());
ui->m_loopGallery->setChecked(settings->loopGallery());
ui->m_svgTiny12Only->setChecked(settings->svgTiny12Only());
ui->m_mouseWheelBehavior->setModel(MW_OPTIONS.buildComboBoxModel(this));
Settings::MouseWheelBehavior mwb = settings->mouseWheelBehavior();
ui->m_mouseWheelBehavior->setCurrentIndex(MW_OPTIONS.to_index(mwb));
ui->m_initWindowSizeBehavior->setModel(IWS_OPTIONS.buildComboBoxModel(this));
Settings::WindowSizeBehavior iwsb = settings->initWindowSizeBehavior();
ui->m_initWindowSizeBehavior->setCurrentIndex(IWS_OPTIONS.to_index(iwsb));
ui->m_hiDpiRoundingPolicyBehavior->setModel(HIDPI_OPTIONS.buildComboBoxModel(this));
Qt::HighDpiScaleFactorRoundingPolicy hidpi = settings->hiDpiScaleFactorBehavior();
ui->m_hiDpiRoundingPolicyBehavior->setCurrentIndex(HIDPI_OPTIONS.to_index(hidpi));
QHBoxLayout * mainLayout = new QHBoxLayout(this);
QTabWidget * settingsTabs = new QTabWidget(this);
mainLayout->addWidget(settingsTabs);
QWidget * settingsFormHolder = new QWidget;
QFormLayout * settingsForm = new QFormLayout(settingsFormHolder);
settingsTabs->addTab(settingsFormHolder, tr("Options"));
QSplitter * shortcutEditorSplitter = new QSplitter;
shortcutEditorSplitter->setOrientation(Qt::Vertical);
shortcutEditorSplitter->setChildrenCollapsible(false);
QScrollArea * shortcutScrollArea = new QScrollArea;
shortcutEditorSplitter->addWidget(shortcutScrollArea);
shortcutScrollArea->setWidgetResizable(true);
shortcutScrollArea->setMinimumHeight(200);
QWidget * shortcutsFormHolder = new QWidget;
QFormLayout * shortcutsForm = new QFormLayout(shortcutsFormHolder);
shortcutScrollArea->setWidget(shortcutsFormHolder);
settingsTabs->addTab(shortcutEditorSplitter, tr("Shortcuts"));
for (const QAction * action : parent->actions()) {
ShortcutEdit * shortcutEdit = new ShortcutEdit;
shortcutEdit->setObjectName(QLatin1String("shortcut_") + action->objectName());
shortcutEdit->setShortcuts(action->shortcuts());
shortcutsForm->addRow(action->text(), shortcutEdit);
connect(shortcutEdit, &ShortcutEdit::editButtonClicked, this, [=](){
if (shortcutEditorSplitter->count() == 1) shortcutEditorSplitter->addWidget(new QWidget);
ShortcutEditor * shortcutEditor = new ShortcutEditor(shortcutEdit);
shortcutEditor->setDescription(tr("Editing shortcuts for action \"%1\":").arg(action->text()));
QWidget * oldEditor = shortcutEditorSplitter->replaceWidget(1, shortcutEditor);
shortcutEditorSplitter->setSizes({shortcutEditorSplitter->height(), 1});
oldEditor->deleteLater();
});
connect(shortcutEdit, &ShortcutEdit::applyShortcutsRequested, this, [=](QList<QKeySequence> newShortcuts){
bool succ = Settings::instance()->setShortcutsForAction(parent, shortcutEdit->objectName().mid(9),
newShortcuts);
if (!succ) {
QMessageBox::warning(this, tr("Failed to set shortcuts"),
tr("Please check if shortcuts are duplicated with existing shortcuts."));
}
shortcutEdit->setShortcuts(action->shortcuts());
});
}
static QList< QPair<Settings::DoubleClickBehavior, QString> > _dc_options {
{ Settings::DoubleClickBehavior::Ignore, tr("Do nothing") },
{ Settings::DoubleClickBehavior::Close, tr("Close the window") },
{ Settings::DoubleClickBehavior::Maximize, tr("Toggle maximize") },
{ Settings::DoubleClickBehavior::FullScreen, tr("Toggle fullscreen") }
};
static QList< QPair<Settings::MouseWheelBehavior, QString> > _mw_options {
{ Settings::MouseWheelBehavior::Zoom, tr("Zoom in and out") },
{ Settings::MouseWheelBehavior::Switch, tr("View next or previous item") }
};
static QList< QPair<Settings::WindowSizeBehavior, QString> > _iws_options {
{ Settings::WindowSizeBehavior::Auto, tr("Auto size") },
{ Settings::WindowSizeBehavior::Maximized, tr("Maximized") },
{ Settings::WindowSizeBehavior::Windowed, tr("Windowed") }
};
static QList< QPair<Qt::HighDpiScaleFactorRoundingPolicy, QString> > _hidpi_options {
{ Qt::HighDpiScaleFactorRoundingPolicy::Round, tr("Round (Integer scaling)", "This option means round up for .5 and above") },
{ Qt::HighDpiScaleFactorRoundingPolicy::Ceil, tr("Ceil (Integer scaling)", "This option means always round up") },
{ Qt::HighDpiScaleFactorRoundingPolicy::Floor, tr("Floor (Integer scaling)", "This option means always round down") },
{ Qt::HighDpiScaleFactorRoundingPolicy::PassThrough, tr("Follow system (Fractional scaling)", "This option means don't round") }
};
QStringList dcbDropDown;
for (const QPair<Settings::DoubleClickBehavior, QString> & dcOption : _dc_options) {
dcbDropDown.append(dcOption.second);
}
QStringList mwbDropDown;
for (const QPair<Settings::MouseWheelBehavior, QString> & mwOption : _mw_options) {
mwbDropDown.append(mwOption.second);
}
QStringList iwsbDropDown;
for (const QPair<Settings::WindowSizeBehavior, QString> & iwsOption : _iws_options) {
iwsbDropDown.append(iwsOption.second);
}
QStringList hidpiDropDown;
for (const QPair<Qt::HighDpiScaleFactorRoundingPolicy, QString> & hidpiOption : _hidpi_options) {
hidpiDropDown.append(hidpiOption.second);
}
settingsForm->addRow(tr("Stay on top when start-up"), m_stayOnTop);
settingsForm->addRow(tr("Use built-in close window animation"), m_useBuiltInCloseAnimation);
settingsForm->addRow(tr("Show title bar"), m_showTitleBar);
settingsForm->addRow(tr("Use light-color checkerboard"), m_useLightCheckerboard);
settingsForm->addRow(tr("Loop the loaded gallery"), m_loopGallery);
settingsForm->addRow(tr("Auto long image mode"), m_autoLongImageMode);
settingsForm->addRow(tr("Limit SVG support to SVG Tiny 1.2"), m_svgTiny12Only);
settingsForm->addRow(tr("Double-click behavior"), m_doubleClickBehavior);
settingsForm->addRow(tr("Mouse wheel behavior"), m_mouseWheelBehavior);
settingsForm->addRow(tr("Default window size"), m_initWindowSizeBehavior);
settingsForm->addRow(tr("HiDPI scale factor rounding policy"), m_hiDpiRoundingPolicyBehavior);
m_stayOnTop->setChecked(Settings::instance()->stayOnTop());
m_useBuiltInCloseAnimation->setChecked(Settings::instance()->useBuiltInCloseAnimation());
m_showTitleBar->setChecked(Settings::instance()->showTitleBar());
m_useLightCheckerboard->setChecked(Settings::instance()->useLightCheckerboard());
m_loopGallery->setChecked(Settings::instance()->loopGallery());
m_autoLongImageMode->setChecked(Settings::instance()->autoLongImageMode());
m_svgTiny12Only->setChecked(Settings::instance()->svgTiny12Only());
m_doubleClickBehavior->setModel(new QStringListModel(dcbDropDown));
Settings::DoubleClickBehavior dcb = Settings::instance()->doubleClickBehavior();
m_doubleClickBehavior->setCurrentIndex(static_cast<int>(dcb));
m_mouseWheelBehavior->setModel(new QStringListModel(mwbDropDown));
Settings::MouseWheelBehavior mwb = Settings::instance()->mouseWheelBehavior();
m_mouseWheelBehavior->setCurrentIndex(static_cast<int>(mwb));
m_initWindowSizeBehavior->setModel(new QStringListModel(iwsbDropDown));
Settings::WindowSizeBehavior iwsb = Settings::instance()->initWindowSizeBehavior();
m_initWindowSizeBehavior->setCurrentIndex(static_cast<int>(iwsb));
m_hiDpiRoundingPolicyBehavior->setModel(new QStringListModel(hidpiDropDown));
Qt::HighDpiScaleFactorRoundingPolicy hidpi = Settings::instance()->hiDpiScaleFactorBehavior();
for (int i = 0; i < _hidpi_options.count(); i++) {
if (_hidpi_options.at(i).first == hidpi) {
m_hiDpiRoundingPolicyBehavior->setCurrentIndex(i);
break;
}
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
# define QCHECKBOX_CHECKSTATECHANGED QCheckBox::checkStateChanged
@@ -100,41 +167,55 @@ SettingsDialog::SettingsDialog(QWidget *parent)
# define QT_CHECKSTATE int
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
connect(ui->m_useLightCheckerboard, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
connect(m_stayOnTop, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setStayOnTop(state == Qt::Checked);
});
connect(m_useBuiltInCloseAnimation, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setUseBuiltInCloseAnimation(state == Qt::Checked);
});
connect(m_showTitleBar, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setShowTitleBar(state == Qt::Checked);
});
connect(m_useLightCheckerboard, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setUseLightCheckerboard(state == Qt::Checked);
});
connect(ui->m_loopGallery, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
connect(m_loopGallery, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setLoopGallery(state == Qt::Checked);
});
connect(ui->m_svgTiny12Only, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
connect(m_autoLongImageMode, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setAutoLongImageMode(state == Qt::Checked);
});
connect(m_svgTiny12Only, &QCHECKBOX_CHECKSTATECHANGED, this, [ = ](QT_CHECKSTATE state){
Settings::instance()->setSvgTiny12Only(state == Qt::Checked);
});
connect(ui->m_mouseWheelBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setMouseWheelBehavior(MW_OPTIONS.to_value(index));
connect(m_doubleClickBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setDoubleClickBehavior(_dc_options.at(index).first);
});
connect(ui->m_initWindowSizeBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setInitWindowSizeBehavior(IWS_OPTIONS.to_value(index));
connect(m_mouseWheelBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setMouseWheelBehavior(_mw_options.at(index).first);
});
connect(ui->m_hiDpiRoundingPolicyBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setHiDpiScaleFactorBehavior(HIDPI_OPTIONS.to_value(index));
connect(m_initWindowSizeBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setInitWindowSizeBehavior(_iws_options.at(index).first);
});
// YYC MARK:
// Use adjustSize() to make sure all ComboBox are expanded by its items.
// Because items are added after inserting them into layout.
// It is inviable to call this function in ctor because this relys on Qt event system.
// It only can be done by QTimer::singleShot().
QTimer::singleShot(0, this, [this](){
this->adjustSize();
connect(m_hiDpiRoundingPolicyBehavior, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [ = ](int index){
Settings::instance()->setHiDpiScaleFactorBehavior(_hidpi_options.at(index).first);
});
adjustSize();
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
}
SettingsDialog::~SettingsDialog()
{
delete ui;
}
+18 -7
View File
@@ -5,14 +5,11 @@
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QObject>
#include <QDialog>
QT_BEGIN_NAMESPACE
namespace Ui {
class SettingsDialog;
}
QT_END_NAMESPACE
class QCheckBox;
class QComboBox;
class SettingsDialog : public QDialog
{
Q_OBJECT
@@ -20,8 +17,22 @@ public:
explicit SettingsDialog(QWidget *parent = nullptr);
~SettingsDialog();
signals:
public slots:
private:
QT_PREPEND_NAMESPACE(Ui::SettingsDialog) *ui;
QCheckBox * m_stayOnTop = nullptr;
QCheckBox * m_useBuiltInCloseAnimation = nullptr;
QCheckBox * m_showTitleBar = nullptr;
QCheckBox * m_useLightCheckerboard = nullptr;
QCheckBox * m_loopGallery = nullptr;
QCheckBox * m_autoLongImageMode = nullptr;
QCheckBox * m_svgTiny12Only = nullptr;
QComboBox * m_doubleClickBehavior = nullptr;
QComboBox * m_mouseWheelBehavior = nullptr;
QComboBox * m_initWindowSizeBehavior = nullptr;
QComboBox * m_hiDpiRoundingPolicyBehavior = nullptr;
};
#endif // SETTINGSDIALOG_H
-81
View File
@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingsDialog</class>
<widget class="QDialog" name="SettingsDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="windowTitle">
<string>Settings</string>
</property>
<layout class="QHBoxLayout" name="mainLayout">
<item>
<widget class="QTabWidget" name="settingsTabs">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="optionsTab">
<attribute name="title">
<string>Options</string>
</attribute>
<layout class="QFormLayout" name="settingsForm">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="m_useLightCheckerboard">
<property name="text">
<string>Use light-color checkerboard</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="m_loopGallery">
<property name="text">
<string>Loop the loaded gallery</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="m_svgTiny12Only">
<property name="text">
<string>Limit SVG support to SVG Tiny 1.2</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="m_mouseWheelBehaviorLabel">
<property name="text">
<string>Mouse wheel behavior</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="m_mouseWheelBehavior"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="m_initWindowSizeBehaviorLabel">
<property name="text">
<string>Default window size</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="m_initWindowSizeBehavior"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="m_hiDpiRoundingPolicyBehaviorLabel">
<property name="text">
<string>HiDPI scale factor rounding policy</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="m_hiDpiRoundingPolicyBehavior"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+126
View File
@@ -0,0 +1,126 @@
// SPDX-FileCopyrightText: 2024 Gary Wang <opensource@blumia.net>
//
// SPDX-License-Identifier: MIT
#include "shortcutedit.h"
#include <QLabel>
#include <QToolButton>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QKeySequenceEdit>
ShortcutEditor::ShortcutEditor(ShortcutEdit * shortcutEdit, QWidget * parent)
: QWidget(parent)
, m_descriptionLabel(new QLabel)
, m_shortcutEdit(shortcutEdit)
, m_shortcutLayout(new QFormLayout)
{
Q_CHECK_PTR(m_shortcutEdit);
QDialogButtonBox * buttons = new QDialogButtonBox(QDialogButtonBox::Apply | QDialogButtonBox::Discard);
QVBoxLayout * layout = new QVBoxLayout(this);
layout->addWidget(m_descriptionLabel);
layout->addLayout(m_shortcutLayout);
layout->addWidget(buttons);
connect(buttons, &QDialogButtonBox::clicked, this, [=](QAbstractButton *button){
if ((QPushButton *)button == buttons->button(QDialogButtonBox::Apply)) {
applyShortcuts();
} else {
reloadShortcuts();
}
});
connect(shortcutEdit, &ShortcutEdit::shortcutsChanged, this, &ShortcutEditor::reloadShortcuts);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
reloadShortcuts();
}
void ShortcutEditor::setDescription(const QString &desc)
{
m_descriptionLabel->setText(desc);
}
void ShortcutEditor::reloadShortcuts()
{
if (!m_keySequenceEdits.isEmpty()) {
for (QKeySequenceEdit * keyseqEdit : m_keySequenceEdits) {
m_shortcutLayout->removeRow(keyseqEdit);
}
m_keySequenceEdits.clear();
}
QList<QKeySequence> shortcuts = m_shortcutEdit->shortcuts();
shortcuts.append(QKeySequence());
for (const QKeySequence & shortcut : shortcuts) {
QKeySequenceEdit * keyseqEdit = new QKeySequenceEdit(this);
keyseqEdit->setClearButtonEnabled(true);
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
keyseqEdit->setMaximumSequenceLength(1);
#endif // QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
keyseqEdit->setKeySequence(shortcut);
m_keySequenceEdits.append(keyseqEdit);
}
for (int i = 0; i < m_keySequenceEdits.count(); i++) {
m_shortcutLayout->addRow(tr("Shortcut #%1").arg(i + 1), m_keySequenceEdits.at(i));
}
}
void ShortcutEditor::applyShortcuts()
{
QList<QKeySequence> shortcuts;
for (const QKeySequenceEdit * keyseqEdit : m_keySequenceEdits) {
if (!keyseqEdit->keySequence().isEmpty() && !shortcuts.contains(keyseqEdit->keySequence())) {
shortcuts.append(keyseqEdit->keySequence());
}
}
emit m_shortcutEdit->applyShortcutsRequested(shortcuts);
}
// ----------------------------------------
ShortcutEdit::ShortcutEdit(QWidget *parent)
: QWidget(parent)
, m_shortcutsLabel(new QLabel(this))
, m_setShortcutButton(new QToolButton(this))
{
m_setShortcutButton->setText("...");
QHBoxLayout * layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_shortcutsLabel, 1);
layout->addWidget(m_setShortcutButton);
connect(this, &ShortcutEdit::shortcutsChanged, this, [=](){
QStringList shortcutTexts;
for (const QKeySequence & shortcut : std::as_const(m_shortcuts)) {
shortcutTexts.append(shortcut.toString(QKeySequence::NativeText));
}
m_shortcutsLabel->setText(shortcutTexts.isEmpty() ? tr("No shortcuts") : shortcutTexts.join(", "));
m_shortcutsLabel->setDisabled(shortcutTexts.isEmpty());
});
connect(m_setShortcutButton, &QToolButton::clicked, this, &ShortcutEdit::editButtonClicked);
adjustSize();
}
ShortcutEdit::~ShortcutEdit()
{
}
QList<QKeySequence> ShortcutEdit::shortcuts() const
{
return m_shortcuts;
}
void ShortcutEdit::setShortcuts(const QList<QKeySequence> &shortcuts)
{
m_shortcuts = shortcuts;
emit shortcutsChanged();
}
+55
View File
@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: 2024 Gary Wang <opensource@blumia.net>
//
// SPDX-License-Identifier: MIT
#pragma once
#include <QWidget>
#include <QList>
#include <QKeySequence>
class QLabel;
class QFormLayout;
class QToolButton;
class QKeySequenceEdit;
class ShortcutEdit;
class ShortcutEditor : public QWidget
{
Q_OBJECT
public:
explicit ShortcutEditor(ShortcutEdit * shortcutEdit, QWidget * parent = nullptr);
~ShortcutEditor() = default;
void setDescription(const QString & desc);
void reloadShortcuts();
void applyShortcuts();
private:
QLabel * m_descriptionLabel;
ShortcutEdit * m_shortcutEdit;
QFormLayout * m_shortcutLayout;
QList<QKeySequenceEdit *> m_keySequenceEdits;
};
class ShortcutEdit : public QWidget
{
Q_OBJECT
Q_PROPERTY(QList<QKeySequence> shortcuts MEMBER m_shortcuts WRITE setShortcuts NOTIFY shortcutsChanged)
public:
explicit ShortcutEdit(QWidget * parent = nullptr);
~ShortcutEdit();
QList<QKeySequence> shortcuts() const;
void setShortcuts(const QList<QKeySequence> &shortcuts);
signals:
void shortcutsChanged();
void editButtonClicked();
void applyShortcutsRequested(QList<QKeySequence> newShortcuts);
private:
QList<QKeySequence> m_shortcuts;
QLabel * m_shortcutsLabel;
QToolButton * m_setShortcutButton;
};
+218
View File
@@ -0,0 +1,218 @@
// SPDX-FileCopyrightText: 2025 Gary Wang <git@blumia.net>
//
// SPDX-License-Identifier: MIT
#include "titlebar.h"
#include "opacityhelper.h"
#include <QPainter>
#include <QStyle>
#include <QMouseEvent>
#include <QEvent>
#include <QEnterEvent>
#include <QWindow>
#include <QCursor>
TitleBar::TitleBar(QWidget *parent)
: QWidget(parent)
, m_opacityHelper(new OpacityHelper(this))
, m_closeIcon(QStringLiteral(":/icons/window-close.svg"))
{
setFixedHeight(32);
setMouseTracking(true);
setAttribute(Qt::WA_Hover, true);
if (QWidget *win = window())
win->installEventFilter(this);
}
void TitleBar::setOpacity(qreal opacity, bool animated)
{
m_opacityHelper->setOpacity(opacity, animated);
}
void TitleBar::setCloseButtonVisible(bool visible)
{
if (m_closeButtonVisible == visible)
return;
m_closeButtonVisible = visible;
if (!visible) {
m_closeHovered = false;
m_closePressed = false;
}
update();
}
void TitleBar::setCloseButtonOnly(bool only)
{
if (m_closeButtonOnly == only)
return;
m_closeButtonOnly = only;
update();
}
QRect TitleBar::closeButtonRect() const
{
const int btnWidth = closeButtonWidth();
return QRect(width() - btnWidth, 0, btnWidth, height());
}
void TitleBar::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
// Subtle translucent backdrop so the title bar region is distinguishable
// (similar to the bottom button group). Skipped in close-button-only mode.
if (!m_closeButtonOnly) {
painter.fillRect(rect(), QColor(0, 0, 0, 120));
}
const QRect closeRect = closeButtonRect();
// Title text (leave room for the close button).
QRect labelRect = rect().adjusted(8, 0, 0, 0);
if (m_closeButtonVisible)
labelRect.setRight(closeRect.left() - 2);
const QString title = window() ? window()->windowTitle() : QString();
if (!m_closeButtonOnly && !title.isEmpty()) {
const QString elided = painter.fontMetrics().elidedText(title, Qt::ElideRight, labelRect.width());
const int flags = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine;
painter.setPen(Qt::black);
painter.drawText(labelRect.adjusted(1, 1, 1, 1), flags, elided);
painter.setPen(Qt::white);
painter.drawText(labelRect, flags, elided);
}
if (m_closeButtonVisible) {
if (m_closeHovered) {
painter.fillRect(closeRect,
m_closePressed ? QColor(0xC5, 0x0F, 0x1F)
: QColor(0xE8, 0x11, 0x23));
}
const int sz = height() / 3 * 2;
const QRect iconRect = QStyle::alignedRect(layoutDirection(), Qt::AlignCenter,
QSize(sz, sz), closeRect);
m_closeIcon.paint(&painter, iconRect);
}
}
void TitleBar::mousePressEvent(QMouseEvent *event)
{
if (event->button() != Qt::LeftButton) {
QWidget::mousePressEvent(event);
return;
}
if (m_closeButtonVisible && closeButtonRect().contains(event->pos())) {
m_closePressed = true;
m_dragPending = false;
update();
event->accept();
return;
}
m_dragPending = true;
m_moveStartPos = event->pos();
event->accept();
}
void TitleBar::mouseMoveEvent(QMouseEvent *event)
{
if (m_closeButtonVisible) {
const bool hovered = closeButtonRect().contains(event->pos());
if (hovered != m_closeHovered) {
m_closeHovered = hovered;
update();
}
}
if (event->buttons() & Qt::LeftButton && m_dragPending
&& !window()->isMaximized() && !window()->isFullScreen()) {
if (QWindow *wh = window()->windowHandle()) {
if (!wh->startSystemMove())
window()->move(event->globalPosition().toPoint() - m_moveStartPos);
}
event->accept();
}
QWidget::mouseMoveEvent(event);
}
void TitleBar::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
const bool wasClosePressed = m_closePressed;
m_closePressed = false;
m_dragPending = false;
update();
if (wasClosePressed && m_closeButtonVisible
&& closeButtonRect().contains(event->pos())) {
emit closeRequested();
event->accept();
return;
}
}
QWidget::mouseReleaseEvent(event);
}
void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton
&& !(m_closeButtonVisible && closeButtonRect().contains(event->pos()))) {
emit maximizeToggleRequested();
event->accept();
return;
}
QWidget::mouseDoubleClickEvent(event);
}
void TitleBar::enterEvent(QEnterEvent *event)
{
Q_UNUSED(event);
if (m_closeButtonVisible) {
const bool hovered = closeButtonRect().contains(mapFromGlobal(QCursor::pos()));
if (hovered != m_closeHovered) {
m_closeHovered = hovered;
update();
}
}
QWidget::enterEvent(event);
}
void TitleBar::leaveEvent(QEvent *event)
{
if (m_closeHovered) {
m_closeHovered = false;
update();
}
QWidget::leaveEvent(event);
}
bool TitleBar::eventFilter(QObject *watched, QEvent *event)
{
if (watched == window()) {
switch (event->type()) {
case QEvent::WindowTitleChange:
case QEvent::WindowStateChange:
case QEvent::ActivationChange:
update();
break;
default:
break;
}
}
return QWidget::eventFilter(watched, event);
}
QSize TitleBar::sizeHint() const
{
return QSize(0, 32);
}
+60
View File
@@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: 2025 Gary Wang <git@blumia.net>
//
// SPDX-License-Identifier: MIT
#ifndef TITLEBAR_H
#define TITLEBAR_H
#include <QWidget>
#include <QIcon>
QT_BEGIN_NAMESPACE
class QPaintEvent;
class QMouseEvent;
class QEvent;
class QEnterEvent;
QT_END_NAMESPACE
class OpacityHelper;
class TitleBar : public QWidget
{
Q_OBJECT
public:
explicit TitleBar(QWidget *parent = nullptr);
void setOpacity(qreal opacity, bool animated = true);
void setCloseButtonVisible(bool visible);
bool closeButtonOnly() const { return m_closeButtonOnly; }
void setCloseButtonOnly(bool only);
int closeButtonWidth() const { return qMax(height(), 46); }
signals:
void closeRequested();
void maximizeToggleRequested();
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
void enterEvent(QEnterEvent *event) override;
void leaveEvent(QEvent *event) override;
bool eventFilter(QObject *watched, QEvent *event) override;
QSize sizeHint() const override;
private:
QRect closeButtonRect() const;
OpacityHelper *m_opacityHelper;
QIcon m_closeIcon;
bool m_closeButtonVisible = true;
bool m_closeButtonOnly = false;
bool m_closeHovered = false;
bool m_closePressed = false;
bool m_dragPending = false;
QPoint m_moveStartPos;
};
#endif // TITLEBAR_H
+33
View File
@@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
//
// SPDX-License-Identifier: MIT
#include "toolbutton.h"
#include "actionmanager.h"
#include "opacityhelper.h"
#include <QPainter>
#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>
ToolButton::ToolButton(QWidget *parent)
: QPushButton(parent)
, m_opacityHelper(new OpacityHelper(this))
{
setFlat(true);
QString qss = "QPushButton {"
"background: transparent;"
"}";
setStyleSheet(qss);
}
void ToolButton::setIconResourcePath(const QString &iconp)
{
this->setIcon(ActionManager::loadHidpiIcon(iconp, this->iconSize()));
}
void ToolButton::setOpacity(qreal opacity, bool animated)
{
m_opacityHelper->setOpacity(opacity, animated);
}
+25
View File
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
//
// SPDX-License-Identifier: MIT
#ifndef TOOLBUTTON_H
#define TOOLBUTTON_H
#include <QPushButton>
class OpacityHelper;
class ToolButton : public QPushButton
{
Q_OBJECT
public:
ToolButton(QWidget * parent = nullptr);
void setIconResourcePath(const QString &iconp);
public slots:
void setOpacity(qreal opacity, bool animated = true);
private:
OpacityHelper * m_opacityHelper;
};
#endif // TOOLBUTTON_H
+56 -51
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Arrossegueu una imatge aquí</translation>
@@ -210,71 +210,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>La llista d&apos;ubicacions és buida</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Copia</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Les dades de la imatge no són vàlides</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>El tipus MIME no és compatible: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -403,7 +403,7 @@
<translation>Imatge següent</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -761,151 +761,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Paràmetres</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>No facis res</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Tanca la finestra</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Commuta la maximització</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Amplia i redueix</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Mostra l&apos;element següent o l&apos;anterior</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Mida automàtica</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Maximitza</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Mantingues a sobre a l&apos;inici</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Comportament del doble clic</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Comportament de la roda del ratolí</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Mida de la finestra per defecte</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+56 -51
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Ziehen Sie das Bild hierher</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Die Datei-URL-Liste ist leer</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Kopieren</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Bilddaten sind ungültig</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Nicht unterstützte Mimedaten: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -407,7 +407,7 @@
<translation>Nächstes Bild</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Einstellungen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Nichts tun</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Fenster schließen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Maximieren umschalten</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Hinein- und Hinauszoomen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Zeige nächstes oder vorheriges Element</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Automatische Größe</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Maximiert</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Beim Start oben bleiben</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Doppelklickverhalten</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Mausradverhalten</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Standard-Fenstergröße</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+56 -51
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation type="unfinished"></translation>
@@ -198,71 +198,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -391,7 +391,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -749,151 +749,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Double-click behavior</source>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Mouse wheel behavior</source>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Default window size</source>
<source>Double-click behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+57 -52
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Arrastre una imagen aquí</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>La lista de ubicaciones está vacía</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Copiar</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Los datos de la imagen no son válidos</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>El tipo MIME no es compatible: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>Imagen del portapapeles</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>¿Estás seguro de que quieres mover &quot;%1&quot; a la papelera de reciclaje?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Mover a la papelera ha fallado, puede deberse a un problema con los permisos de los archivos, una limitación del sistema de archivos o una limitación de la plataforma.</translation>
</message>
@@ -407,7 +407,7 @@
<translation>Imagen siguiente</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Mover a la papelera</translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Preferencias</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>Opciones</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>Atajos</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>Editando atajos para la acción &quot;%1&quot;:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>No se pudieron establecer accesos directos</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation>Por favor, verifique si los accesos directos están duplicados.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>No hacer nada</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Cerrar la ventana</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Maximizar/desmaximizar</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Ampliar y reducir</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Mostrar el elemento siguiente/anterior</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Tamaño automático</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Maximizar</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Redondeo (escala de enteros)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Ceil (redondear enteros hacia arriba)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Floor (redondear enteros hacia abajo)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Redondeo (redondear los enteros)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Mantener encima al inicio</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation>Utilice un tablero de ajedrez de color claro</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
<source>Use light-color checkerboard</source>
<translation>Utilice un tablero de ajedrez de color claro</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Comportamiento del doble clic</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Comportamiento de la rueda del ratón</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Tamaño de la ventana por defecto</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>Política de redondeo del factor de escala HiDPI</translation>
</message>
+56 -51
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Faites glisser l&apos;image ici</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>La liste des URL de fichiers est vide</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Copier</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Les données d&apos;image ne sont pas valides</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Mimedata non pris en charge&#xa0;: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -407,7 +407,7 @@
<translation>Image suivant</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Paramètres</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Ne rien faire</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Fermer la fenêtre</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Activer/désactiver l&apos;agrandissement</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Zoom avant et arrière</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Voir l&apos;élément suivant ou précédent</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Taille automatique</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Agrandi</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Rester en-haut lors du démarrage</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Comportement du double-clic</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Comportement de la molette de la souris</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Taille de la fenêtre par défaut</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+56 -51
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Tarik gambar ke sini</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Daftar url file kosong</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Salin</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Data gambar tidak valid</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Tidak didukung mimedata: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -407,7 +407,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Pengaturan</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Jangan lakukan apapun</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Tutup jendela</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Perbesar dan perkecil</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Lihat item berikutnya atau sebelumnya</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Double-click behavior</source>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Mouse wheel behavior</source>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Default window size</source>
<source>Double-click behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+53 -48
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Trascina qui l&apos;immagine</translation>
@@ -210,71 +210,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>L&apos;elenco degli URL dei file è vuoto</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Copia</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>I dati dell&apos;immagine non sono validi</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Dati mime non supportati: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>Immagine dagli appunti</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>Sei sicuro di voler spostare &quot;%1&quot; nel cestino?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation>Impossibile spostare il file nel cestino</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Lo spostamento nel cestino non è riuscito, potrebbe essere causato da un problema di autorizzazione del file, da una limitazione del file system o da una limitazione della piattaforma.</translation>
</message>
@@ -403,7 +403,7 @@
<translation>Immagine successiva</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Sposta nel cestino</translation>
@@ -761,151 +761,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Impostazioni</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>Opzioni</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>Scorciatoie</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>Modifica delle scorciatoie per l&apos;azione &quot;%1&quot;:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>Impossibile impostare le scorciatoie</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation>Controlla se i collegamenti sono duplicati con collegamenti esistenti.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Non fare nulla</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Chiudi la finestra</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Attiva massimizzazione</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation>Attiva schermo intero</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Zoom avanti e indietro</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Visualizza l&apos;elemento successivo o precedente</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Dimensione automatica</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Massimizzato</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation>Finestrato</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Round (ridimensionamento intero)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Ceil (ridimensionamento intero)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Floor (ridimensionamento intero)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Segui il sistema (scala frazionaria)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Rimani in cima quando si avvia</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation>Utilizza l&apos;animazione di chiusura della finestra integrata</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>Utilizzare scacchiera di colore chiaro</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation>Esegui il loop della galleria caricata</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation>Modalità immagine lunga automatica</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Comportamento del doppio clic</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Comportamento della rotellina del mouse</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Dimensioni predefinite della finestra</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>Politica di arrotondamento del fattore di scala HiDPI</translation>
</message>
+57 -52
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation></translation>
@@ -210,71 +210,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>urlリストがエンプティーです</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>(&amp;C)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>mimedata: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>%1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation></translation>
</message>
@@ -403,7 +403,7 @@
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation></translation>
@@ -761,151 +761,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>%1:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation> ()</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation> ()</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation> ()</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation> ()</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation>使</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
<source>Use light-color checkerboard</source>
<translation>使</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>DPIスケーリングの四捨五入方法</translation>
</message>
+53 -48
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation> </translation>
@@ -210,71 +210,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation> URL </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>(&amp;C)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation> mimedata: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation> .</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation>%1 (*.%2)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation> .</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation> : %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>&quot;%1&quot; ?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation> . , .</translation>
</message>
@@ -403,7 +403,7 @@
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation> </translation>
@@ -761,151 +761,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation> &quot;%1&quot; :</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation> .</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation> ( )</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation> ( )</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation> ( )</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation> ( )</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation>SVG SVG Tiny 1.2 </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>HiDPI </translation>
</message>
+56 -51
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Dra bilde hit</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Listen over filnettadresser er ugyldig</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Kopier</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Ugyldig bildedata</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Ustøttet MIME-data: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>Er du sikker at du vil flytte &quot;%1&quot; til papirkurven?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Flytt til papirkurven mislyktes, det kan skyldes filtillatelsesproblem, filsystembegrensning eller plattformbegrensning.</translation>
</message>
@@ -407,7 +407,7 @@
<translation>Neste bilde</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Flytt til papirkurven</translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Innstillinger</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Ikke gjør noe</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Lukk vinduet</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Maksimering av/</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Zoom inn og ut</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Vis neste eller forrige element</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation type="unfinished">Automatisk størrelse</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Maksimert</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Behold i forgrunnen ved oppstart</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Dobbeltklikksoppførsel</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Musehjulsoppførsel</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Forvalgt vindusstørrelse</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+53 -48
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Sleep een afbeelding hierheen</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>De bestandspadlijst is leeg</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Kopiëren</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Beschadigde afbeeldingsgegevens</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Niet-ondersteunde mime-gegevens: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation>Opslaan als</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation>Er is geen afbeelding geopend.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation>%1-afbeelding (*.%2)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation>Er zijn geen ondersteunde formaten beschikbaar.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation>De afbeelding kan niet worden opgeslagen: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>Afbeelding van klembord</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>Weet u zeker dat u %1 naar de prullenbak wilt verplaatsen?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation>Verplaatsen naar prullenbak mislukt</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Het bestand kan niet naar de prullenbak worden verplaatst, mogelijk door een rechtenprobleem of systeembeperking.</translation>
</message>
@@ -407,7 +407,7 @@
<translation>Volgende afbeelding</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Verplaatsen naar prullenbak</translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Instellingen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>Opties</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>Sneltoetsen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>Bewerken van sneltoetsen voor actie %1:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>Instellen mislukt</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation>Controleer of de gekozen sneltoetsen niet al in gebruik zijn.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Niets doen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Venster sluiten</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Maximaliseren/Demaximaliseren</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation>Schermvullende weergave aan/uit</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>In-/Uitzoomen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Ga naar volgende of vorige item</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Automatische grootte</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Gemaximaliseerd</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation>Venster</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Rond (geheel getal)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Keil (geheel getal)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Grond (geheel getal)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Systeeminstelling (fractionele schaal)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Automatisch altijd bovenop</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation>Meegeleverde animatie voor venster sluiten gebruiken</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>Licht schaakbordpatroon gebruiken</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation>Gekozen galerij herhalen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation>Automatische langeafbeeldingsmodus</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation>Svg-ondersteuning beperken tot SVG Tiny 1.2</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Dubbelklikgedrag</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Scrollwielgedrag</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Standaard vensterafmetingen</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>HiDPI-schaalfactor - afrondbeleid</translation>
</message>
+56 -51
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation type="unfinished"></translation>
@@ -198,71 +198,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>کاپی کرو</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -391,7 +391,7 @@
<translation>اگلی تصویر</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -749,151 +749,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>سیٹنگاں</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation type="unfinished">ودھو ودھ بدلو</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>ودھ توں ودھ</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Double-click behavior</source>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Mouse wheel behavior</source>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Default window size</source>
<source>Double-click behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+53 -48
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Перетащите изображение сюда</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Список URL-адресов файлов пуст</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Скопировать</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Параметры изображения недействительны</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Неподдерживаемые mimedata: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation>Сохранить как</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation>В настоящее время нет открытых изображений.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation>%1 Изображение (*.%2)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation>Нет доступных поддерживаемых форматов изображений.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation>Не удалось сохранить изображение: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>Изображение из буфера обмена</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>Вы уверены, что хотите переместить &quot;%1&quot; в корзину?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation>Не удалось переместить файл в корзину</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Перемещение в корзину не удалось, возможно, из-за проблем с правами доступа к файлу, ограничений файловой системы или ограничений платформы.</translation>
</message>
@@ -407,7 +407,7 @@
<translation>Следующее изображение</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Переместить в корзину</translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Параметры</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>Опции</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>Ярлыки</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>Сокращенные команды для действия &quot;%1&quot;:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>Не удалось установить ярлыки</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation>Пожалуйста, проверьте, не дублируются ли ярлыки с существующими ярлыками.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Ничего не делать</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Закрыть окно</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Переключить окно</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation>Переключить полноэкранный режим</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Увеличение и уменьшение масштаба</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Следующее или предыдущее изображение</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Авторазмер</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Максимизировать</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation>Оконный</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Round (целочисленное масштабирование)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Ceil (целочисленное масштабирование)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Floor (целочисленное масштабирование)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Следовать системе (дробное масштабирование)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Поверх всех окон при запуске</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation>Использовать встроенную анимацию закрытия окна</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>Использовать легкий шахматный узор</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation>Зациклить загруженную галерею</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation>Режим автоматического увеличения изображения</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation>Ограничить поддержку SVG до SVG Tiny 1.2</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Действие при двойном щелчке</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Действие колеса мыши</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Размер окна по умолчанию</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>Политика округления коэффициента масштабирования HiDPI</translation>
</message>
+56 -51
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation type="unfinished"></translation>
@@ -210,71 +210,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation> ... (url) </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -398,7 +398,7 @@
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -761,151 +761,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Double-click behavior</source>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Mouse wheel behavior</source>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Default window size</source>
<source>Double-click behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation type="unfinished"></translation>
</message>
+53 -48
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Povlecite sliko sem</translation>
@@ -198,71 +198,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Seznam url-jev datotek je prazen</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Kopiraj</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Podatki slike so neveljavni</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Ni podprtih podatkov mime: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation>Shrani kot</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation>Trenutno ni odprta nobena slika.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation>Slika %1 (*.%2)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation>Nobenih podprtih formatov slik ni na razpolago.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation>Shranjevanje slike ni uspelo: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>Slika iz odložišča</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>Ali ste prepričani, da želite premakniti &quot;%1&quot; v koš?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation>Datoteke ni bilo mogoče premakniti v koš</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Premik v koš ni uspel. Morda je vzrok težava z dovoljenji za datoteke, omejitev datotečnega sistema ali omejitev platforme.</translation>
</message>
@@ -391,7 +391,7 @@
<translation>Naslednja slika</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Premakni v koš</translation>
@@ -749,151 +749,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Nastavitve</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>Možnosti</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>Bližnjice</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>Urejanje bližnjic za dejanje &quot;%1&quot;:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>Nastavitev bližnjic ni uspela</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation>Preverite, ali so bližnjice podvojene z obstoječimi bližnjicami.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Ne naredi ničesar</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Zapri okno</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Preklopi maksimiranje</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation>Preklopi celozaslonski način</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Povečava in pomanjšava</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Ogled naslednjega ali prejšnjega elementa</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Samodejna velikost</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Maksimizirano</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation>Okenski način</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Zaokroženo (celoštevilsko skaliranje)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Zaokroževanje navzgor (celoštevilsko skaliranje)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Zaokroževanje navzdol (celoštevilsko skaliranje)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Sledi sistemu (delno skaliranje)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Ostani na vrhu pri zagonu</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation>Uporabi vgrajeno animacijo zapiranja okna</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>Uporabite svetlo šahovnico</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation>Ponavljaj naloženo galerijo</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation>Samodejni način dolge slike</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation>Omeji podporo za SVG na SVG Tiny 1.2</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Obnašanje dvojnega klika</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Obnašanje miškinega kolesca</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Privzeta velikost okna</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>Politika zaokroževanja faktorja merila HiDPI</translation>
</message>
+53 -48
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation> </translation>
@@ -198,71 +198,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation> ி ி ி </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation> (&amp;c)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation> ிி: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>ிிிி </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>ி ி &quot;%1&quot; ிி?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation> ி ி</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation> ி, ி, ி .</translation>
</message>
@@ -391,7 +391,7 @@
<translation> </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation> </translation>
@@ -749,151 +749,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>ி</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>ி</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation> ி ி &quot;%1&quot;:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>ி ி ி</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation> ி ி ி.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>ி </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation> ி</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation> ி ி</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation> ி </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>ி</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation> ( ி)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation> ( ி)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>ி ( ி)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>ிி ி (ி ி)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>ி </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation> ி </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>ி- </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation> ி </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation> </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>ி </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>ி </translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>HIDPI ி ி ி </translation>
</message>
+53 -48
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Resmi buraya sürükleyin</translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Dosya URL listesi boş</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Kopyala</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Resim verisi geçersiz</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Desteklenmeyen dosya türü verisi: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>Panodaki Resim</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>&quot;%1&quot; ögesini geri dönüşüm kutusuna taşımak istediğinizden emin misiniz?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation>Dosya çöpe taşınamadı</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Çöp kutusuna taşıma başarısız oldu, dosya izin sorunu, dosya sistemi sınırlaması veya platform sınırlamasından kaynaklanıyor olabilir.</translation>
</message>
@@ -407,7 +407,7 @@
<translation>Sonraki resim</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Çöp Kutusuna Taşı</translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Ayarlar</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>Seçenekler</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>Kısayollar</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>&quot;%1&quot; için kısayol düzenleniyor:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>Kısayollar ayarlanamadı</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation>Kısayolların var olan kısayollarla çakışma durumunu denetleyin.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Hiçbir şey yapma</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Pencereyi kapat</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Tam boyuta geç</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation>Tam ekranı /kapat</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Yaklaştır ve uzaklaştır</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Sonraki veya önceki ögeyi görüntüle</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Otomatik boyut</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Tam boyut</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation>Pencereli</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Yuvarlak (Tamsayı ölçekleme)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Tavan (Tamsayı ölçekleme)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Kat (Tamsayı ölçekleme)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Sistemi takip et (Kesirli ölçekleme)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Açılışta pencerelerin üstünde kal</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation>Yerleşik kapat pencere canlandırmasını kullan</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>Açık renk dama tahtası kullan</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation>Yüklenen galeriyi döngüye al</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation>Kendiliğinden uzun resim kipi</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation>SVG desteğini SVG Tiny 1.2 ile sınırla</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Çift tıklama davranışı</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Fare tekeri davranışı</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Öntanımlı pencere boyutu</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>HiDPI ölçek katsayısı yuvarlama ilkesi</translation>
</message>
+56 -51
View File
@@ -174,7 +174,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Перетягніть зображення сюди</translation>
@@ -210,71 +210,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Список URL-адрес файлів порожній</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Скопіювати</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Дані зображення недійсні</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Не підтримується mimedata: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation type="unfinished"></translation>
</message>
@@ -403,7 +403,7 @@
<translation>Наступне зображення</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation type="unfinished"></translation>
@@ -761,151 +761,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Налаштування</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Нічого не робити</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Закрити вікно</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Перемкнути на максимум</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Збільшення та зменшення</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Переглянути наступний або попередній елемент</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Автоматичний розмір</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Максимізувати</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Round (цілочисельне масштабування)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Ceil (цілочисельне масштабування)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Floor (цілочисельне масштабування)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Стежити за системою (дробове масштабування)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Поверх всіх вікон під час запуску</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Loop the loaded gallery</source>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Auto long image mode</source>
<source>Use light-color checkerboard</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<source>Loop the loaded gallery</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Поведінка при подвійному кліку</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Поведінка колеса миші</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Розмір вікна за замовчуванням</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>Політика округлення коефіцієнта HiDPI</translation>
</message>
+53 -48
View File
@@ -175,7 +175,7 @@ Loc Huynh &lt;https://github.com/hthienloc&gt;</translation>
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation>Kéo hình nh vào đây</translation>
@@ -199,71 +199,71 @@ Loc Huynh &lt;https://github.com/hthienloc&gt;</translation>
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation>Danh sách url tệp trống</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>&amp;Sao chép</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation>Dữ liệu hình nh không hợp lệ</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation>Dữ liệu mimedata không đưc hỗ trợ: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation>Lưu dưới dạng</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation>Hiện tại không hình nh nào đưc mở.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation>Hình nh %1 (*.%2)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation>Không đnh dạng hình nh đưc hỗ trợ.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation>Không lưu đưc hình nh: %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation>Hình nh từ bộ nhớ tạm</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>Bạn chắc chắn muốn chuyển &quot;%1&quot; vào thùng rác không?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation>Không thể di chuyển tệp vào thùng rác</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation>Di chuyển vào thùng rác không thành công, nguyên nhân thể do vấn đ về quyền đi với tệp, giới hạn hệ thống tệp hoặc giới hạn nền tảng.</translation>
</message>
@@ -392,7 +392,7 @@ Loc Huynh &lt;https://github.com/hthienloc&gt;</translation>
<translation>Hình nh tiếp theo</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation>Chuyển vào Thùng rác</translation>
@@ -750,151 +750,156 @@ Loc Huynh &lt;https://github.com/hthienloc&gt;</translation>
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation>Cài đt</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation>Tùy chọn</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation>Phím tắt</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>Chỉnh sửa phím tắt cho hành đng &quot;%1&quot;:</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation>Không đt đưc phím tắt</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation>Vui lòng kiểm tra xem các phím tắt bị trùng lặp với các phím tắt hiện hay không.</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation>Không làm cả</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation>Đóng cửa sổ</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation>Chuyển đi tối đa hóa</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation>Chuyển đi toàn màn hình</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation>Zoom thu nhỏ</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation>Xem mục tiếp theo hoặc trước đó</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation>Kích thước tự đng</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation>Tối đa hóa</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation> cửa sổ</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation>Tròn (Tỷ lệ số nguyên)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation>Ceil (Tỷ lệ số nguyên)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation>Tầng (Tỷ lệ số nguyên)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation>Hệ thống theo dõi (Chia tỷ lệ phân số)</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation>Luôn dẫn đu khi khởi nghiệp</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation>Sử dụng hoạt nh đóng cửa sổ tích hợp</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>Sử dụng bàn cờ màu sáng</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation>Lặp lại thư viện đã tải</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation>Chế đ hình nh dài tự đng</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation>Giới hạn hỗ trợ SVG SVG Tiny 1.2</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation>Hành vi bấm đúp</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation>Hành vi của bánh xe chuột</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation>Kích thước cửa sổ mặc đnh</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>Chính sách làm tròn hệ số tỷ lệ HiDPI</translation>
</message>
+53 -48
View File
@@ -178,7 +178,7 @@
<context>
<name>GraphicsScene</name>
<message>
<location filename="../mainwindow.cpp" line="293"/>
<location filename="../mainwindow.cpp" line="294"/>
<location filename="../graphicsscene.cpp" line="102"/>
<source>Drag image here</source>
<translation></translation>
@@ -214,71 +214,71 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="568"/>
<location filename="../mainwindow.cpp" line="192"/>
<location filename="../mainwindow.cpp" line="569"/>
<source>File url list is empty</source>
<translation> URL </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="462"/>
<location filename="../mainwindow.cpp" line="463"/>
<source>&amp;Copy</source>
<translation>(&amp;C)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="576"/>
<location filename="../mainwindow.cpp" line="577"/>
<source>Image data is invalid</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="583"/>
<location filename="../mainwindow.cpp" line="584"/>
<source>Not supported mimedata: %1</source>
<translation> MimeData %1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="727"/>
<location filename="../mainwindow.cpp" line="734"/>
<location filename="../mainwindow.cpp" line="764"/>
<location filename="../mainwindow.cpp" line="716"/>
<location filename="../mainwindow.cpp" line="733"/>
<location filename="../mainwindow.cpp" line="740"/>
<location filename="../mainwindow.cpp" line="770"/>
<source>Save As</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="710"/>
<location filename="../mainwindow.cpp" line="716"/>
<source>No image is currently open.</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="722"/>
<location filename="../mainwindow.cpp" line="728"/>
<source>%1 Image (*.%2)</source>
<translation>%1 (*.%2)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="728"/>
<location filename="../mainwindow.cpp" line="734"/>
<source>No supported image formats are available.</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="765"/>
<location filename="../mainwindow.cpp" line="771"/>
<source>Failed to save image: %1</source>
<translation>%1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="854"/>
<location filename="../mainwindow.cpp" line="860"/>
<source>Image From Clipboard</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="872"/>
<location filename="../mainwindow.cpp" line="878"/>
<source>Are you sure you want to move &quot;%1&quot; to recycle bin?</source>
<translation>%1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="876"/>
<location filename="../mainwindow.cpp" line="882"/>
<source>Failed to move file to trash</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../mainwindow.cpp" line="883"/>
<source>Move to trash failed, it might caused by file permission issue, file system limitation, or platform limitation.</source>
<translation></translation>
</message>
@@ -407,7 +407,7 @@
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="871"/>
<location filename="../mainwindow.cpp" line="877"/>
<location filename="../actionmanager.cpp" line="111"/>
<source>Move to Trash</source>
<translation></translation>
@@ -765,151 +765,156 @@
<context>
<name>SettingsDialog</name>
<message>
<location filename="../settingsdialog.cpp" line="33"/>
<location filename="../settingsdialog.cpp" line="34"/>
<source>Settings</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="41"/>
<location filename="../settingsdialog.cpp" line="42"/>
<source>Options</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="53"/>
<location filename="../settingsdialog.cpp" line="54"/>
<source>Shortcuts</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="63"/>
<location filename="../settingsdialog.cpp" line="64"/>
<source>Editing shortcuts for action &quot;%1&quot;:</source>
<translation>%1</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="72"/>
<location filename="../settingsdialog.cpp" line="73"/>
<source>Failed to set shortcuts</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="73"/>
<location filename="../settingsdialog.cpp" line="74"/>
<source>Please check if shortcuts are duplicated with existing shortcuts.</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="80"/>
<location filename="../settingsdialog.cpp" line="81"/>
<source>Do nothing</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="81"/>
<location filename="../settingsdialog.cpp" line="82"/>
<source>Close the window</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="82"/>
<location filename="../settingsdialog.cpp" line="83"/>
<source>Toggle maximize</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="83"/>
<location filename="../settingsdialog.cpp" line="84"/>
<source>Toggle fullscreen</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="87"/>
<location filename="../settingsdialog.cpp" line="88"/>
<source>Zoom in and out</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="88"/>
<location filename="../settingsdialog.cpp" line="89"/>
<source>View next or previous item</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="92"/>
<location filename="../settingsdialog.cpp" line="93"/>
<source>Auto size</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="93"/>
<location filename="../settingsdialog.cpp" line="94"/>
<source>Maximized</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="94"/>
<location filename="../settingsdialog.cpp" line="95"/>
<source>Windowed</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="98"/>
<location filename="../settingsdialog.cpp" line="99"/>
<source>Round (Integer scaling)</source>
<comment>This option means round up for .5 and above</comment>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="99"/>
<location filename="../settingsdialog.cpp" line="100"/>
<source>Ceil (Integer scaling)</source>
<comment>This option means always round up</comment>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="100"/>
<location filename="../settingsdialog.cpp" line="101"/>
<source>Floor (Integer scaling)</source>
<comment>This option means always round down</comment>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="101"/>
<location filename="../settingsdialog.cpp" line="102"/>
<source>Follow system (Fractional scaling)</source>
<comment>This option means don&apos;t round</comment>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="124"/>
<location filename="../settingsdialog.cpp" line="125"/>
<source>Stay on top when start-up</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="125"/>
<location filename="../settingsdialog.cpp" line="126"/>
<source>Use built-in close window animation</source>
<translation>使</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="126"/>
<location filename="../settingsdialog.cpp" line="127"/>
<source>Show title bar</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<source>Use light-color checkerboard</source>
<translation>使</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="127"/>
<location filename="../settingsdialog.cpp" line="129"/>
<source>Loop the loaded gallery</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="128"/>
<location filename="../settingsdialog.cpp" line="130"/>
<source>Auto long image mode</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="129"/>
<location filename="../settingsdialog.cpp" line="131"/>
<source>Limit SVG support to SVG Tiny 1.2</source>
<translation> SVG SVG Tiny 1.2</translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="130"/>
<location filename="../settingsdialog.cpp" line="132"/>
<source>Double-click behavior</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="131"/>
<location filename="../settingsdialog.cpp" line="133"/>
<source>Mouse wheel behavior</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="132"/>
<location filename="../settingsdialog.cpp" line="134"/>
<source>Default window size</source>
<translation></translation>
</message>
<message>
<location filename="../settingsdialog.cpp" line="133"/>
<location filename="../settingsdialog.cpp" line="135"/>
<source>HiDPI scale factor rounding policy</source>
<translation>HiDPI </translation>
</message>
-29
View File
@@ -1,29 +0,0 @@
<center>
<p>
<img width='128' height='128' src=':/icons/app-icon.svg'/>
<br/>
<!-- Application name -->
<span>%1</span>
<br/>
<!-- Version info -->
<span>%2</span>
</p>
<hr/>
<p>
<!-- Upstream author and fork author -->
<span>%3</span><span>:&nbsp;</span><a href='https://github.com/BLumia'>@BLumia</a>
<br/>
<span>%4</span><span>:&nbsp;</span><a href='https://github.com/yyc12345'>@yyc12345</a>
<br/>
<!-- Icon author -->
<span>%5</span><span>:&nbsp;</span><a href='https://github.com/Lovelyblack'>@Lovelyblack</a>
</p>
<hr/>
<p>
<!-- Built Qt version info -->
<span>%6</span>
<br/>
<!-- Source code -->
<span>%7</span><span>:&nbsp;</span><a href='https://github.com/BLumia/pineapple-pictures'>GitHub</a>
</p>
</center>
-29
View File
@@ -1,29 +0,0 @@
<!-- General help -->
<h1 align='center'>%1</h1>
<ul>
<li>
<span>%2</span>
<ul>
<li>%3</li>
<li>%4</li>
</ul>
</li>
<li>%5</li>
<li>%6</li>
</ul>
<hr/>
<!-- Context menu option help -->
<h1 align='center'>%7</h1>
<!-- Context menu option list -->
<ul>
<li>
<b>%8</b><span>:</span>
<br/>
<span>%9</span>
</li>
<li>
<b>%10</b><span>:</span>
<br/>
<span>%11</span>
</li>
</ul>
-29
View File
@@ -1,29 +0,0 @@
<!-- License -->
<h1 align='center'><b>%1</b></h1>
<p>%2</p>
<hr/>
<!-- VErbatime license -->
<h1 align='center'><b>%3</b></h1>
<pre>
Expat/MIT License
Copyright &copy; 2026 BLumia
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre>
-15
View File
@@ -1,15 +0,0 @@
<!-- Title -->
<h1 align='center'><b>%1</b></h1>
<!-- List intro message -->
<p>%2</p>
<p>%3</p>
<ul>
<li>
<a href='https://www.qt.io/'>Qt</a><span>: </span>
<span>GPLv2 + GPLv3 + LGPLv2.1 + LGPLv3</span>
</li>
<li style="display: none;">
<a href='https://www.exiv2.org/'>Exiv2</a><span>: </span>
<span>GPLv2</span>
</li>
</ul>
@@ -1,14 +1,3 @@
<!-- Contributor title -->
<h1 align='center'>%1</h1>
<!-- Contributor list -->
<a href='https://github.com/BLumia/pineapple-pictures/graphs/contributors'>%2</a>
<!-- The message to thank these contributors -->
<p>%3</p>
<!-- Translator title -->
<h1 align='center'>%4</h1>
<!-- The message to thank these translators -->
<p>%5</p>
<ul>
<li><u>Catalan</u>: Toni Estévez</li>
<li><u>Chinese (Simplified)</u>: Percy Hong</li>
+1 -5
View File
@@ -10,10 +10,6 @@
<file>icons/window-close.svg</file>
<file>icons/go-next.svg</file>
<file>icons/go-previous.svg</file>
<file>plain/help.html</file>
<file>plain/about.html</file>
<file>plain/special-thanks.html</file>
<file>plain/license.html</file>
<file>plain/third-party-libs.html</file>
<file>plain/translators.html</file>
</qresource>
</RCC>
@@ -53,7 +53,6 @@
<url type="bugtracker">https://github.com/BLumia/pineapple-pictures/issues</url>
<url type="donation">https://ko-fi.com/blumia</url>
<url type="translate">https://hosted.weblate.org/projects/pineapple-pictures/</url>
<url type="vcs-browser">https://github.com/BLumia/pineapple-pictures</url>
<provides>
<binary>ppic</binary>
</provides>
@@ -102,26 +101,6 @@
</screenshot>
</screenshots>
<releases>
<release type="stable" version="1.5.0" date="2026-07-04T00:00:00Z">
<description>
<p>This release adds the following features:</p>
<ul>
<li>Introduced an optional titlebar that display file name and allows drag and double-click to move and toggle maximize state</li>
<li>Windows: Now the application will use the system's built-in animation for open window animation</li>
</ul>
<p>This release fixes the following bug:</p>
<ul>
<li>Show empty url list should also reset window title to blank</li>
</ul>
<p>This release includes the following changes:</p>
<ul>
<li>Update translations</li>
<li>Add vcs-browser link to AppStream metadata</li>
</ul>
<p>With contributions from:</p>
<p>Heimen Stoffels (vistaus), VenusGirl (VenusGirl)</p>
</description>
</release>
<release type="stable" version="1.4.1" date="2026-04-05T00:00:00Z">
<description>
<p>This release includes the following changes:</p>
+118
View File
@@ -0,0 +1,118 @@
targetApp=ppic.exe
friendlyAppName=Pineapple Pictures
friendlyAppName[zh_CN]=菠萝看图
openCommand="\"{targetAppFullPath}\" \"%1\""
[ProgId/jpeg]
name=JPEG Image
name[zh_CN]=JPEG 图像
extensions=jpg,jpeg,jfif
[ProgId/gif]
name=GIF Animation Image
name[zh_CN]=GIF 动图
[ProgId/png]
name=PNG Image
name[zh_CN]=PNG 图像
[ProgId/svg]
name=Scalable Vector Graphics
name[zh_CN]=可缩放矢量图像
[ProgId/webp]
name=WebP Image
name[zh_CN]=WebP 图像
extensions=webp
[ProgId/avif]
name=AV1 Image File
name[zh_CN]=AV1 图像文件
[ProgId/ico]
name=Windows Icon Image
name[zh_CN]=Windows 图标图像
[ProgId/icns]
name=Apple Icon Image
name[zh_CN]=苹果图标图像
[ProgId/psd]
name=Photoshop Document
name[zh_CN]=Photoshop 文档
extensions=psd,psb,pdd,psdt
[ProgId/kra]
name=Krita Document
name[zh_CN]=Krita 文档
[ProgId/xcf]
name=GIMP Document
name[zh_CN]=GIMP 文档
[ProgId/tga]
name=TARGA Image
name[zh_CN]=TARGA 图像
[ProgId/tif]
name=Tagged Image File Format
name[zh_CN]=标签图像文件格式
extensions=tif,tiff
[ProgId/bmp]
name=Bitmap
name[zh_CN]=位图
[ProgId/wbmp]
name=Wireless Bitmap
name[zh_CN]=无线位图
[ProgId/dds]
name=DirectDraw Surface
[ProgId/hdr]
name=High Dynamic Range Image
name[zh_CN]=高动态范围图像
[ProgId/iff]
name=Interchange File Format
name[zh_CN]=可交换文件格式
[ProgId/pic]
name=Softimage Picture
name[zh_CN]=Softimage 图像
[ProgId/pcx]
name=PiCture eXchange PC Paintbrush Image
name[zh_CN]=PC Paintbrush 图像
[ProgId/qoi]
name=Quite OK Image
name[zh_CN]=挺 OK 图像
[ProgId/ras]
name=Sun Raster Image
name[zh_CN]=Sun 栅格图象
extensions=ras,sun
[ProgId/ora]
name=OpenRaster Image
name[zh_CN]=OpenRaster 图象
[ProgId/ani]
name=Animated Cursor
name[zh_CN]=动态光标
[ProgId/pfm]
name=Portable Float Map
extensions=pfm,phm
[ProgId/rgb]
name=Silicon Graphics Image
extensions=rgb,rgba,bw,sgi
[ProgId/pxr]
name=Pixar Raster Image
[ProgId/sct]
name=Scitex Continuous Tone